--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -6729,17 +6729,17 @@ nsDocument::CreateRange(nsIDOMRange** aR
*aReturn = nsIDocument::CreateRange(rv).take();
return rv.StealNSResult();
}
already_AddRefed<nsRange>
nsIDocument::CreateRange(ErrorResult& rv)
{
RefPtr<nsRange> range = new nsRange(this);
- nsresult res = range->Set(this, 0, this, 0);
+ nsresult res = range->CollapseTo(this, 0);
if (NS_FAILED(res)) {
rv.Throw(res);
return nullptr;
}
return range.forget();
}
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -266,50 +266,38 @@ nsRange::nsRange(nsINode* aNode)
}
/* static */
nsresult
nsRange::CreateRange(nsINode* aStartParent, int32_t aStartOffset,
nsINode* aEndParent, int32_t aEndOffset,
nsRange** aRange)
{
- nsCOMPtr<nsIDOMNode> startDomNode = do_QueryInterface(aStartParent);
- nsCOMPtr<nsIDOMNode> endDomNode = do_QueryInterface(aEndParent);
-
- nsresult rv = CreateRange(startDomNode, aStartOffset, endDomNode, aEndOffset,
- aRange);
-
- return rv;
-
+ MOZ_ASSERT(aRange);
+ *aRange = nullptr;
+
+ RefPtr<nsRange> range = new nsRange(aStartParent);
+ nsresult rv = range->SetStartAndEnd(aStartParent, aStartOffset,
+ aEndParent, aEndOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ range.forget(aRange);
+ return NS_OK;
}
/* static */
nsresult
nsRange::CreateRange(nsIDOMNode* aStartParent, int32_t aStartOffset,
nsIDOMNode* aEndParent, int32_t aEndOffset,
nsRange** aRange)
{
- MOZ_ASSERT(aRange);
- *aRange = nullptr;
-
nsCOMPtr<nsINode> startParent = do_QueryInterface(aStartParent);
- NS_ENSURE_ARG_POINTER(startParent);
-
- RefPtr<nsRange> range = new nsRange(startParent);
-
- // XXX this can be optimized by inlining SetStart/End and calling
- // DoSetRange *once*.
- nsresult rv = range->SetStart(startParent, aStartOffset);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = range->SetEnd(aEndParent, aEndOffset);
- NS_ENSURE_SUCCESS(rv, rv);
-
- range.forget(aRange);
- return NS_OK;
+ nsCOMPtr<nsINode> endParent = do_QueryInterface(aEndParent);
+ return CreateRange(startParent, aStartOffset, endParent, aEndOffset, aRange);
}
/* static */
nsresult
nsRange::CreateRange(nsIDOMNode* aStartParent, int32_t aStartOffset,
nsIDOMNode* aEndParent, int32_t aEndOffset,
nsIDOMRange** aRange)
{
@@ -1144,16 +1132,25 @@ nsRange::GetCommonAncestorContainer(nsID
NS_ADDREF(*aCommonParent = commonAncestor->AsDOMNode());
} else {
*aCommonParent = nullptr;
}
return rv.StealNSResult();
}
+/* static */
+bool
+nsRange::IsValidOffset(nsINode* aNode, int32_t aOffset)
+{
+ return aNode &&
+ aOffset >= 0 &&
+ static_cast<size_t>(aOffset) <= aNode->Length();
+}
+
nsINode*
nsRange::IsValidBoundary(nsINode* aNode)
{
if (!aNode) {
return nullptr;
}
if (aNode->IsNodeOfType(nsINode::eCONTENT)) {
@@ -1232,17 +1229,17 @@ nsRange::SetStart(nsIDOMNode* aParent, i
/* virtual */ nsresult
nsRange::SetStart(nsINode* aParent, int32_t aOffset)
{
nsINode* newRoot = IsValidBoundary(aParent);
if (!newRoot) {
return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
}
- if (aOffset < 0 || uint32_t(aOffset) > aParent->Length()) {
+ if (!IsValidOffset(aParent, aOffset)) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
// Collapse if not positioned yet, if positioned in another doc or
// if the new start is after end.
if (!mIsPositioned || newRoot != mRoot ||
nsContentUtils::ComparePoints(aParent, aOffset,
mEndParent, mEndOffset) == 1) {
@@ -1269,17 +1266,19 @@ nsRange::SetStartBefore(nsINode& aNode,
{
if (!nsContentUtils::LegacyIsCallerNativeCode() &&
!nsContentUtils::CanCallerAccess(&aNode)) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
AutoInvalidateSelection atEndOfBlock(this);
- aRv = SetStart(aNode.GetParentNode(), IndexOf(&aNode));
+ int32_t offset = -1;
+ nsINode* parent = GetParentAndOffsetBefore(&aNode, &offset);
+ aRv = SetStart(parent, offset);
}
NS_IMETHODIMP
nsRange::SetStartBefore(nsIDOMNode* aSibling)
{
nsCOMPtr<nsINode> sibling = do_QueryInterface(aSibling);
if (!sibling) {
return NS_ERROR_DOM_NOT_OBJECT_ERR;
@@ -1303,17 +1302,19 @@ nsRange::SetStartAfter(nsINode& aNode, E
{
if (!nsContentUtils::LegacyIsCallerNativeCode() &&
!nsContentUtils::CanCallerAccess(&aNode)) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
AutoInvalidateSelection atEndOfBlock(this);
- aRv = SetStart(aNode.GetParentNode(), IndexOf(&aNode) + 1);
+ int32_t offset = -1;
+ nsINode* parent = GetParentAndOffsetAfter(&aNode, &offset);
+ aRv = SetStart(parent, offset);
}
NS_IMETHODIMP
nsRange::SetStartAfter(nsIDOMNode* aSibling)
{
nsCOMPtr<nsINode> sibling = do_QueryInterface(aSibling);
if (!sibling) {
return NS_ERROR_DOM_NOT_OBJECT_ERR;
@@ -1360,17 +1361,17 @@ nsRange::SetEnd(nsIDOMNode* aParent, int
/* virtual */ nsresult
nsRange::SetEnd(nsINode* aParent, int32_t aOffset)
{
nsINode* newRoot = IsValidBoundary(aParent);
if (!newRoot) {
return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
}
- if (aOffset < 0 || uint32_t(aOffset) > aParent->Length()) {
+ if (!IsValidOffset(aParent, aOffset)) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
// Collapse if not positioned yet, if positioned in another doc or
// if the new end is before start.
if (!mIsPositioned || newRoot != mRoot ||
nsContentUtils::ComparePoints(mStartParent, mStartOffset,
aParent, aOffset) == 1) {
@@ -1379,16 +1380,74 @@ nsRange::SetEnd(nsINode* aParent, int32_
return NS_OK;
}
DoSetRange(mStartParent, mStartOffset, aParent, aOffset, mRoot);
return NS_OK;
}
+nsresult
+nsRange::SetStartAndEnd(nsINode* aStartParent, int32_t aStartOffset,
+ nsINode* aEndParent, int32_t aEndOffset)
+{
+ if (NS_WARN_IF(!aStartParent) || NS_WARN_IF(!aEndParent)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ nsINode* newStartRoot = IsValidBoundary(aStartParent);
+ if (!newStartRoot) {
+ return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
+ }
+ if (!IsValidOffset(aStartParent, aStartOffset)) {
+ return NS_ERROR_DOM_INDEX_SIZE_ERR;
+ }
+
+ if (aStartParent == aEndParent) {
+ if (!IsValidOffset(aEndParent, aEndOffset)) {
+ return NS_ERROR_DOM_INDEX_SIZE_ERR;
+ }
+ // If the end offset is less than the start offset, this should be
+ // collapsed at the end offset.
+ if (aStartOffset > aEndOffset) {
+ DoSetRange(aEndParent, aEndOffset, aEndParent, aEndOffset, newStartRoot);
+ } else {
+ DoSetRange(aStartParent, aStartOffset,
+ aEndParent, aEndOffset, newStartRoot);
+ }
+ return NS_OK;
+ }
+
+ nsINode* newEndRoot = IsValidBoundary(aEndParent);
+ if (!newEndRoot) {
+ return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
+ }
+ if (!IsValidOffset(aEndParent, aEndOffset)) {
+ return NS_ERROR_DOM_INDEX_SIZE_ERR;
+ }
+
+ // If they have different root, this should be collapsed at the end point.
+ if (newStartRoot != newEndRoot) {
+ DoSetRange(aEndParent, aEndOffset, aEndParent, aEndOffset, newEndRoot);
+ return NS_OK;
+ }
+
+ // If the end point is before the start point, this should be collapsed at
+ // the end point.
+ if (nsContentUtils::ComparePoints(aStartParent, aStartOffset,
+ aEndParent, aEndOffset) == 1) {
+ DoSetRange(aEndParent, aEndOffset, aEndParent, aEndOffset, newEndRoot);
+ return NS_OK;
+ }
+
+ // Otherwise, set the range as specified.
+ DoSetRange(aStartParent, aStartOffset, aEndParent, aEndOffset, newStartRoot);
+ return NS_OK;
+}
+
void
nsRange::SetEndBeforeJS(nsINode& aNode, ErrorResult& aErr)
{
AutoCalledByJSRestore calledByJSRestorer(*this);
mCalledByJS = true;
SetEndBefore(aNode, aErr);
}
@@ -1397,17 +1456,19 @@ nsRange::SetEndBefore(nsINode& aNode, Er
{
if (!nsContentUtils::LegacyIsCallerNativeCode() &&
!nsContentUtils::CanCallerAccess(&aNode)) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
AutoInvalidateSelection atEndOfBlock(this);
- aRv = SetEnd(aNode.GetParentNode(), IndexOf(&aNode));
+ int32_t offset = -1;
+ nsINode* parent = GetParentAndOffsetBefore(&aNode, &offset);
+ aRv = SetEnd(parent, offset);
}
NS_IMETHODIMP
nsRange::SetEndBefore(nsIDOMNode* aSibling)
{
nsCOMPtr<nsINode> sibling = do_QueryInterface(aSibling);
if (!sibling) {
return NS_ERROR_DOM_NOT_OBJECT_ERR;
@@ -1431,17 +1492,19 @@ nsRange::SetEndAfter(nsINode& aNode, Err
{
if (!nsContentUtils::LegacyIsCallerNativeCode() &&
!nsContentUtils::CanCallerAccess(&aNode)) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
AutoInvalidateSelection atEndOfBlock(this);
- aRv = SetEnd(aNode.GetParentNode(), IndexOf(&aNode) + 1);
+ int32_t offset = -1;
+ nsINode* parent = GetParentAndOffsetAfter(&aNode, &offset);
+ aRv = SetEnd(parent, offset);
}
NS_IMETHODIMP
nsRange::SetEndAfter(nsIDOMNode* aSibling)
{
nsCOMPtr<nsINode> sibling = do_QueryInterface(aSibling);
if (!sibling) {
return NS_ERROR_DOM_NOT_OBJECT_ERR;
--- a/dom/base/nsRange.h
+++ b/dom/base/nsRange.h
@@ -144,29 +144,71 @@ public:
*/
void SetIsGenerated(bool aIsGenerated)
{
mIsGenerated = aIsGenerated;
}
nsINode* GetCommonAncestor() const;
void Reset();
+
+ /**
+ * SetStart() and SetEnd() sets start point or end point separately.
+ * However, this is expensive especially when it's a range of Selection.
+ * When you set both start and end of a range, you should use
+ * SetStartAndEnd() instead.
+ */
nsresult SetStart(nsINode* aParent, int32_t aOffset);
nsresult SetEnd(nsINode* aParent, int32_t aOffset);
+
already_AddRefed<nsRange> CloneRange() const;
- nsresult Set(nsINode* aStartParent, int32_t aStartOffset,
- nsINode* aEndParent, int32_t aEndOffset)
+ /**
+ * SetStartAndEnd() works similar to call both SetStart() and SetEnd().
+ * Different from calls them separately, this does nothing if either
+ * the start point or the end point is invalid point.
+ * If the specified start point is after the end point, the range will be
+ * collapsed at the end point. Similarly, if they are in different root,
+ * the range will be collapsed at the end point.
+ */
+ nsresult SetStartAndEnd(nsINode* aStartParent, int32_t aStartOffset,
+ nsINode* aEndParent, int32_t aEndOffset);
+
+ /**
+ * CollapseTo() works similar to call both SetStart() and SetEnd() with
+ * same node and offset. This just calls SetStartAndParent() to set
+ * collapsed range at aParent and aOffset.
+ */
+ nsresult CollapseTo(nsINode* aParent, int32_t aOffset)
{
- // If this starts being hot, we may be able to optimize this a bit,
- // but for now just set start and end separately.
- nsresult rv = SetStart(aStartParent, aStartOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ return SetStartAndEnd(aParent, aOffset, aParent, aOffset);
+ }
- return SetEnd(aEndParent, aEndOffset);
+ /**
+ * Retrieves node and offset for setting start or end of a range to
+ * before or after aNode.
+ */
+ static nsINode* GetParentAndOffsetAfter(nsINode* aNode, int32_t* aOffset)
+ {
+ MOZ_ASSERT(aNode);
+ MOZ_ASSERT(aOffset);
+ nsINode* parentNode = aNode->GetParentNode();
+ *aOffset = parentNode ? parentNode->IndexOf(aNode) : -1;
+ if (*aOffset >= 0) {
+ (*aOffset)++;
+ }
+ return parentNode;
+ }
+ static nsINode* GetParentAndOffsetBefore(nsINode* aNode, int32_t* aOffset)
+ {
+ MOZ_ASSERT(aNode);
+ MOZ_ASSERT(aOffset);
+ nsINode* parentNode = aNode->GetParentNode();
+ *aOffset = parentNode ? parentNode->IndexOf(aNode) : -1;
+ return parentNode;
}
NS_IMETHOD GetUsedFontFaces(nsIDOMFontFaceList** aResult);
// nsIMutationObserver methods
NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
@@ -309,16 +351,17 @@ public:
*/
void ExcludeNonSelectableNodes(nsTArray<RefPtr<nsRange>>* aOutRanges);
typedef nsTHashtable<nsPtrHashKey<nsRange> > RangeHashTable;
protected:
void RegisterCommonAncestor(nsINode* aNode);
void UnregisterCommonAncestor(nsINode* aNode);
nsINode* IsValidBoundary(nsINode* aNode);
+ static bool IsValidOffset(nsINode* aNode, int32_t aOffset);
// CharacterDataChanged set aNotInsertedYet to true to disable an assertion
// and suppress re-registering a range common ancestor node since
// the new text node of a splitText hasn't been inserted yet.
// CharacterDataChanged does the re-registering when needed.
void DoSetRange(nsINode* aStartN, int32_t aStartOffset,
nsINode* aEndN, int32_t aEndOffset,
nsINode* aRoot, bool aNotInsertedYet = false);
--- a/dom/events/ContentEventHandler.cpp
+++ b/dom/events/ContentEventHandler.cpp
@@ -980,21 +980,17 @@ ContentEventHandler::SetRangeFromFlatTex
*aNewOffset = aOffset;
}
if (aLastTextNode) {
*aLastTextNode = nullptr;
}
// Special case like <br contenteditable>
if (!mRootContent->HasChildren()) {
- nsresult rv = aRange->SetStart(mRootContent, 0);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
- rv = aRange->SetEnd(mRootContent, 0);
+ nsresult rv = aRange->CollapseTo(mRootContent, 0);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
nsCOMPtr<nsIContentIterator> iter = NS_NewPreContentIterator();
nsresult rv = iter->Init(mRootContent);
if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -2878,18 +2874,17 @@ ContentEventHandler::AdjustCollapsedRang
}
// But if the found node isn't a text node, we cannot modify the range.
if (!childNode || !childNode->IsNodeOfType(nsINode::eTEXT) ||
NS_WARN_IF(offsetInChildNode < 0)) {
return NS_OK;
}
- nsresult rv = aRange->Set(childNode, offsetInChildNode,
- childNode, offsetInChildNode);
+ nsresult rv = aRange->CollapseTo(childNode, offsetInChildNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
nsresult
ContentEventHandler::GetStartFrameAndOffset(const nsRange* aRange,
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -1441,26 +1441,25 @@ HTMLEditRules::WillInsertText(EditAction
}
aSelection->SetInterlinePosition(false);
if (curNode) aSelection->Collapse(curNode, curOffset);
// manually update the doc changed range so that AfterEdit will clean up
// the correct portion of the document.
if (!mDocChangeRange) {
mDocChangeRange = new nsRange(selNode);
}
- rv = mDocChangeRange->SetStart(selNode, selOffset);
- NS_ENSURE_SUCCESS(rv, rv);
if (curNode) {
- rv = mDocChangeRange->SetEnd(curNode, curOffset);
+ rv = mDocChangeRange->SetStartAndEnd(selNode, selOffset,
+ curNode, curOffset);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else {
- rv = mDocChangeRange->SetEnd(selNode, selOffset);
+ rv = mDocChangeRange->CollapseTo(selNode, selOffset);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
}
return NS_OK;
}
@@ -5246,20 +5245,21 @@ HTMLEditRules::ExpandSelectionForDeletio
bool doEndExpansion = true;
if (firstBRParent) {
// Find block node containing br
nsCOMPtr<Element> brBlock = HTMLEditor::GetBlock(*firstBRParent);
bool nodeBefore = false, nodeAfter = false;
// Create a range that represents expanded selection
RefPtr<nsRange> range = new nsRange(selStartNode);
- nsresult rv = range->SetStart(selStartNode, selStartOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = range->SetEnd(selEndNode, selEndOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsresult rv = range->SetStartAndEnd(selStartNode, selStartOffset,
+ selEndNode, selEndOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
// Check if block is entirely inside range
if (brBlock) {
nsRange::CompareNodeToRange(brBlock, range, &nodeBefore, &nodeAfter);
}
// If block isn't contained, forgo grabbing the br in expanded selection
if (nodeBefore || nodeAfter) {
@@ -5711,36 +5711,37 @@ HTMLEditRules::PromoteRange(nsRange& aRa
}
}
}
// Make a new adjusted range to represent the appropriate block content.
// This is tricky. The basic idea is to push out the range endpoints to
// truly enclose the blocks that we will affect.
- nsCOMPtr<nsIDOMNode> opStartNode;
- nsCOMPtr<nsIDOMNode> opEndNode;
+ nsCOMPtr<nsIDOMNode> opDOMStartNode;
+ nsCOMPtr<nsIDOMNode> opDOMEndNode;
int32_t opStartOffset, opEndOffset;
GetPromotedPoint(kStart, GetAsDOMNode(startNode), startOffset,
- aOperationType, address_of(opStartNode), &opStartOffset);
+ aOperationType, address_of(opDOMStartNode), &opStartOffset);
GetPromotedPoint(kEnd, GetAsDOMNode(endNode), endOffset, aOperationType,
- address_of(opEndNode), &opEndOffset);
+ address_of(opDOMEndNode), &opEndOffset);
// Make sure that the new range ends up to be in the editable section.
if (!htmlEditor->IsDescendantOfEditorRoot(
- EditorBase::GetNodeAtRangeOffsetPoint(opStartNode, opStartOffset)) ||
+ EditorBase::GetNodeAtRangeOffsetPoint(opDOMStartNode, opStartOffset)) ||
!htmlEditor->IsDescendantOfEditorRoot(
- EditorBase::GetNodeAtRangeOffsetPoint(opEndNode, opEndOffset - 1))) {
+ EditorBase::GetNodeAtRangeOffsetPoint(opDOMEndNode, opEndOffset - 1))) {
return;
}
- DebugOnly<nsresult> rv = aRange.SetStart(opStartNode, opStartOffset);
- MOZ_ASSERT(NS_SUCCEEDED(rv));
- rv = aRange.SetEnd(opEndNode, opEndOffset);
+ nsCOMPtr<nsINode> opStartNode = do_QueryInterface(opDOMStartNode);
+ nsCOMPtr<nsINode> opEndNode = do_QueryInterface(opDOMEndNode);
+ DebugOnly<nsresult> rv =
+ aRange.SetStartAndEnd(opStartNode, opStartOffset, opEndNode, opEndOffset);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
class UniqueFunctor final : public BoolDomIterFunctor
{
public:
explicit UniqueFunctor(nsTArray<OwningNonNull<nsINode>>& aArray)
: mArray(aArray)
@@ -7401,20 +7402,20 @@ HTMLEditRules::PinSelectionToNewBlock(Se
EditorBase::GetStartNodeAndOffset(aSelection,
getter_AddRefs(selNode), &selOffset);
NS_ENSURE_SUCCESS(rv, rv);
// use ranges and sRangeHelper to compare sel point to new block
nsCOMPtr<nsINode> node = do_QueryInterface(selNode);
NS_ENSURE_STATE(node);
RefPtr<nsRange> range = new nsRange(node);
- rv = range->SetStart(selNode, selOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = range->SetEnd(selNode, selOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = range->CollapseTo(node, selOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
bool nodeBefore, nodeAfter;
rv = nsRange::CompareNodeToRange(mNewBlock, range, &nodeBefore, &nodeAfter);
NS_ENSURE_SUCCESS(rv, rv);
if (nodeBefore && nodeAfter) {
return NS_OK; // selection is inside block
} else if (nodeBefore) {
// selection is after block. put at end of block.
@@ -8299,20 +8300,23 @@ NS_IMETHODIMP
HTMLEditRules::DidSplitNode(nsIDOMNode* aExistingRightNode,
int32_t aOffset,
nsIDOMNode* aNewLeftNode,
nsresult aResult)
{
if (!mListenerEnabled) {
return NS_OK;
}
- nsresult rv = mUtilRange->SetStart(aNewLeftNode, 0);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = mUtilRange->SetEnd(aExistingRightNode, 0);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsINode> newLeftNode = do_QueryInterface(aNewLeftNode);
+ nsCOMPtr<nsINode> existingRightNode = do_QueryInterface(aExistingRightNode);
+ nsresult rv = mUtilRange->SetStartAndEnd(newLeftNode, 0,
+ existingRightNode, 0);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
return UpdateDocChangeRange(mUtilRange);
}
NS_IMETHODIMP
HTMLEditRules::WillJoinNodes(nsIDOMNode* aLeftNode,
nsIDOMNode* aRightNode,
nsIDOMNode* aParent)
{
@@ -8327,21 +8331,22 @@ NS_IMETHODIMP
HTMLEditRules::DidJoinNodes(nsIDOMNode* aLeftNode,
nsIDOMNode* aRightNode,
nsIDOMNode* aParent,
nsresult aResult)
{
if (!mListenerEnabled) {
return NS_OK;
}
+ nsCOMPtr<nsINode> rightNode = do_QueryInterface(aRightNode);
// assumption that Join keeps the righthand node
- nsresult rv = mUtilRange->SetStart(aRightNode, mJoinOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = mUtilRange->SetEnd(aRightNode, mJoinOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsresult rv = mUtilRange->CollapseTo(rightNode, mJoinOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
return UpdateDocChangeRange(mUtilRange);
}
NS_IMETHODIMP
HTMLEditRules::WillInsertText(nsIDOMCharacterData* aTextNode,
int32_t aOffset,
const nsAString& aString)
{
@@ -8353,21 +8358,22 @@ HTMLEditRules::DidInsertText(nsIDOMChara
int32_t aOffset,
const nsAString& aString,
nsresult aResult)
{
if (!mListenerEnabled) {
return NS_OK;
}
int32_t length = aString.Length();
- nsCOMPtr<nsIDOMNode> theNode = do_QueryInterface(aTextNode);
- nsresult rv = mUtilRange->SetStart(theNode, aOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = mUtilRange->SetEnd(theNode, aOffset+length);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsINode> theNode = do_QueryInterface(aTextNode);
+ nsresult rv = mUtilRange->SetStartAndEnd(theNode, aOffset,
+ theNode, aOffset + length);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
return UpdateDocChangeRange(mUtilRange);
}
NS_IMETHODIMP
HTMLEditRules::WillDeleteText(nsIDOMCharacterData* aTextNode,
int32_t aOffset,
int32_t aLength)
{
@@ -8378,49 +8384,54 @@ NS_IMETHODIMP
HTMLEditRules::DidDeleteText(nsIDOMCharacterData* aTextNode,
int32_t aOffset,
int32_t aLength,
nsresult aResult)
{
if (!mListenerEnabled) {
return NS_OK;
}
- nsCOMPtr<nsIDOMNode> theNode = do_QueryInterface(aTextNode);
- nsresult rv = mUtilRange->SetStart(theNode, aOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = mUtilRange->SetEnd(theNode, aOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsINode> theNode = do_QueryInterface(aTextNode);
+ nsresult rv = mUtilRange->CollapseTo(theNode, aOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
return UpdateDocChangeRange(mUtilRange);
}
NS_IMETHODIMP
HTMLEditRules::WillDeleteSelection(nsISelection* aSelection)
{
if (!mListenerEnabled) {
return NS_OK;
}
if (NS_WARN_IF(!aSelection)) {
return NS_ERROR_INVALID_ARG;
}
RefPtr<Selection> selection = aSelection->AsSelection();
// get the (collapsed) selection location
- nsCOMPtr<nsIDOMNode> selNode;
- int32_t selOffset;
-
+ nsCOMPtr<nsINode> startNode;
+ int32_t startOffset;
nsresult rv =
EditorBase::GetStartNodeAndOffset(selection,
- getter_AddRefs(selNode), &selOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = mUtilRange->SetStart(selNode, selOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ getter_AddRefs(startNode), &startOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ nsCOMPtr<nsINode> endNode;
+ int32_t endOffset;
rv = EditorBase::GetEndNodeAndOffset(selection,
- getter_AddRefs(selNode), &selOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = mUtilRange->SetEnd(selNode, selOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ getter_AddRefs(endNode), &endOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ rv = mUtilRange->SetStartAndEnd(startNode, startOffset, endNode, endOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
return UpdateDocChangeRange(mUtilRange);
}
NS_IMETHODIMP
HTMLEditRules::DidDeleteSelection(nsISelection *aSelection)
{
return NS_OK;
}
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -3283,18 +3283,18 @@ HTMLEditor::DoContentInserted(nsIDocumen
if (aInsertedOrAppended == eAppended) {
// Count all the appended nodes
nsIContent* sibling = aChild->GetNextSibling();
while (sibling) {
endIndex++;
sibling = sibling->GetNextSibling();
}
}
- nsresult rv = range->Set(aContainer, aIndexInContainer,
- aContainer, endIndex);
+ nsresult rv = range->SetStartAndEnd(aContainer, aIndexInContainer,
+ aContainer, endIndex);
if (NS_SUCCEEDED(rv)) {
mInlineSpellChecker->SpellCheckRange(range);
}
}
}
}
void
--- a/editor/libeditor/HTMLStyleEditor.cpp
+++ b/editor/libeditor/HTMLStyleEditor.cpp
@@ -531,19 +531,21 @@ HTMLEditor::SplitStyleAboveRange(nsRange
// second verse, same as the first...
nsresult rv =
SplitStyleAbovePoint(address_of(endNode), &endOffset, aProperty,
aAttribute);
NS_ENSURE_SUCCESS(rv, rv);
// reset the range
- rv = inRange->SetStart(startNode, startOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- return inRange->SetEnd(endNode, endOffset);
+ rv = inRange->SetStartAndEnd(startNode, startOffset, endNode, endOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
}
nsresult
HTMLEditor::SplitStyleAbovePoint(nsCOMPtr<nsINode>* aNode,
int32_t* aOffset,
// null here means we split all properties
nsIAtom* aProperty,
const nsAString* aAttribute,
@@ -878,20 +880,21 @@ HTMLEditor::PromoteRangeIfStartsOrEndsIn
}
NS_ENSURE_TRUE(parent, NS_ERROR_NULL_POINTER);
if (HTMLEditUtils::IsNamedAnchor(parent)) {
endNode = parent->GetParentNode();
endOffset = endNode ? endNode->IndexOf(parent) + 1 : 0;
}
- nsresult rv = aRange.SetStart(startNode, startOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = aRange.SetEnd(endNode, endOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsresult rv = aRange.SetStartAndEnd(startNode, startOffset,
+ endNode, endOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
return NS_OK;
}
nsresult
HTMLEditor::PromoteInlineRange(nsRange& aRange)
{
nsCOMPtr<nsINode> startNode = aRange.GetStartParent();
@@ -911,20 +914,21 @@ HTMLEditor::PromoteInlineRange(nsRange&
IsEditable(endNode) && IsAtEndOfNode(*endNode, endOffset)) {
nsCOMPtr<nsINode> parent = endNode->GetParentNode();
NS_ENSURE_TRUE(parent, NS_ERROR_NULL_POINTER);
// We are AFTER this node
endOffset = 1 + parent->IndexOf(endNode);
endNode = parent;
}
- nsresult rv = aRange.SetStart(startNode, startOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = aRange.SetEnd(endNode, endOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsresult rv = aRange.SetStartAndEnd(startNode, startOffset,
+ endNode, endOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
return NS_OK;
}
bool
HTMLEditor::IsAtFrontOfNode(nsINode& aNode,
int32_t aOffset)
{
--- a/editor/libeditor/SelectionState.cpp
+++ b/editor/libeditor/SelectionState.cpp
@@ -681,15 +681,16 @@ RangeItem::StoreRange(nsRange* aRange)
endNode = aRange->GetEndParent();
endOffset = aRange->EndOffset();
}
already_AddRefed<nsRange>
RangeItem::GetRange()
{
RefPtr<nsRange> range = new nsRange(startNode);
- if (NS_FAILED(range->Set(startNode, startOffset, endNode, endOffset))) {
+ if (NS_FAILED(range->SetStartAndEnd(startNode, startOffset,
+ endNode, endOffset))) {
return nullptr;
}
return range.forget();
}
} // namespace mozilla
--- a/editor/libeditor/WSRunObject.cpp
+++ b/editor/libeditor/WSRunObject.cpp
@@ -1291,17 +1291,17 @@ WSRunObject::DeleteChars(nsINode* aStart
mHTMLEditor->DeleteText(*node, 0, AssertedCast<uint32_t>(aEndOffset));
NS_ENSURE_SUCCESS(rv, rv);
}
break;
} else {
if (!range) {
range = new nsRange(aStartNode);
nsresult rv =
- range->Set(aStartNode, aStartOffset, aEndNode, aEndOffset);
+ range->SetStartAndEnd(aStartNode, aStartOffset, aEndNode, aEndOffset);
NS_ENSURE_SUCCESS(rv, rv);
}
bool nodeBefore, nodeAfter;
nsresult rv =
nsRange::CompareNodeToRange(node, range, &nodeBefore, &nodeAfter);
NS_ENSURE_SUCCESS(rv, rv);
if (nodeAfter) {
break;
--- a/editor/txtsvc/nsTextServicesDocument.cpp
+++ b/editor/txtsvc/nsTextServicesDocument.cpp
@@ -401,21 +401,23 @@ nsTextServicesDocument::ExpandRangeToWor
rngEndOffset != wordStartOffset ||
(rngEndNode == rngStartNode && rngEndOffset == rngStartOffset)) {
rngEndNode = wordEndNode;
rngEndOffset = wordEndOffset;
}
// Now adjust the range so that it uses our new
// end points.
-
- rv = range->SetEnd(rngEndNode, rngEndOffset);
- NS_ENSURE_SUCCESS(rv, rv);
-
- return range->SetStart(rngStartNode, rngStartOffset);
+ nsCOMPtr<nsINode> startNode = do_QueryInterface(rngStartNode);
+ nsCOMPtr<nsINode> endNode = do_QueryInterface(rngEndNode);
+ rv = range->SetStartAndEnd(startNode, rngStartOffset, endNode, rngEndOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
}
NS_IMETHODIMP
nsTextServicesDocument::SetFilter(nsITextServicesFilter *aFilter)
{
// Hang on to the filter so we can set it into the filtered iterator.
mTxtSvcFilter = aFilter;
--- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -159,26 +159,33 @@ mozInlineSpellStatus::InitForEditorChang
mRange = new nsRange(prevNode);
// ...we need to put the start and end in the correct order
int16_t cmpResult;
rv = mAnchorRange->ComparePoint(aPreviousNode, aPreviousOffset, &cmpResult);
NS_ENSURE_SUCCESS(rv, rv);
if (cmpResult < 0) {
// previous anchor node is before the current anchor
- rv = mRange->SetStart(aPreviousNode, aPreviousOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = mRange->SetEnd(aAnchorNode, aAnchorOffset);
+ nsCOMPtr<nsINode> previousNode = do_QueryInterface(aPreviousNode);
+ nsCOMPtr<nsINode> anchorNode = do_QueryInterface(aAnchorNode);
+ rv = mRange->SetStartAndEnd(previousNode, aPreviousOffset,
+ anchorNode, aAnchorOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
} else {
// previous anchor node is after (or the same as) the current anchor
- rv = mRange->SetStart(aAnchorNode, aAnchorOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = mRange->SetEnd(aPreviousNode, aPreviousOffset);
+ nsCOMPtr<nsINode> previousNode = do_QueryInterface(aPreviousNode);
+ nsCOMPtr<nsINode> anchorNode = do_QueryInterface(aAnchorNode);
+ rv = mRange->SetStartAndEnd(anchorNode, aAnchorOffset,
+ previousNode, aPreviousOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
- NS_ENSURE_SUCCESS(rv, rv);
// On insert save this range: DoSpellCheck optimizes things in this range.
// Otherwise, just leave this nullptr.
if (aAction == EditAction::insertText)
mCreatedRange = mRange;
// if we were given a range, we need to expand our range to encompass it
if (aStartNode && aEndNode) {
@@ -449,27 +456,29 @@ mozInlineSpellStatus::GetDocument(nsIDOM
// mozInlineSpellStatus::PositionToCollapsedRange
//
// Converts a given DOM position to a collapsed range covering that
// position. We use ranges to store DOM positions becuase they stay
// updated as the DOM is changed.
nsresult
mozInlineSpellStatus::PositionToCollapsedRange(nsIDOMDocument* aDocument,
- nsIDOMNode* aNode, int32_t aOffset, nsIDOMRange** aRange)
+ nsIDOMNode* aNode,
+ int32_t aOffset,
+ nsRange** aRange)
{
*aRange = nullptr;
- nsCOMPtr<nsIDOMRange> range;
- nsresult rv = aDocument->CreateRange(getter_AddRefs(range));
- NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsINode> documentNode = do_QueryInterface(aDocument);
+ RefPtr<nsRange> range = new nsRange(documentNode);
- rv = range->SetStart(aNode, aOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = range->SetEnd(aNode, aOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
+ nsresult rv = range->CollapseTo(node, aOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
range.swap(*aRange);
return NS_OK;
}
// mozInlineSpellResume
class mozInlineSpellResume : public Runnable
@@ -1162,19 +1171,18 @@ mozInlineSpellChecker::MakeSpellCheckRan
nsCOMPtr<nsIEditor> editor (do_QueryReferent(mEditor));
NS_ENSURE_TRUE(editor, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMDocument> doc;
rv = editor->GetDocument(getter_AddRefs(doc));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
- nsCOMPtr<nsIDOMRange> range;
- rv = doc->CreateRange(getter_AddRefs(range));
- NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsINode> documentNode = do_QueryInterface(doc);
+ RefPtr<nsRange> range = new nsRange(documentNode);
// possibly use full range of the editor
nsCOMPtr<nsIDOMElement> rootElem;
if (! aStartNode || ! aEndNode) {
rv = editor->GetRootElement(getter_AddRefs(rootElem));
NS_ENSURE_SUCCESS(rv, rv);
aStartNode = rootElem;
@@ -1196,25 +1204,33 @@ mozInlineSpellChecker::MakeSpellCheckRan
aEndOffset = childCount;
}
// sometimes we are are requested to check an empty range (possibly an empty
// document). This will result in assertions later.
if (aStartNode == aEndNode && aStartOffset == aEndOffset)
return NS_OK;
- rv = range->SetStart(aStartNode, aStartOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- if (aEndOffset)
- rv = range->SetEnd(aEndNode, aEndOffset);
- else
- rv = range->SetEndAfter(aEndNode);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsINode> startNode = do_QueryInterface(aStartNode);
+ nsCOMPtr<nsINode> endNode = do_QueryInterface(aEndNode);
+ if (aEndOffset) {
+ rv = range->SetStartAndEnd(startNode, aStartOffset, endNode, aEndOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ } else {
+ int32_t endOffset = -1;
+ endNode = nsRange::GetParentAndOffsetAfter(endNode, &endOffset);
+ rv = range->SetStartAndEnd(startNode, aStartOffset, endNode, endOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ }
- *aRange = static_cast<nsRange*>(range.forget().take());
+ range.swap(*aRange);
return NS_OK;
}
nsresult
mozInlineSpellChecker::SpellCheckBetweenNodes(nsIDOMNode *aStartNode,
int32_t aStartOffset,
nsIDOMNode *aEndNode,
int32_t aEndOffset)
--- a/extensions/spellcheck/src/mozInlineSpellChecker.h
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.h
@@ -80,25 +80,25 @@ public:
// Contains the range computed for the current word. Can be nullptr.
RefPtr<nsRange> mNoCheckRange;
// Indicates the position of the cursor for the event (so we can compute
// mNoCheckRange). It can be nullptr if we don't care about the cursor position
// (such as for the intial check of everything).
//
// For mOp == eOpNavigation, this is the NEW position of the cursor
- nsCOMPtr<nsIDOMRange> mAnchorRange;
+ RefPtr<nsRange> mAnchorRange;
// -----
// The following members are only for navigation events and are only
// stored for FinishNavigationEvent to initialize the other members.
// -----
// this is the OLD position of the cursor
- nsCOMPtr<nsIDOMRange> mOldNavigationAnchorRange;
+ RefPtr<nsRange> mOldNavigationAnchorRange;
// Set when we should force checking the current word. See
// mozInlineSpellChecker::HandleNavigationEvent for a description of why we
// have this.
bool mForceNavigationWordCheck;
// Contains the offset passed in to HandleNavigationEvent
int32_t mNewNavigationPositionOffset;
@@ -106,17 +106,17 @@ public:
protected:
nsresult FinishNavigationEvent(mozInlineSpellWordUtil& aWordUtil);
nsresult FillNoCheckRangeFromAnchor(mozInlineSpellWordUtil& aWordUtil);
nsresult GetDocument(nsIDOMDocument** aDocument);
nsresult PositionToCollapsedRange(nsIDOMDocument* aDocument,
nsIDOMNode* aNode, int32_t aOffset,
- nsIDOMRange** aRange);
+ nsRange** aRange);
};
class mozInlineSpellChecker final : public nsIInlineSpellChecker,
public nsIEditActionListener,
public nsIDOMEventListener,
public nsSupportsWeakReference
{
private:
--- a/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp
@@ -331,19 +331,21 @@ nsresult
mozInlineSpellWordUtil::MakeRange(NodeOffset aBegin, NodeOffset aEnd,
nsRange** aRange)
{
NS_ENSURE_ARG_POINTER(aBegin.mNode);
if (!mDOMDocument)
return NS_ERROR_NOT_INITIALIZED;
RefPtr<nsRange> range = new nsRange(aBegin.mNode);
- nsresult rv = range->Set(aBegin.mNode, aBegin.mOffset,
- aEnd.mNode, aEnd.mOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsresult rv = range->SetStartAndEnd(aBegin.mNode, aBegin.mOffset,
+ aEnd.mNode, aEnd.mOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
range.forget(aRange);
return NS_OK;
}
/*********** DOM text extraction ************/
// IsDOMWordSeparator
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -750,22 +750,22 @@ nsTextControlFrame::SetSelectionInternal
// Note that we use a new range to avoid having to do
// isIncreasing checks to avoid possible errors.
RefPtr<nsRange> range = new nsRange(mContent);
// Be careful to use internal nsRange methods which do not check to make sure
// we have access to the node.
nsCOMPtr<nsINode> start = do_QueryInterface(aStartNode);
nsCOMPtr<nsINode> end = do_QueryInterface(aEndNode);
- // XXXbz nsRange::Set takes int32_t (and ranges generally work on int32_t),
- // but we're passing uint32_t. The good news is that at this point our
- // endpoints should really be within our length, so not really that big. And
- // if they _are_ that big, Set() will simply error out, which is not too bad
- // for a case we don't expect to happen.
- nsresult rv = range->Set(start, aStartOffset, end, aEndOffset);
+ // XXXbz nsRange::SetStartAndEnd takes int32_t (and ranges generally work on
+ // int32_t), but we're passing uint32_t. The good news is that at this point
+ // our endpoints should really be within our length, so not really that big.
+ // And if they _are_ that big, SetStartAndEnd() will simply error out, which
+ // is not too bad for a case we don't expect to happen.
+ nsresult rv = range->SetStartAndEnd(start, aStartOffset, end, aEndOffset);
NS_ENSURE_SUCCESS(rv, rv);
// Get the selection, clear it and add the new range to it!
nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
NS_ASSERTION(txtCtrl, "Content not a text control element");
nsISelectionController* selCon = txtCtrl->GetSelectionController();
NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -1790,18 +1790,17 @@ nsFrameSelection::TakeFocus(nsIContent*
if (aMultipleSelection) {
// Remove existing collapsed ranges as there's no point in having
// non-anchor/focus collapsed ranges.
mDomSelections[index]->RemoveCollapsedRanges();
RefPtr<nsRange> newRange = new nsRange(aNewFocus);
- newRange->SetStart(aNewFocus, aContentOffset);
- newRange->SetEnd(aNewFocus, aContentOffset);
+ newRange->CollapseTo(aNewFocus, aContentOffset);
mDomSelections[index]->AddRange(newRange);
mBatching = batching;
mChangesDuringBatching = changes;
} else {
bool oldDesiredPosSet = mDesiredPosSet; //need to keep old desired position if it was set.
mDomSelections[index]->Collapse(aNewFocus, aContentOffset);
mDesiredPosSet = oldDesiredPosSet; //now reset desired pos back.
mBatching = batching;
@@ -3363,21 +3362,22 @@ Selection::GetTableSelectionType(nsIDOMR
nsresult
nsFrameSelection::CreateAndAddRange(nsINode *aParentNode, int32_t aOffset)
{
if (!aParentNode) return NS_ERROR_NULL_POINTER;
RefPtr<nsRange> range = new nsRange(aParentNode);
// Set range around child at given offset
- nsresult result = range->SetStart(aParentNode, aOffset);
- if (NS_FAILED(result)) return result;
- result = range->SetEnd(aParentNode, aOffset+1);
- if (NS_FAILED(result)) return result;
-
+ nsresult rv = range->SetStartAndEnd(aParentNode, aOffset,
+ aParentNode, aOffset + 1);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
int8_t index = GetIndexFromSelectionType(SelectionType::eNormal);
if (!mDomSelections[index])
return NS_ERROR_NULL_POINTER;
return mDomSelections[index]->AddRange(range);
}
// End of Table Selection
@@ -3795,42 +3795,39 @@ Selection::SubtractRange(RangeData* aRan
// cmp < 0, and cmp2 < 0
// If it right overlaps the new range then cmp > 0 and cmp2 > 0
// If it fully contains the new range, then cmp < 0 and cmp2 > 0
if (cmp2 > 0) {
// We need to add a new RangeData to the output, running from
// the end of aSubtract to the end of range
RefPtr<nsRange> postOverlap = new nsRange(aSubtract->GetEndParent());
-
- rv =
- postOverlap->SetStart(aSubtract->GetEndParent(), aSubtract->EndOffset());
- NS_ENSURE_SUCCESS(rv, rv);
- rv =
- postOverlap->SetEnd(range->GetEndParent(), range->EndOffset());
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = postOverlap->SetStartAndEnd(
+ aSubtract->GetEndParent(), aSubtract->EndOffset(),
+ range->GetEndParent(), range->EndOffset());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
if (!postOverlap->Collapsed()) {
if (!aOutput->InsertElementAt(0, RangeData(postOverlap)))
return NS_ERROR_OUT_OF_MEMORY;
(*aOutput)[0].mTextRangeStyle = aRange->mTextRangeStyle;
}
}
if (cmp < 0) {
// We need to add a new RangeData to the output, running from
// the start of the range to the start of aSubtract
RefPtr<nsRange> preOverlap = new nsRange(range->GetStartParent());
-
- nsresult rv =
- preOverlap->SetStart(range->GetStartParent(), range->StartOffset());
- NS_ENSURE_SUCCESS(rv, rv);
- rv =
- preOverlap->SetEnd(aSubtract->GetStartParent(), aSubtract->StartOffset());
- NS_ENSURE_SUCCESS(rv, rv);
-
+ rv = preOverlap->SetStartAndEnd(
+ range->GetStartParent(), range->StartOffset(),
+ aSubtract->GetStartParent(), aSubtract->StartOffset());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
if (!preOverlap->Collapsed()) {
if (!aOutput->InsertElementAt(0, RangeData(preOverlap)))
return NS_ERROR_OUT_OF_MEMORY;
(*aOutput)[0].mTextRangeStyle = aRange->mTextRangeStyle;
}
}
return NS_OK;
@@ -5272,22 +5269,17 @@ Selection::Collapse(nsINode& aParentNode
(parentNode == f->GetContent()->GetParentNode() &&
parentNode->IndexOf(f->GetContent()) + 1 == int32_t(aOffset))) {
frameSelection->SetHint(CARET_ASSOCIATE_AFTER);
}
}
}
RefPtr<nsRange> range = new nsRange(parentNode);
- result = range->SetEnd(parentNode, aOffset);
- if (NS_FAILED(result)) {
- aRv.Throw(result);
- return;
- }
- result = range->SetStart(parentNode, aOffset);
+ result = range->CollapseTo(parentNode, aOffset);
if (NS_FAILED(result)) {
aRv.Throw(result);
return;
}
#ifdef DEBUG_SELECTION
nsCOMPtr<nsIContent> content = do_QueryInterface(parentNode);
nsCOMPtr<nsIDocument> doc = do_QueryInterface(parentNode);
@@ -5680,21 +5672,18 @@ Selection::Extend(nsINode& aParentNode,
RefPtr<nsRange> difRange = new nsRange(&aParentNode);
if ((result1 == 0 && result3 < 0) || (result1 <= 0 && result2 < 0)){//a1,2 a,1,2
//select from 1 to 2 unless they are collapsed
range->SetEnd(aParentNode, aOffset, aRv);
if (aRv.Failed()) {
return;
}
SetDirection(eDirNext);
- res = difRange->SetEnd(range->GetEndParent(), range->EndOffset());
- nsresult tmp = difRange->SetStart(focusNode, focusOffset);
- if (NS_FAILED(tmp)) {
- res = tmp;
- }
+ res = difRange->SetStartAndEnd(focusNode, focusOffset,
+ range->GetEndParent(), range->EndOffset());
if (NS_FAILED(res)) {
aRv.Throw(res);
return;
}
SelectFrames(presContext, difRange , true);
res = SetAnchorFocusToRange(range);
if (NS_FAILED(res)) {
aRv.Throw(res);
@@ -5712,21 +5701,18 @@ Selection::Extend(nsINode& aParentNode,
res = SetAnchorFocusToRange(range);
if (NS_FAILED(res)) {
aRv.Throw(res);
return;
}
}
else if (result3 <= 0 && result2 >= 0) {//a,2,1 or a2,1 or a,21 or a21
//deselect from 2 to 1
- res = difRange->SetEnd(focusNode, focusOffset);
- difRange->SetStart(aParentNode, aOffset, aRv);
- if (aRv.Failed()) {
- return;
- }
+ res = difRange->SetStartAndEnd(&aParentNode, aOffset,
+ focusNode, focusOffset);
if (NS_FAILED(res)) {
aRv.Throw(res);
return;
}
range->SetEnd(aParentNode, aOffset, aRv);
if (aRv.Failed()) {
return;
@@ -5780,21 +5766,18 @@ Selection::Extend(nsINode& aParentNode,
return;
}
}
//select from a to 2
SelectFrames(presContext, range , true);
}
else if (result2 <= 0 && result3 >= 0) {//1,2,a or 12,a or 1,2a or 12a
//deselect from 1 to 2
- difRange->SetEnd(aParentNode, aOffset, aRv);
- res = difRange->SetStart(focusNode, focusOffset);
- if (aRv.Failed()) {
- return;
- }
+ res = difRange->SetStartAndEnd(focusNode, focusOffset,
+ &aParentNode, aOffset);
if (NS_FAILED(res)) {
aRv.Throw(res);
return;
}
SetDirection(eDirPrevious);
range->SetStart(aParentNode, aOffset, aRv);
if (aRv.Failed()) {
return;
@@ -5815,22 +5798,19 @@ Selection::Extend(nsINode& aParentNode,
}
SetDirection(eDirPrevious);
range->SetStart(aParentNode, aOffset, aRv);
if (aRv.Failed()) {
return;
}
//deselect from a to 1
if (focusNode != anchorNode || focusOffset!= anchorOffset) {//if collapsed diff dont do anything
- res = difRange->SetStart(anchorNode, anchorOffset);
- nsresult tmp = difRange->SetEnd(focusNode, focusOffset);
- if (NS_FAILED(tmp)) {
- res = tmp;
- }
- tmp = SetAnchorFocusToRange(range);
+ res = difRange->SetStartAndEnd(anchorNode, anchorOffset,
+ focusNode, focusOffset);
+ nsresult tmp = SetAnchorFocusToRange(range);
if (NS_FAILED(tmp)) {
res = tmp;
}
if (NS_FAILED(res)) {
aRv.Throw(res);
return;
}
SelectFrames(presContext, difRange, false);
@@ -5848,21 +5828,19 @@ Selection::Extend(nsINode& aParentNode,
}
else if (result2 >= 0 && result1 >= 0) {//2,1,a or 21,a or 2,1a or 21a
//select from 2 to 1
range->SetStart(aParentNode, aOffset, aRv);
if (aRv.Failed()) {
return;
}
SetDirection(eDirPrevious);
- res = difRange->SetEnd(focusNode, focusOffset);
- nsresult tmp = difRange->SetStart(range->GetStartParent(), range->StartOffset());
- if (NS_FAILED(tmp)) {
- res = tmp;
- }
+ res = difRange->SetStartAndEnd(
+ range->GetStartParent(), range->StartOffset(),
+ focusNode, focusOffset);
if (NS_FAILED(res)) {
aRv.Throw(res);
return;
}
SelectFrames(presContext, difRange, true);
res = SetAnchorFocusToRange(range);
if (NS_FAILED(res)) {
--- a/layout/printing/nsPrintEngine.cpp
+++ b/layout/printing/nsPrintEngine.cpp
@@ -2446,23 +2446,27 @@ CloneRangeToSelection(nsRange* aRange, n
int32_t endOffset = aRange->EndOffset();
NS_ENSURE_TRUE_VOID(startContainer && endContainer);
nsCOMPtr<nsIDOMNode> newStart = GetEqualNodeInCloneTree(startContainer, aDoc);
nsCOMPtr<nsIDOMNode> newEnd = GetEqualNodeInCloneTree(endContainer, aDoc);
NS_ENSURE_TRUE_VOID(newStart && newEnd);
nsCOMPtr<nsINode> newStartNode = do_QueryInterface(newStart);
- NS_ENSURE_TRUE_VOID(newStartNode);
+ nsCOMPtr<nsINode> newEndNode = do_QueryInterface(newEnd);
+ if (NS_WARN_IF(!newStartNode) || NS_WARN_IF(!newEndNode)) {
+ return;
+ }
RefPtr<nsRange> range = new nsRange(newStartNode);
- nsresult rv = range->SetStart(newStartNode, startOffset);
- NS_ENSURE_SUCCESS_VOID(rv);
- rv = range->SetEnd(newEnd, endOffset);
- NS_ENSURE_SUCCESS_VOID(rv);
+ nsresult rv =
+ range->SetStartAndEnd(newStartNode, startOffset, newEndNode, endOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return;
+ }
aSelection->AddRange(range);
}
static nsresult CloneSelection(nsIDocument* aOrigDoc, nsIDocument* aDoc)
{
nsIPresShell* origShell = aOrigDoc->GetShell();
nsIPresShell* shell = aDoc->GetShell();