Bug 1377978 - Make nsRange use uint32_t to offset

Tag #1375
This commit is contained in:
Matt A. Tobin 2020-04-17 06:10:23 -04:00 • committed by Roy Tam
commit 6ce9cc2a25
23 changed files with 425 additions and 287 deletions

View file

@ -2391,6 +2391,9 @@ nsContentUtils::ComparePoints(nsINode* aParent1, int32_t aOffset1,
bool* aDisconnected) bool* aDisconnected)
{ {
if (aParent1 == aParent2) { if (aParent1 == aParent2) {
// XXX This is odd. aOffset1 and/or aOffset2 may be -1, e.g., it's result
// of nsINode::IndexOf(), but this compares such invalid offset with
// valid offset.
return aOffset1 < aOffset2 ? -1 : return aOffset1 < aOffset2 ? -1 :
aOffset1 > aOffset2 ? 1 : aOffset1 > aOffset2 ? 1 :
0; 0;
@ -2441,10 +2444,14 @@ nsContentUtils::ComparePoints(nsINode* aParent1, int32_t aOffset1,
if (!pos1) { if (!pos1) {
nsINode* child2 = parents2.ElementAt(--pos2); nsINode* child2 = parents2.ElementAt(--pos2);
// XXX aOffset1 may be -1 as mentioned above. So, why does this return
// it's *before* of the valid DOM point?
return aOffset1 <= parent->IndexOf(child2) ? -1 : 1; return aOffset1 <= parent->IndexOf(child2) ? -1 : 1;
} }
nsINode* child1 = parents1.ElementAt(--pos1); nsINode* child1 = parents1.ElementAt(--pos1);
// XXX aOffset2 may be -1 as mentioned above. So, why does this return it's
// *after* of the valid DOM point?
return parent->IndexOf(child1) < aOffset2 ? -1 : 1; return parent->IndexOf(child1) < aOffset2 ? -1 : 1;
} }

View file

@ -339,6 +339,13 @@ public:
* NOTE! If the two nodes aren't in the same connected subtree, * NOTE! If the two nodes aren't in the same connected subtree,
* the result is 1, and the optional aDisconnected parameter * the result is 1, and the optional aDisconnected parameter
* is set to true. * is set to true.
*
* XXX aOffset1 and aOffset2 should be uint32_t since valid offset value is
* between 0 - UINT32_MAX. However, these methods work even with
* negative offset values! E.g., when aOffset1 is -1 and aOffset is 0,
* these methods return -1. Some root callers depend on this behavior.
* On the other hand, nsINode can have ATTRCHILD_ARRAY_MAX_CHILD_COUN
* (0x3FFFFF) at most. Therefore, they can be int32_t for now.
*/ */
static int32_t ComparePoints(nsINode* aParent1, int32_t aOffset1, static int32_t ComparePoints(nsINode* aParent1, int32_t aOffset1,
nsINode* aParent2, int32_t aOffset2, nsINode* aParent2, int32_t aOffset2,

View file

@ -1588,10 +1588,13 @@ nsHTMLCopyEncoder::IncludeInContext(nsINode *aNode)
nsresult nsresult
nsHTMLCopyEncoder::PromoteRange(nsIDOMRange *inRange) nsHTMLCopyEncoder::PromoteRange(nsIDOMRange *inRange)
{ {
if (!inRange) return NS_ERROR_NULL_POINTER; RefPtr<nsRange> range = static_cast<nsRange*>(inRange);
if (!range) {
return NS_ERROR_NULL_POINTER;
}
nsresult rv; nsresult rv;
nsCOMPtr<nsIDOMNode> startNode, endNode, common; nsCOMPtr<nsIDOMNode> startNode, endNode, common;
int32_t startOffset, endOffset; uint32_t startOffset, endOffset;
rv = inRange->GetCommonAncestorContainer(getter_AddRefs(common)); rv = inRange->GetCommonAncestorContainer(getter_AddRefs(common));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -1609,9 +1612,11 @@ nsHTMLCopyEncoder::PromoteRange(nsIDOMRange *inRange)
int32_t opStartOffset, opEndOffset; int32_t opStartOffset, opEndOffset;
// examine range endpoints. // examine range endpoints.
rv = GetPromotedPoint( kStart, startNode, startOffset, address_of(opStartNode), &opStartOffset, common); rv = GetPromotedPoint(kStart, startNode, static_cast<int32_t>(startOffset),
address_of(opStartNode), &opStartOffset, common);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = GetPromotedPoint( kEnd, endNode, endOffset, address_of(opEndNode), &opEndOffset, common); rv = GetPromotedPoint(kEnd, endNode, static_cast<int32_t>(endOffset),
address_of(opEndNode), &opEndOffset, common);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// if both range endpoints are at the common ancestor, check for possible inclusion of ancestors // if both range endpoints are at the common ancestor, check for possible inclusion of ancestors
@ -1623,9 +1628,9 @@ nsHTMLCopyEncoder::PromoteRange(nsIDOMRange *inRange)
} }
// set the range to the new values // set the range to the new values
rv = inRange->SetStart(opStartNode, opStartOffset); rv = inRange->SetStart(opStartNode, static_cast<uint32_t>(opStartOffset));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = inRange->SetEnd(opEndNode, opEndOffset); rv = inRange->SetEnd(opEndNode, static_cast<uint32_t>(opEndOffset));
return rv; return rv;
} }

View file

@ -2457,7 +2457,7 @@ nsFocusManager::GetSelectionLocation(nsIDocument* aDocument,
nsCOMPtr<nsIDOMNode> startNode, endNode; nsCOMPtr<nsIDOMNode> startNode, endNode;
bool isCollapsed = false; bool isCollapsed = false;
nsCOMPtr<nsIContent> startContent, endContent; nsCOMPtr<nsIContent> startContent, endContent;
int32_t startOffset = 0; uint32_t startOffset = 0;
if (domSelection) { if (domSelection) {
domSelection->GetIsCollapsed(&isCollapsed); domSelection->GetIsCollapsed(&isCollapsed);
nsCOMPtr<nsIDOMRange> domRange; nsCOMPtr<nsIDOMRange> domRange;
@ -2471,7 +2471,6 @@ nsFocusManager::GetSelectionLocation(nsIDocument* aDocument,
startContent = do_QueryInterface(startNode); startContent = do_QueryInterface(startNode);
if (startContent && startContent->IsElement()) { if (startContent && startContent->IsElement()) {
NS_ASSERTION(startOffset >= 0, "Start offset cannot be negative");
childContent = startContent->GetChildAt(startOffset); childContent = startContent->GetChildAt(startOffset);
if (childContent) { if (childContent) {
startContent = childContent; startContent = childContent;
@ -2480,9 +2479,8 @@ nsFocusManager::GetSelectionLocation(nsIDocument* aDocument,
endContent = do_QueryInterface(endNode); endContent = do_QueryInterface(endNode);
if (endContent && endContent->IsElement()) { if (endContent && endContent->IsElement()) {
int32_t endOffset = 0; uint32_t endOffset = 0;
domRange->GetEndOffset(&endOffset); domRange->GetEndOffset(&endOffset);
NS_ASSERTION(endOffset >= 0, "End offset cannot be negative");
childContent = endContent->GetChildAt(endOffset); childContent = endContent->GetChildAt(endOffset);
if (childContent) { if (childContent) {
endContent = childContent; endContent = childContent;
@ -2510,7 +2508,7 @@ nsFocusManager::GetSelectionLocation(nsIDocument* aDocument,
bool isFormControl = bool isFormControl =
startContent->IsNodeOfType(nsINode::eHTML_FORM_CONTROL); startContent->IsNodeOfType(nsINode::eHTML_FORM_CONTROL);
if (nodeValue.Length() == (uint32_t)startOffset && !isFormControl && if (nodeValue.Length() == startOffset && !isFormControl &&
startContent != aDocument->GetRootElement()) { startContent != aDocument->GetRootElement()) {
// Yes, indeed we were at the end of the last node // Yes, indeed we were at the end of the last node
nsCOMPtr<nsIFrameEnumerator> frameTraversal; nsCOMPtr<nsIFrameEnumerator> frameTraversal;

View file

@ -111,29 +111,35 @@ nsRange::CompareNodeToRange(nsINode* aNode, nsRange* aRange,
// so instead represent it by (node,0) and (node,numChildren) // so instead represent it by (node,0) and (node,numChildren)
parent = aNode; parent = aNode;
nodeStart = 0; nodeStart = 0;
nodeEnd = aNode->GetChildCount(); uint32_t childCount = aNode->GetChildCount();
MOZ_ASSERT(childCount <= INT32_MAX,
"There shouldn't be over INT32_MAX children");
nodeEnd = static_cast<int32_t>(childCount);
} }
else { else {
nodeStart = parent->IndexOf(aNode); nodeStart = parent->IndexOf(aNode);
nodeEnd = nodeStart + 1; nodeEnd = nodeStart + 1;
MOZ_ASSERT(nodeStart < nodeEnd, "nodeStart shouldn't be INT32_MAX");
} }
nsINode* rangeStartParent = aRange->GetStartParent(); nsINode* rangeStartParent = aRange->GetStartParent();
nsINode* rangeEndParent = aRange->GetEndParent(); nsINode* rangeEndParent = aRange->GetEndParent();
int32_t rangeStartOffset = aRange->StartOffset(); uint32_t rangeStartOffset = aRange->StartOffset();
int32_t rangeEndOffset = aRange->EndOffset(); uint32_t rangeEndOffset = aRange->EndOffset();
// is RANGE(start) <= NODE(start) ? // is RANGE(start) <= NODE(start) ?
bool disconnected = false; bool disconnected = false;
*outNodeBefore = nsContentUtils::ComparePoints(rangeStartParent, *outNodeBefore =
rangeStartOffset, nsContentUtils::ComparePoints(rangeStartParent,
static_cast<int32_t>(rangeStartOffset),
parent, nodeStart, parent, nodeStart,
&disconnected) > 0; &disconnected) > 0;
NS_ENSURE_TRUE(!disconnected, NS_ERROR_DOM_WRONG_DOCUMENT_ERR); NS_ENSURE_TRUE(!disconnected, NS_ERROR_DOM_WRONG_DOCUMENT_ERR);
// is RANGE(end) >= NODE(end) ? // is RANGE(end) >= NODE(end) ?
*outNodeAfter = nsContentUtils::ComparePoints(rangeEndParent, *outNodeAfter =
rangeEndOffset, nsContentUtils::ComparePoints(rangeEndParent,
static_cast<int32_t>(rangeEndOffset),
parent, nodeEnd, parent, nodeEnd,
&disconnected) < 0; &disconnected) < 0;
NS_ENSURE_TRUE(!disconnected, NS_ERROR_DOM_WRONG_DOCUMENT_ERR); NS_ENSURE_TRUE(!disconnected, NS_ERROR_DOM_WRONG_DOCUMENT_ERR);
@ -164,13 +170,17 @@ struct IsItemInRangeComparator
int operator()(const nsRange* const aRange) const int operator()(const nsRange* const aRange) const
{ {
int32_t cmp = nsContentUtils::ComparePoints(mNode, mEndOffset, int32_t cmp =
nsContentUtils::ComparePoints(
mNode, static_cast<int32_t>(mEndOffset),
aRange->GetStartParent(), aRange->GetStartParent(),
aRange->StartOffset()); static_cast<int32_t>(aRange->StartOffset()));
if (cmp == 1) { if (cmp == 1) {
cmp = nsContentUtils::ComparePoints(mNode, mStartOffset, cmp =
nsContentUtils::ComparePoints(
mNode, static_cast<int32_t>(mStartOffset),
aRange->GetEndParent(), aRange->GetEndParent(),
aRange->EndOffset()); static_cast<int32_t>(aRange->EndOffset()));
if (cmp == -1) { if (cmp == -1) {
return 0; return 0;
} }
@ -266,8 +276,8 @@ nsRange::nsRange(nsINode* aNode)
/* static */ /* static */
nsresult nsresult
nsRange::CreateRange(nsINode* aStartParent, int32_t aStartOffset, nsRange::CreateRange(nsINode* aStartParent, uint32_t aStartOffset,
nsINode* aEndParent, int32_t aEndOffset, nsINode* aEndParent, uint32_t aEndOffset,
nsRange** aRange) nsRange** aRange)
{ {
MOZ_ASSERT(aRange); MOZ_ASSERT(aRange);
@ -285,8 +295,8 @@ nsRange::CreateRange(nsINode* aStartParent, int32_t aStartOffset,
/* static */ /* static */
nsresult nsresult
nsRange::CreateRange(nsIDOMNode* aStartParent, int32_t aStartOffset, nsRange::CreateRange(nsIDOMNode* aStartParent, uint32_t aStartOffset,
nsIDOMNode* aEndParent, int32_t aEndOffset, nsIDOMNode* aEndParent, uint32_t aEndOffset,
nsRange** aRange) nsRange** aRange)
{ {
nsCOMPtr<nsINode> startParent = do_QueryInterface(aStartParent); nsCOMPtr<nsINode> startParent = do_QueryInterface(aStartParent);
@ -296,8 +306,8 @@ nsRange::CreateRange(nsIDOMNode* aStartParent, int32_t aStartOffset,
/* static */ /* static */
nsresult nsresult
nsRange::CreateRange(nsIDOMNode* aStartParent, int32_t aStartOffset, nsRange::CreateRange(nsIDOMNode* aStartParent, uint32_t aStartOffset,
nsIDOMNode* aEndParent, int32_t aEndOffset, nsIDOMNode* aEndParent, uint32_t aEndOffset,
nsIDOMRange** aRange) nsIDOMRange** aRange)
{ {
RefPtr<nsRange> range; RefPtr<nsRange> range;
@ -455,16 +465,28 @@ nsRange::CharacterDataChanged(nsIDocument* aDocument,
// again (when the new text node is notified). // again (when the new text node is notified).
nsINode* parentNode = aContent->GetParentNode(); nsINode* parentNode = aContent->GetParentNode();
int32_t index = -1; int32_t index = -1;
if (parentNode == mEndParent && mEndOffset > 0 && if (parentNode == mEndParent && mEndOffset > 0) {
(index = parentNode->IndexOf(aContent)) + 1 == mEndOffset) { index = parentNode->IndexOf(aContent);
++mEndOffset; NS_WARNING_ASSERTION(index >= 0,
"Shouldn't be called during removing the node or something");
if (static_cast<uint32_t>(index + 1) == mEndOffset) {
newEndNode = mEndParent;
newEndOffset = mEndOffset + 1;
MOZ_ASSERT(IsValidOffset(newEndOffset));
mEndOffsetWasIncremented = true; mEndOffsetWasIncremented = true;
} }
if (parentNode == mStartParent && mStartOffset > 0 && }
(index != -1 ? index : parentNode->IndexOf(aContent)) + 1 == mStartOffset) { if (parentNode == mStartParent && mStartOffset > 0) {
++mStartOffset; if (index <= 0) {
index = parentNode->IndexOf(aContent);
}
if (static_cast<uint32_t>(index + 1) == mStartOffset) {
newStartNode = mStartParent;
newStartOffset = mStartOffset + 1;
MOZ_ASSERT(IsValidOffset(newStartOffset));
mStartOffsetWasIncremented = true; mStartOffsetWasIncremented = true;
} }
}
#ifdef DEBUG #ifdef DEBUG
if (mStartOffsetWasIncremented || mEndOffsetWasIncremented) { if (mStartOffsetWasIncremented || mEndOffsetWasIncremented) {
mAssertNextInsertOrAppendIndex = mAssertNextInsertOrAppendIndex =
@ -476,16 +498,15 @@ nsRange::CharacterDataChanged(nsIDocument* aDocument,
// If the changed node contains our start boundary and the change starts // If the changed node contains our start boundary and the change starts
// before the boundary we'll need to adjust the offset. // before the boundary we'll need to adjust the offset.
if (aContent == mStartParent && if (aContent == mStartParent && aInfo->mChangeStart < mStartOffset) {
aInfo->mChangeStart < static_cast<uint32_t>(mStartOffset)) {
if (aInfo->mDetails) { if (aInfo->mDetails) {
// splitText(), aInfo->mDetails->mNextSibling is the new text node // splitText(), aInfo->mDetails->mNextSibling is the new text node
NS_ASSERTION(aInfo->mDetails->mType == NS_ASSERTION(aInfo->mDetails->mType ==
CharacterDataChangeInfo::Details::eSplit, CharacterDataChangeInfo::Details::eSplit,
"only a split can start before the end"); "only a split can start before the end");
NS_ASSERTION(static_cast<uint32_t>(mStartOffset) <= aInfo->mChangeEnd + 1, NS_ASSERTION(mStartOffset <= aInfo->mChangeEnd + 1,
"mStartOffset is beyond the end of this node"); "mStartOffset is beyond the end of this node");
newStartOffset = static_cast<uint32_t>(mStartOffset) - aInfo->mChangeStart; newStartOffset = mStartOffset - aInfo->mChangeStart;
newStartNode = aInfo->mDetails->mNextSibling; newStartNode = aInfo->mDetails->mNextSibling;
if (MOZ_UNLIKELY(aContent == mRoot)) { if (MOZ_UNLIKELY(aContent == mRoot)) {
newRoot = IsValidBoundary(newStartNode); newRoot = IsValidBoundary(newStartNode);
@ -502,7 +523,7 @@ nsRange::CharacterDataChanged(nsIDocument* aDocument,
} else { } else {
// If boundary is inside changed text, position it before change // If boundary is inside changed text, position it before change
// else adjust start offset for the change in length. // else adjust start offset for the change in length.
mStartOffset = static_cast<uint32_t>(mStartOffset) <= aInfo->mChangeEnd ? mStartOffset = mStartOffset <= aInfo->mChangeEnd ?
aInfo->mChangeStart : aInfo->mChangeStart :
mStartOffset + aInfo->mChangeStart - aInfo->mChangeEnd + mStartOffset + aInfo->mChangeStart - aInfo->mChangeEnd +
aInfo->mReplaceLength; aInfo->mReplaceLength;
@ -512,16 +533,15 @@ nsRange::CharacterDataChanged(nsIDocument* aDocument,
// Do the same thing for the end boundary, except for splitText of a node // Do the same thing for the end boundary, except for splitText of a node
// with no parent then only switch to the new node if the start boundary // with no parent then only switch to the new node if the start boundary
// did so too (otherwise the range would end up with disconnected nodes). // did so too (otherwise the range would end up with disconnected nodes).
if (aContent == mEndParent && if (aContent == mEndParent && aInfo->mChangeStart < mEndOffset) {
aInfo->mChangeStart < static_cast<uint32_t>(mEndOffset)) {
if (aInfo->mDetails && (aContent->GetParentNode() || newStartNode)) { if (aInfo->mDetails && (aContent->GetParentNode() || newStartNode)) {
// splitText(), aInfo->mDetails->mNextSibling is the new text node // splitText(), aInfo->mDetails->mNextSibling is the new text node
NS_ASSERTION(aInfo->mDetails->mType == NS_ASSERTION(aInfo->mDetails->mType ==
CharacterDataChangeInfo::Details::eSplit, CharacterDataChangeInfo::Details::eSplit,
"only a split can start before the end"); "only a split can start before the end");
NS_ASSERTION(static_cast<uint32_t>(mEndOffset) <= aInfo->mChangeEnd + 1, NS_ASSERTION(mEndOffset <= aInfo->mChangeEnd + 1,
"mEndOffset is beyond the end of this node"); "mEndOffset is beyond the end of this node");
newEndOffset = static_cast<uint32_t>(mEndOffset) - aInfo->mChangeStart; newEndOffset = mEndOffset - aInfo->mChangeStart;
newEndNode = aInfo->mDetails->mNextSibling; newEndNode = aInfo->mDetails->mNextSibling;
bool isCommonAncestor = IsInSelection() && mStartParent == mEndParent; bool isCommonAncestor = IsInSelection() && mStartParent == mEndParent;
@ -534,7 +554,7 @@ nsRange::CharacterDataChanged(nsIDocument* aDocument,
newEndNode->SetDescendantOfCommonAncestorForRangeInSelection(); newEndNode->SetDescendantOfCommonAncestorForRangeInSelection();
} }
} else { } else {
mEndOffset = static_cast<uint32_t>(mEndOffset) <= aInfo->mChangeEnd ? mEndOffset = mEndOffset <= aInfo->mChangeEnd ?
aInfo->mChangeStart : aInfo->mChangeStart :
mEndOffset + aInfo->mChangeStart - aInfo->mChangeEnd + mEndOffset + aInfo->mChangeStart - aInfo->mChangeEnd +
aInfo->mReplaceLength; aInfo->mReplaceLength;
@ -547,14 +567,14 @@ nsRange::CharacterDataChanged(nsIDocument* aDocument,
// that will be removed // that will be removed
nsIContent* removed = aInfo->mDetails->mNextSibling; nsIContent* removed = aInfo->mDetails->mNextSibling;
if (removed == mStartParent) { if (removed == mStartParent) {
newStartOffset = static_cast<uint32_t>(mStartOffset) + aInfo->mChangeStart; newStartOffset = mStartOffset + aInfo->mChangeStart;
newStartNode = aContent; newStartNode = aContent;
if (MOZ_UNLIKELY(removed == mRoot)) { if (MOZ_UNLIKELY(removed == mRoot)) {
newRoot = IsValidBoundary(newStartNode); newRoot = IsValidBoundary(newStartNode);
} }
} }
if (removed == mEndParent) { if (removed == mEndParent) {
newEndOffset = static_cast<uint32_t>(mEndOffset) + aInfo->mChangeStart; newEndOffset = mEndOffset + aInfo->mChangeStart;
newEndNode = aContent; newEndNode = aContent;
if (MOZ_UNLIKELY(removed == mRoot)) { if (MOZ_UNLIKELY(removed == mRoot)) {
newRoot = IsValidBoundary(newEndNode); newRoot = IsValidBoundary(newEndNode);
@ -568,13 +588,13 @@ nsRange::CharacterDataChanged(nsIDocument* aDocument,
// point before the first child is never affected by normalize().) // point before the first child is never affected by normalize().)
nsINode* parentNode = aContent->GetParentNode(); nsINode* parentNode = aContent->GetParentNode();
if (parentNode == mStartParent && mStartOffset > 0 && if (parentNode == mStartParent && mStartOffset > 0 &&
uint32_t(mStartOffset) < parentNode->GetChildCount() && mStartOffset < parentNode->GetChildCount() &&
removed == parentNode->GetChildAt(mStartOffset)) { removed == parentNode->GetChildAt(mStartOffset)) {
newStartNode = aContent; newStartNode = aContent;
newStartOffset = aInfo->mChangeStart; newStartOffset = aInfo->mChangeStart;
} }
if (parentNode == mEndParent && mEndOffset > 0 && if (parentNode == mEndParent && mEndOffset > 0 &&
uint32_t(mEndOffset) < parentNode->GetChildCount() && mEndOffset < parentNode->GetChildCount() &&
removed == parentNode->GetChildAt(mEndOffset)) { removed == parentNode->GetChildAt(mEndOffset)) {
newEndNode = aContent; newEndNode = aContent;
newEndOffset = aInfo->mChangeEnd; newEndOffset = aInfo->mChangeEnd;
@ -639,13 +659,19 @@ nsRange::ContentInserted(nsIDocument* aDocument,
nsINode* container = NODE_FROM(aContainer, aDocument); nsINode* container = NODE_FROM(aContainer, aDocument);
// Adjust position if a sibling was inserted. // Adjust position if a sibling was inserted.
if (container == mStartParent && aIndexInContainer < mStartOffset && if (container == mStartParent &&
(NS_WARN_IF(aIndexInContainer < 0) ||
static_cast<uint32_t>(aIndexInContainer) < mStartOffset) &&
!mStartOffsetWasIncremented) { !mStartOffsetWasIncremented) {
++mStartOffset; ++mStartOffset;
MOZ_ASSERT(IsValidOffset(mStartOffset));
} }
if (container == mEndParent && aIndexInContainer < mEndOffset && if (container == mEndParent &&
(NS_WARN_IF(aIndexInContainer < 0) ||
static_cast<uint32_t>(aIndexInContainer) < mEndOffset) &&
!mEndOffsetWasIncremented) { !mEndOffsetWasIncremented) {
++mEndOffset; ++mEndOffset;
MOZ_ASSERT(IsValidOffset(mEndOffset));
} }
if (container->IsSelectionDescendant() && if (container->IsSelectionDescendant() &&
!aChild->IsDescendantOfCommonAncestorForRangeInSelection()) { !aChild->IsDescendantOfCommonAncestorForRangeInSelection()) {
@ -684,7 +710,7 @@ nsRange::ContentRemoved(nsIDocument* aDocument,
// Adjust position if a sibling was removed... // Adjust position if a sibling was removed...
if (container == mStartParent) { if (container == mStartParent) {
if (aIndexInContainer < mStartOffset) { if (aIndexInContainer < static_cast<int32_t>(mStartOffset)) {
--mStartOffset; --mStartOffset;
} }
} else { // ...or gravitate if an ancestor was removed. } else { // ...or gravitate if an ancestor was removed.
@ -694,7 +720,7 @@ nsRange::ContentRemoved(nsIDocument* aDocument,
// Do same thing for end boundry. // Do same thing for end boundry.
if (container == mEndParent) { if (container == mEndParent) {
if (aIndexInContainer < mEndOffset) { if (aIndexInContainer < static_cast<int32_t>(mEndOffset)) {
--mEndOffset; --mEndOffset;
} }
} else if (didCheckStartParentDescendant && mStartParent == mEndParent) { } else if (didCheckStartParentDescendant && mStartParent == mEndParent) {
@ -753,12 +779,15 @@ nsRange::ParentChainChanged(nsIContent *aContent)
* Utilities for comparing points: API from nsIDOMRange * Utilities for comparing points: API from nsIDOMRange
******************************************************/ ******************************************************/
NS_IMETHODIMP NS_IMETHODIMP
nsRange::IsPointInRange(nsIDOMNode* aParent, int32_t aOffset, bool* aResult) nsRange::IsPointInRange(nsIDOMNode* aParent, uint32_t aOffset, bool* aResult)
{ {
nsCOMPtr<nsINode> parent = do_QueryInterface(aParent); nsCOMPtr<nsINode> parent = do_QueryInterface(aParent);
if (!parent) { if (!parent) {
return NS_ERROR_DOM_NOT_OBJECT_ERR; return NS_ERROR_DOM_NOT_OBJECT_ERR;
} }
if (NS_WARN_IF(!IsValidOffset(aOffset))) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
ErrorResult rv; ErrorResult rv;
*aResult = IsPointInRange(*parent, aOffset, rv); *aResult = IsPointInRange(*parent, aOffset, rv);
@ -781,7 +810,7 @@ nsRange::IsPointInRange(nsINode& aParent, uint32_t aOffset, ErrorResult& aRv)
// returns -1 if point is before range, 0 if point is in range, // returns -1 if point is before range, 0 if point is in range,
// 1 if point is after range. // 1 if point is after range.
NS_IMETHODIMP NS_IMETHODIMP
nsRange::ComparePoint(nsIDOMNode* aParent, int32_t aOffset, int16_t* aResult) nsRange::ComparePoint(nsIDOMNode* aParent, uint32_t aOffset, int16_t* aResult)
{ {
nsCOMPtr<nsINode> parent = do_QueryInterface(aParent); nsCOMPtr<nsINode> parent = do_QueryInterface(aParent);
NS_ENSURE_TRUE(parent, NS_ERROR_DOM_HIERARCHY_REQUEST_ERR); NS_ENSURE_TRUE(parent, NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
@ -815,14 +844,18 @@ nsRange::ComparePoint(nsINode& aParent, uint32_t aOffset, ErrorResult& aRv)
return 0; return 0;
} }
int32_t cmp; int32_t cmp =
if ((cmp = nsContentUtils::ComparePoints(&aParent, aOffset, nsContentUtils::ComparePoints(&aParent,
mStartParent, mStartOffset)) <= 0) { static_cast<int32_t>(aOffset),
mStartParent,
static_cast<int32_t>(mStartOffset));
if (cmp <= 0) {
return cmp; return cmp;
} }
if (nsContentUtils::ComparePoints(mEndParent, mEndOffset, if (nsContentUtils::ComparePoints(mEndParent,
&aParent, aOffset) == -1) { static_cast<int32_t>(mEndOffset),
&aParent,
static_cast<int32_t>(aOffset)) == -1) {
return 1; return 1;
} }
@ -865,11 +898,14 @@ nsRange::IntersectsNode(nsINode& aNode, ErrorResult& aRv)
// Steps 6-7. // Steps 6-7.
// Note: if disconnected is true, ComparePoints returns 1. // Note: if disconnected is true, ComparePoints returns 1.
bool disconnected = false; bool disconnected = false;
bool result = nsContentUtils::ComparePoints(mStartParent, mStartOffset, bool result =
nsContentUtils::ComparePoints(mStartParent,
static_cast<int32_t>(mStartOffset),
parent, nodeIndex + 1, parent, nodeIndex + 1,
&disconnected) < 0 && &disconnected) < 0 &&
nsContentUtils::ComparePoints(parent, nodeIndex, nsContentUtils::ComparePoints(parent, nodeIndex,
mEndParent, mEndOffset, mEndParent,
static_cast<int32_t>(mEndOffset),
&disconnected) < 0; &disconnected) < 0;
// Step 2. // Step 2.
@ -889,8 +925,8 @@ nsRange::IntersectsNode(nsINode& aNode, ErrorResult& aRv)
// Calling DoSetRange with either parent argument null will collapse // Calling DoSetRange with either parent argument null will collapse
// the range to have both endpoints point to the other node // the range to have both endpoints point to the other node
void void
nsRange::DoSetRange(nsINode* aStartN, int32_t aStartOffset, nsRange::DoSetRange(nsINode* aStartN, uint32_t aStartOffset,
nsINode* aEndN, int32_t aEndOffset, nsINode* aEndN, uint32_t aEndOffset,
nsINode* aRoot, bool aNotInsertedYet) nsINode* aRoot, bool aNotInsertedYet)
{ {
NS_PRECONDITION((aStartN && aEndN && aRoot) || NS_PRECONDITION((aStartN && aEndN && aRoot) ||
@ -916,6 +952,8 @@ nsRange::DoSetRange(nsINode* aStartN, int32_t aStartOffset,
/*For backward compatibility*/ /*For backward compatibility*/
aRoot->IsNodeOfType(nsINode::eCONTENT))), aRoot->IsNodeOfType(nsINode::eCONTENT))),
"Bad root"); "Bad root");
MOZ_ASSERT(IsValidOffset(aStartOffset));
MOZ_ASSERT(IsValidOffset(aEndOffset));
if (mRoot != aRoot) { if (mRoot != aRoot) {
if (mRoot) { if (mRoot) {
@ -1028,7 +1066,7 @@ nsRange::GetStartContainer(ErrorResult& aRv) const
} }
NS_IMETHODIMP NS_IMETHODIMP
nsRange::GetStartOffset(int32_t* aStartOffset) nsRange::GetStartOffset(uint32_t* aStartOffset)
{ {
if (!mIsPositioned) if (!mIsPositioned)
return NS_ERROR_NOT_INITIALIZED; return NS_ERROR_NOT_INITIALIZED;
@ -1070,7 +1108,7 @@ nsRange::GetEndContainer(ErrorResult& aRv) const
} }
NS_IMETHODIMP NS_IMETHODIMP
nsRange::GetEndOffset(int32_t* aEndOffset) nsRange::GetEndOffset(uint32_t* aEndOffset)
{ {
if (!mIsPositioned) if (!mIsPositioned)
return NS_ERROR_NOT_INITIALIZED; return NS_ERROR_NOT_INITIALIZED;
@ -1129,10 +1167,10 @@ nsRange::GetCommonAncestorContainer(nsIDOMNode** aCommonParent)
/* static */ /* static */
bool bool
nsRange::IsValidOffset(nsINode* aNode, int32_t aOffset) nsRange::IsValidOffset(nsINode* aNode, uint32_t aOffset)
{ {
return aNode && return aNode &&
aOffset >= 0 && IsValidOffset(aOffset) &&
static_cast<size_t>(aOffset) <= aNode->Length(); static_cast<size_t>(aOffset) <= aNode->Length();
} }
@ -1196,7 +1234,7 @@ nsRange::SetStart(nsINode& aNode, uint32_t aOffset, ErrorResult& aRv)
} }
NS_IMETHODIMP NS_IMETHODIMP
nsRange::SetStart(nsIDOMNode* aParent, int32_t aOffset) nsRange::SetStart(nsIDOMNode* aParent, uint32_t aOffset)
{ {
nsCOMPtr<nsINode> parent = do_QueryInterface(aParent); nsCOMPtr<nsINode> parent = do_QueryInterface(aParent);
if (!parent) { if (!parent) {
@ -1209,7 +1247,7 @@ nsRange::SetStart(nsIDOMNode* aParent, int32_t aOffset)
} }
/* virtual */ nsresult /* virtual */ nsresult
nsRange::SetStart(nsINode* aParent, int32_t aOffset) nsRange::SetStart(nsINode* aParent, uint32_t aOffset)
{ {
nsINode* newRoot = IsValidBoundary(aParent); nsINode* newRoot = IsValidBoundary(aParent);
if (!newRoot) { if (!newRoot) {
@ -1223,8 +1261,10 @@ nsRange::SetStart(nsINode* aParent, int32_t aOffset)
// Collapse if not positioned yet, if positioned in another doc or // Collapse if not positioned yet, if positioned in another doc or
// if the new start is after end. // if the new start is after end.
if (!mIsPositioned || newRoot != mRoot || if (!mIsPositioned || newRoot != mRoot ||
nsContentUtils::ComparePoints(aParent, aOffset, nsContentUtils::ComparePoints(aParent,
mEndParent, mEndOffset) == 1) { static_cast<int32_t>(aOffset),
mEndParent,
static_cast<int32_t>(mEndOffset)) == 1) {
DoSetRange(aParent, aOffset, aParent, aOffset, newRoot); DoSetRange(aParent, aOffset, aParent, aOffset, newRoot);
return NS_OK; return NS_OK;
@ -1245,7 +1285,10 @@ nsRange::SetStartBefore(nsINode& aNode, ErrorResult& aRv)
} }
AutoInvalidateSelection atEndOfBlock(this); AutoInvalidateSelection atEndOfBlock(this);
int32_t offset = -1; // If the node is being removed from its parent, GetContainerAndOffsetBefore()
// returns nullptr. Then, SetStart() will throw
// NS_ERROR_DOM_INVALID_NODE_TYPE_ERR.
uint32_t offset = UINT32_MAX;
nsINode* parent = GetParentAndOffsetBefore(&aNode, &offset); nsINode* parent = GetParentAndOffsetBefore(&aNode, &offset);
aRv = SetStart(parent, offset); aRv = SetStart(parent, offset);
} }
@ -1273,7 +1316,10 @@ nsRange::SetStartAfter(nsINode& aNode, ErrorResult& aRv)
} }
AutoInvalidateSelection atEndOfBlock(this); AutoInvalidateSelection atEndOfBlock(this);
int32_t offset = -1; // If the node is being removed from its parent, GetContainerAndOffsetAfter()
// returns nullptr. Then, SetStart() will throw
// NS_ERROR_DOM_INVALID_NODE_TYPE_ERR.
uint32_t offset = UINT32_MAX;
nsINode* parent = GetParentAndOffsetAfter(&aNode, &offset); nsINode* parent = GetParentAndOffsetAfter(&aNode, &offset);
aRv = SetStart(parent, offset); aRv = SetStart(parent, offset);
} }
@ -1304,7 +1350,7 @@ nsRange::SetEnd(nsINode& aNode, uint32_t aOffset, ErrorResult& aRv)
} }
NS_IMETHODIMP NS_IMETHODIMP
nsRange::SetEnd(nsIDOMNode* aParent, int32_t aOffset) nsRange::SetEnd(nsIDOMNode* aParent, uint32_t aOffset)
{ {
nsCOMPtr<nsINode> parent = do_QueryInterface(aParent); nsCOMPtr<nsINode> parent = do_QueryInterface(aParent);
if (!parent) { if (!parent) {
@ -1317,7 +1363,7 @@ nsRange::SetEnd(nsIDOMNode* aParent, int32_t aOffset)
} }
/* virtual */ nsresult /* virtual */ nsresult
nsRange::SetEnd(nsINode* aParent, int32_t aOffset) nsRange::SetEnd(nsINode* aParent, uint32_t aOffset)
{ {
nsINode* newRoot = IsValidBoundary(aParent); nsINode* newRoot = IsValidBoundary(aParent);
if (!newRoot) { if (!newRoot) {
@ -1331,8 +1377,10 @@ nsRange::SetEnd(nsINode* aParent, int32_t aOffset)
// Collapse if not positioned yet, if positioned in another doc or // Collapse if not positioned yet, if positioned in another doc or
// if the new end is before start. // if the new end is before start.
if (!mIsPositioned || newRoot != mRoot || if (!mIsPositioned || newRoot != mRoot ||
nsContentUtils::ComparePoints(mStartParent, mStartOffset, nsContentUtils::ComparePoints(mStartParent,
aParent, aOffset) == 1) { static_cast<int32_t>(mStartOffset),
aParent,
static_cast<int32_t>(aOffset)) == 1) {
DoSetRange(aParent, aOffset, aParent, aOffset, newRoot); DoSetRange(aParent, aOffset, aParent, aOffset, newRoot);
return NS_OK; return NS_OK;
@ -1344,8 +1392,8 @@ nsRange::SetEnd(nsINode* aParent, int32_t aOffset)
} }
nsresult nsresult
nsRange::SetStartAndEnd(nsINode* aStartParent, int32_t aStartOffset, nsRange::SetStartAndEnd(nsINode* aStartParent, uint32_t aStartOffset,
nsINode* aEndParent, int32_t aEndOffset) nsINode* aEndParent, uint32_t aEndOffset)
{ {
if (NS_WARN_IF(!aStartParent) || NS_WARN_IF(!aEndParent)) { if (NS_WARN_IF(!aStartParent) || NS_WARN_IF(!aEndParent)) {
return NS_ERROR_INVALID_ARG; return NS_ERROR_INVALID_ARG;
@ -1390,8 +1438,10 @@ nsRange::SetStartAndEnd(nsINode* aStartParent, int32_t aStartOffset,
// If the end point is before the start point, this should be collapsed at // If the end point is before the start point, this should be collapsed at
// the end point. // the end point.
if (nsContentUtils::ComparePoints(aStartParent, aStartOffset, if (nsContentUtils::ComparePoints(aStartParent,
aEndParent, aEndOffset) == 1) { static_cast<int32_t>(aStartOffset),
aEndParent,
static_cast<int32_t>(aEndOffset)) == 1) {
DoSetRange(aEndParent, aEndOffset, aEndParent, aEndOffset, newEndRoot); DoSetRange(aEndParent, aEndOffset, aEndParent, aEndOffset, newEndRoot);
return NS_OK; return NS_OK;
} }
@ -1411,7 +1461,10 @@ nsRange::SetEndBefore(nsINode& aNode, ErrorResult& aRv)
} }
AutoInvalidateSelection atEndOfBlock(this); AutoInvalidateSelection atEndOfBlock(this);
int32_t offset = -1; // If the node is being removed from its parent, GetContainerAndOffsetBefore()
// returns nullptr. Then, SetEnd() will throw
// NS_ERROR_DOM_INVALID_NODE_TYPE_ERR.
uint32_t offset = UINT32_MAX;
nsINode* parent = GetParentAndOffsetBefore(&aNode, &offset); nsINode* parent = GetParentAndOffsetBefore(&aNode, &offset);
aRv = SetEnd(parent, offset); aRv = SetEnd(parent, offset);
} }
@ -1439,7 +1492,10 @@ nsRange::SetEndAfter(nsINode& aNode, ErrorResult& aRv)
} }
AutoInvalidateSelection atEndOfBlock(this); AutoInvalidateSelection atEndOfBlock(this);
int32_t offset = -1; // If the node is being removed from its parent, GetContainerAndOffsetAfter()
// returns nullptr. Then, SetEnd() will throw
// NS_ERROR_DOM_INVALID_NODE_TYPE_ERR.
uint32_t offset = UINT32_MAX;
nsINode* parent = GetParentAndOffsetAfter(&aNode, &offset); nsINode* parent = GetParentAndOffsetAfter(&aNode, &offset);
aRv = SetEnd(parent, offset); aRv = SetEnd(parent, offset);
} }
@ -1500,7 +1556,9 @@ nsRange::SelectNode(nsINode& aNode, ErrorResult& aRv)
} }
int32_t index = parent->IndexOf(&aNode); int32_t index = parent->IndexOf(&aNode);
if (index < 0) { if (NS_WARN_IF(index < 0) ||
!IsValidOffset(static_cast<uint32_t>(index)) ||
!IsValidOffset(static_cast<uint32_t>(index) + 1)) {
aRv.Throw(NS_ERROR_DOM_INVALID_NODE_TYPE_ERR); aRv.Throw(NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
return; return;
} }
@ -1949,9 +2007,9 @@ nsRange::CutContents(DocumentFragment** aFragment)
// of Range gravity during our edits! // of Range gravity during our edits!
nsCOMPtr<nsINode> startContainer = mStartParent; nsCOMPtr<nsINode> startContainer = mStartParent;
int32_t startOffset = mStartOffset; uint32_t startOffset = mStartOffset;
nsCOMPtr<nsINode> endContainer = mEndParent; nsCOMPtr<nsINode> endContainer = mEndParent;
int32_t endOffset = mEndOffset; uint32_t endOffset = mEndOffset;
if (retval) { if (retval) {
// For extractContents(), abort early if there's a doctype (bug 719533). // For extractContents(), abort early if there's a doctype (bug 719533).
@ -1962,10 +2020,12 @@ nsRange::CutContents(DocumentFragment** aFragment)
RefPtr<DocumentType> doctype = commonAncestorDocument->GetDoctype(); RefPtr<DocumentType> doctype = commonAncestorDocument->GetDoctype();
if (doctype && if (doctype &&
nsContentUtils::ComparePoints(startContainer, startOffset, nsContentUtils::ComparePoints(startContainer,
static_cast<int32_t>(startOffset),
doctype, 0) < 0 && doctype, 0) < 0 &&
nsContentUtils::ComparePoints(doctype, 0, nsContentUtils::ComparePoints(doctype, 0,
endContainer, endOffset) < 0) { endContainer,
static_cast<int32_t>(endOffset)) < 0) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
} }
} }
@ -2060,8 +2120,7 @@ nsRange::CutContents(DocumentFragment** aFragment)
rv = charData->GetLength(&dataLength); rv = charData->GetLength(&dataLength);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (dataLength >= (uint32_t)startOffset) if (dataLength >= startOffset) {
{
nsMutationGuard guard; nsMutationGuard guard;
nsCOMPtr<nsIDOMCharacterData> cutNode; nsCOMPtr<nsIDOMCharacterData> cutNode;
rv = SplitDataNode(charData, startOffset, getter_AddRefs(cutNode)); rv = SplitDataNode(charData, startOffset, getter_AddRefs(cutNode));
@ -2077,9 +2136,6 @@ nsRange::CutContents(DocumentFragment** aFragment)
else if (node == endContainer) else if (node == endContainer)
{ {
// Delete or extract everything before endOffset. // Delete or extract everything before endOffset.
if (endOffset >= 0)
{
nsMutationGuard guard; nsMutationGuard guard;
nsCOMPtr<nsIDOMCharacterData> cutNode; nsCOMPtr<nsIDOMCharacterData> cutNode;
/* The Range spec clearly states clones get cut and original nodes /* The Range spec clearly states clones get cut and original nodes
@ -2091,8 +2147,6 @@ nsRange::CutContents(DocumentFragment** aFragment)
NS_ENSURE_STATE(!guard.Mutated(1) || NS_ENSURE_STATE(!guard.Mutated(1) ||
ValidateCurrentNode(this, iter)); ValidateCurrentNode(this, iter));
nodeToResult = do_QueryInterface(cutNode); nodeToResult = do_QueryInterface(cutNode);
}
handled = true; handled = true;
} }
} }
@ -2102,8 +2156,7 @@ nsRange::CutContents(DocumentFragment** aFragment)
if (node && node->IsElement() && if (node && node->IsElement() &&
((node == endContainer && endOffset == 0) || ((node == endContainer && endOffset == 0) ||
(node == startContainer && (node == startContainer &&
int32_t(node->AsElement()->GetChildCount()) == startOffset))) node->AsElement()->GetChildCount() == startOffset))) {
{
if (retval) { if (retval) {
ErrorResult rv; ErrorResult rv;
nodeToResult = node->CloneNode(false, rv); nodeToResult = node->CloneNode(false, rv);
@ -2248,7 +2301,7 @@ nsRange::CompareBoundaryPoints(uint16_t aHow, nsRange& aOtherRange,
} }
nsINode *ourNode, *otherNode; nsINode *ourNode, *otherNode;
int32_t ourOffset, otherOffset; uint32_t ourOffset, otherOffset;
switch (aHow) { switch (aHow) {
case nsIDOMRange::START_TO_START: case nsIDOMRange::START_TO_START:
@ -2286,8 +2339,10 @@ nsRange::CompareBoundaryPoints(uint16_t aHow, nsRange& aOtherRange,
return 0; return 0;
} }
return nsContentUtils::ComparePoints(ourNode, ourOffset, return nsContentUtils::ComparePoints(ourNode,
otherNode, otherOffset); static_cast<int32_t>(ourOffset),
otherNode,
static_cast<int32_t>(otherOffset));
} }
/* static */ nsresult /* static */ nsresult
@ -2404,8 +2459,7 @@ nsRange::CloneContents(ErrorResult& aRv)
bool deepClone = !node->IsElement() || bool deepClone = !node->IsElement() ||
(!(node == mEndParent && mEndOffset == 0) && (!(node == mEndParent && mEndOffset == 0) &&
!(node == mStartParent && !(node == mStartParent &&
mStartOffset == mStartOffset == node->AsElement()->GetChildCount()));
int32_t(node->AsElement()->GetChildCount())));
// Clone the current subtree! // Clone the current subtree!
@ -2435,7 +2489,7 @@ nsRange::CloneContents(ErrorResult& aRv)
return nullptr; return nullptr;
} }
if (dataLength > (uint32_t)mEndOffset) if (dataLength > mEndOffset)
{ {
aRv = charData->DeleteData(mEndOffset, dataLength - mEndOffset); aRv = charData->DeleteData(mEndOffset, dataLength - mEndOffset);
if (aRv.Failed()) { if (aRv.Failed()) {
@ -2593,7 +2647,7 @@ nsRange::InsertNode(nsINode& aNode, ErrorResult& aRv)
return; return;
} }
int32_t tStartOffset = StartOffset(); uint32_t tStartOffset = StartOffset();
nsCOMPtr<nsINode> tStartContainer = GetStartContainer(aRv); nsCOMPtr<nsINode> tStartContainer = GetStartContainer(aRv);
if (aRv.Failed()) { if (aRv.Failed()) {
@ -2654,18 +2708,20 @@ nsRange::InsertNode(nsINode& aNode, ErrorResult& aRv)
// We might need to update the end to include the new node (bug 433662). // We might need to update the end to include the new node (bug 433662).
// Ideally we'd only do this if needed, but it's tricky to know when it's // Ideally we'd only do this if needed, but it's tricky to know when it's
// needed in advance (bug 765799). // needed in advance (bug 765799).
int32_t newOffset; uint32_t newOffset;
if (referenceNode) { if (referenceNode) {
newOffset = IndexOf(referenceNode); int32_t indexInParent = IndexOf(referenceNode);
if (NS_WARN_IF(indexInParent < 0)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
newOffset = static_cast<uint32_t>(indexInParent);
} else { } else {
uint32_t length; aRv = tChildList->GetLength(&newOffset);
aRv = tChildList->GetLength(&length);
if (aRv.Failed()) { if (aRv.Failed()) {
return; return;
} }
newOffset = length;
} }
if (aNode.NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) { if (aNode.NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
@ -3021,10 +3077,15 @@ static nsresult GetPartialTextRect(nsLayoutUtils::RectCallback* aCallback,
nsRange::CollectClientRectsAndText(nsLayoutUtils::RectCallback* aCollector, nsRange::CollectClientRectsAndText(nsLayoutUtils::RectCallback* aCollector,
mozilla::dom::DOMStringList* aTextList, mozilla::dom::DOMStringList* aTextList,
nsRange* aRange, nsRange* aRange,
nsINode* aStartParent, int32_t aStartOffset, nsINode* aStartParent, uint32_t aStartOffset,
nsINode* aEndParent, int32_t aEndOffset, nsINode* aEndParent, uint32_t aEndOffset,
bool aClampToEdge, bool aFlushLayout) bool aClampToEdge, bool aFlushLayout)
{ {
// Currently, this method is called with start of end offset of nsRange.
// So, they must be between 0 - INT32_MAX.
MOZ_ASSERT(IsValidOffset(aStartOffset));
MOZ_ASSERT(IsValidOffset(aEndOffset));
// Hold strong pointers across the flush // Hold strong pointers across the flush
nsCOMPtr<nsINode> startContainer = aStartParent; nsCOMPtr<nsINode> startContainer = aStartParent;
nsCOMPtr<nsINode> endContainer = aEndParent; nsCOMPtr<nsINode> endContainer = aEndParent;
@ -3055,13 +3116,15 @@ nsRange::CollectClientRectsAndText(nsLayoutUtils::RectCallback* aCollector,
if (textFrame) { if (textFrame) {
int32_t outOffset; int32_t outOffset;
nsIFrame* outFrame; nsIFrame* outFrame;
textFrame->GetChildFrameContainingOffset(aStartOffset, false, textFrame->GetChildFrameContainingOffset(
static_cast<int32_t>(aStartOffset), false,
&outOffset, &outFrame); &outOffset, &outFrame);
if (outFrame) { if (outFrame) {
nsIFrame* relativeTo = nsIFrame* relativeTo =
nsLayoutUtils::GetContainingBlockForClientRect(outFrame); nsLayoutUtils::GetContainingBlockForClientRect(outFrame);
nsRect r = outFrame->GetRectRelativeToSelf(); nsRect r = outFrame->GetRectRelativeToSelf();
ExtractRectFromOffset(outFrame, aStartOffset, &r, false, aClampToEdge); ExtractRectFromOffset(outFrame, static_cast<int32_t>(aStartOffset),
&r, false, aClampToEdge);
r.width = 0; r.width = 0;
r = nsLayoutUtils::TransformFrameRectToAncestor(outFrame, r, relativeTo); r = nsLayoutUtils::TransformFrameRectToAncestor(outFrame, r, relativeTo);
aCollector->AddRect(r); aCollector->AddRect(r);
@ -3080,12 +3143,14 @@ nsRange::CollectClientRectsAndText(nsLayoutUtils::RectCallback* aCollector,
if (content->IsNodeOfType(nsINode::eTEXT)) { if (content->IsNodeOfType(nsINode::eTEXT)) {
if (node == startContainer) { if (node == startContainer) {
int32_t offset = startContainer == endContainer ? int32_t offset = startContainer == endContainer ?
aEndOffset : content->GetText()->GetLength(); static_cast<int32_t>(aEndOffset) : content->GetText()->GetLength();
GetPartialTextRect(aCollector, aTextList, content, aStartOffset, offset, GetPartialTextRect(aCollector, aTextList, content,
static_cast<int32_t>(aStartOffset), offset,
aClampToEdge, aFlushLayout); aClampToEdge, aFlushLayout);
continue; continue;
} else if (node == endContainer) { } else if (node == endContainer) {
GetPartialTextRect(aCollector, aTextList, content, 0, aEndOffset, GetPartialTextRect(aCollector, aTextList, content,
0, static_cast<int32_t>(aEndOffset),
aClampToEdge, aFlushLayout); aClampToEdge, aFlushLayout);
continue; continue;
} }
@ -3462,7 +3527,7 @@ ElementIsVisibleNoFlush(Element* aElement)
static void static void
AppendTransformedText(InnerTextAccumulator& aResult, AppendTransformedText(InnerTextAccumulator& aResult,
nsGenericDOMDataNode* aTextNode, nsGenericDOMDataNode* aTextNode,
int32_t aStart, int32_t aEnd) uint32_t aStart, uint32_t aEnd)
{ {
nsIFrame* frame = aTextNode->GetPrimaryFrame(); nsIFrame* frame = aTextNode->GetPrimaryFrame();
if (!IsVisibleAndNotInReplacedElement(frame)) { if (!IsVisibleAndNotInReplacedElement(frame)) {
@ -3571,7 +3636,7 @@ nsRange::GetInnerTextNoFlush(DOMString& aValue, ErrorResult& aError,
if (aEndParent->IsNodeOfType(nsINode::eTEXT)) { if (aEndParent->IsNodeOfType(nsINode::eTEXT)) {
endState = AT_NODE; endState = AT_NODE;
} else { } else {
if (uint32_t(aEndOffset) < aEndParent->GetChildCount()) { if (aEndOffset < aEndParent->GetChildCount()) {
endNode = aEndParent->GetChildAt(aEndOffset); endNode = aEndParent->GetChildAt(aEndOffset);
endState = AT_NODE; endState = AT_NODE;
} }

View file

@ -46,14 +46,14 @@ class nsRange final : public nsIDOMRange,
public: public:
explicit nsRange(nsINode* aNode); explicit nsRange(nsINode* aNode);
static nsresult CreateRange(nsIDOMNode* aStartParent, int32_t aStartOffset, static nsresult CreateRange(nsIDOMNode* aStartParent, uint32_t aStartOffset,
nsIDOMNode* aEndParent, int32_t aEndOffset, nsIDOMNode* aEndParent, uint32_t aEndOffset,
nsRange** aRange); nsRange** aRange);
static nsresult CreateRange(nsIDOMNode* aStartParent, int32_t aStartOffset, static nsresult CreateRange(nsIDOMNode* aStartParent, uint32_t aStartOffset,
nsIDOMNode* aEndParent, int32_t aEndOffset, nsIDOMNode* aEndParent, uint32_t aEndOffset,
nsIDOMRange** aRange); nsIDOMRange** aRange);
static nsresult CreateRange(nsINode* aStartParent, int32_t aStartOffset, static nsresult CreateRange(nsINode* aStartParent, uint32_t aStartOffset,
nsINode* aEndParent, int32_t aEndOffset, nsINode* aEndParent, uint32_t aEndOffset,
nsRange** aRange); nsRange** aRange);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@ -91,12 +91,12 @@ public:
return mEndParent; return mEndParent;
} }
int32_t StartOffset() const uint32_t StartOffset() const
{ {
return mStartOffset; return mStartOffset;
} }
int32_t EndOffset() const uint32_t EndOffset() const
{ {
return mEndOffset; return mEndOffset;
} }
@ -155,8 +155,8 @@ public:
* When you set both start and end of a range, you should use * When you set both start and end of a range, you should use
* SetStartAndEnd() instead. * SetStartAndEnd() instead.
*/ */
nsresult SetStart(nsINode* aParent, int32_t aOffset); nsresult SetStart(nsINode* aParent, uint32_t aOffset);
nsresult SetEnd(nsINode* aParent, int32_t aOffset); nsresult SetEnd(nsINode* aParent, uint32_t aOffset);
already_AddRefed<nsRange> CloneRange() const; already_AddRefed<nsRange> CloneRange() const;
@ -168,15 +168,15 @@ public:
* collapsed at the end point. Similarly, if they are in different root, * collapsed at the end point. Similarly, if they are in different root,
* the range will be collapsed at the end point. * the range will be collapsed at the end point.
*/ */
nsresult SetStartAndEnd(nsINode* aStartParent, int32_t aStartOffset, nsresult SetStartAndEnd(nsINode* aStartParent, uint32_t aStartOffset,
nsINode* aEndParent, int32_t aEndOffset); nsINode* aEndParent, uint32_t aEndOffset);
/** /**
* CollapseTo() works similar to call both SetStart() and SetEnd() with * CollapseTo() works similar to call both SetStart() and SetEnd() with
* same node and offset. This just calls SetStartAndParent() to set * same node and offset. This just calls SetStartAndParent() to set
* collapsed range at aParent and aOffset. * collapsed range at aParent and aOffset.
*/ */
nsresult CollapseTo(nsINode* aParent, int32_t aOffset) nsresult CollapseTo(nsINode* aParent, uint32_t aOffset)
{ {
return SetStartAndEnd(aParent, aOffset, aParent, aOffset); return SetStartAndEnd(aParent, aOffset, aParent, aOffset);
} }
@ -185,23 +185,36 @@ public:
* Retrieves node and offset for setting start or end of a range to * Retrieves node and offset for setting start or end of a range to
* before or after aNode. * before or after aNode.
*/ */
static nsINode* GetParentAndOffsetAfter(nsINode* aNode, int32_t* aOffset) static nsINode* GetParentAndOffsetAfter(nsINode* aNode, uint32_t* aOffset)
{ {
MOZ_ASSERT(aNode); MOZ_ASSERT(aNode);
MOZ_ASSERT(aOffset); MOZ_ASSERT(aOffset);
*aOffset = 0;
nsINode* parentNode = aNode->GetParentNode(); nsINode* parentNode = aNode->GetParentNode();
*aOffset = parentNode ? parentNode->IndexOf(aNode) : -1; if (!parentNode) {
if (*aOffset >= 0) { return nullptr;
(*aOffset)++;
} }
int32_t indexInParent = parentNode->IndexOf(aNode);
if (NS_WARN_IF(indexInParent < 0)) {
return nullptr;
}
*aOffset = static_cast<uint32_t>(indexInParent) + 1;
return parentNode; return parentNode;
} }
static nsINode* GetParentAndOffsetBefore(nsINode* aNode, int32_t* aOffset) static nsINode* GetParentAndOffsetBefore(nsINode* aNode, uint32_t* aOffset)
{ {
MOZ_ASSERT(aNode); MOZ_ASSERT(aNode);
MOZ_ASSERT(aOffset); MOZ_ASSERT(aOffset);
*aOffset = 0;
nsINode* parentNode = aNode->GetParentNode(); nsINode* parentNode = aNode->GetParentNode();
*aOffset = parentNode ? parentNode->IndexOf(aNode) : -1; if (!parentNode) {
return nullptr;
}
int32_t indexInParent = parentNode->IndexOf(aNode);
if (NS_WARN_IF(indexInParent < 0)) {
return nullptr;
}
*aOffset = static_cast<uint32_t>(indexInParent);
return parentNode; return parentNode;
} }
@ -316,8 +329,8 @@ public:
static void CollectClientRectsAndText(nsLayoutUtils::RectCallback* aCollector, static void CollectClientRectsAndText(nsLayoutUtils::RectCallback* aCollector,
mozilla::dom::DOMStringList* aTextList, mozilla::dom::DOMStringList* aTextList,
nsRange* aRange, nsRange* aRange,
nsINode* aStartParent, int32_t aStartOffset, nsINode* aStartParent, uint32_t aStartOffset,
nsINode* aEndParent, int32_t aEndOffset, nsINode* aEndParent, uint32_t aEndOffset,
bool aClampToEdge, bool aFlushLayout); bool aClampToEdge, bool aFlushLayout);
/** /**
@ -338,14 +351,25 @@ protected:
void RegisterCommonAncestor(nsINode* aNode); void RegisterCommonAncestor(nsINode* aNode);
void UnregisterCommonAncestor(nsINode* aNode); void UnregisterCommonAncestor(nsINode* aNode);
nsINode* IsValidBoundary(nsINode* aNode); nsINode* IsValidBoundary(nsINode* aNode);
static bool IsValidOffset(nsINode* aNode, int32_t aOffset);
/**
* XXX nsRange should accept 0 - UINT32_MAX as offset. However, users of
* nsRange treat offset as int32_t. Additionally, some other internal
* APIs like nsINode::IndexOf() use int32_t. Therefore, nsRange should
* accept only 0 - INT32_MAX as valid offset for now.
*/
static bool IsValidOffset(uint32_t aOffset)
{
return aOffset <= INT32_MAX;
}
static bool IsValidOffset(nsINode* aNode, uint32_t aOffset);
// CharacterDataChanged set aNotInsertedYet to true to disable an assertion // CharacterDataChanged set aNotInsertedYet to true to disable an assertion
// and suppress re-registering a range common ancestor node since // and suppress re-registering a range common ancestor node since
// the new text node of a splitText hasn't been inserted yet. // the new text node of a splitText hasn't been inserted yet.
// CharacterDataChanged does the re-registering when needed. // CharacterDataChanged does the re-registering when needed.
void DoSetRange(nsINode* aStartN, int32_t aStartOffset, void DoSetRange(nsINode* aStartN, uint32_t aStartOffset,
nsINode* aEndN, int32_t aEndOffset, nsINode* aEndN, uint32_t aEndOffset,
nsINode* aRoot, bool aNotInsertedYet = false); nsINode* aRoot, bool aNotInsertedYet = false);
/** /**
@ -393,8 +417,8 @@ protected:
nsCOMPtr<nsINode> mStartParent; nsCOMPtr<nsINode> mStartParent;
nsCOMPtr<nsINode> mEndParent; nsCOMPtr<nsINode> mEndParent;
RefPtr<mozilla::dom::Selection> mSelection; RefPtr<mozilla::dom::Selection> mSelection;
int32_t mStartOffset; uint32_t mStartOffset;
int32_t mEndOffset; uint32_t mEndOffset;
bool mIsPositioned : 1; bool mIsPositioned : 1;
bool mMaySpanAnonymousSubtrees : 1; bool mMaySpanAnonymousSubtrees : 1;

View file

@ -5631,7 +5631,7 @@ nsIContent* HTMLMediaElement::GetNextSource()
"Should only iterate over direct children"); "Should only iterate over direct children");
#endif #endif
int32_t startOffset = 0; uint32_t startOffset = 0;
rv = mSourcePointer->GetStartOffset(&startOffset); rv = mSourcePointer->GetStartOffset(&startOffset);
NS_ENSURE_SUCCESS(rv, nullptr); NS_ENSURE_SUCCESS(rv, nullptr);

View file

@ -16,14 +16,14 @@
interface nsIDOMRange : nsISupports interface nsIDOMRange : nsISupports
{ {
readonly attribute nsIDOMNode startContainer; readonly attribute nsIDOMNode startContainer;
readonly attribute long startOffset; readonly attribute unsigned long startOffset;
readonly attribute nsIDOMNode endContainer; readonly attribute nsIDOMNode endContainer;
readonly attribute long endOffset; readonly attribute unsigned long endOffset;
readonly attribute boolean collapsed; readonly attribute boolean collapsed;
readonly attribute nsIDOMNode commonAncestorContainer; readonly attribute nsIDOMNode commonAncestorContainer;
void setStart(in nsIDOMNode refNode, in long offset); void setStart(in nsIDOMNode refNode, in unsigned long offset);
void setEnd(in nsIDOMNode refNode, in long offset); void setEnd(in nsIDOMNode refNode, in unsigned long offset);
void setStartBefore(in nsIDOMNode refNode); void setStartBefore(in nsIDOMNode refNode);
void setStartAfter(in nsIDOMNode refNode); void setStartAfter(in nsIDOMNode refNode);
void setEndBefore(in nsIDOMNode refNode); void setEndBefore(in nsIDOMNode refNode);
@ -56,14 +56,14 @@ interface nsIDOMRange : nsISupports
// This returns true if parent+offset equals either // This returns true if parent+offset equals either
// of the boundary points or is between them. // of the boundary points or is between them.
boolean isPointInRange(in nsIDOMNode parent, boolean isPointInRange(in nsIDOMNode parent,
in long offset); in unsigned long offset);
// comparePoint returns // comparePoint returns
// -1 if point is before the start boundary point, // -1 if point is before the start boundary point,
// 0 if point is either of the boundary points or between them, // 0 if point is either of the boundary points or between them,
// 1 if point is after the end boundary point. // 1 if point is after the end boundary point.
// Sort of a strcmp for ranges. // Sort of a strcmp for ranges.
short comparePoint(in nsIDOMNode parent, in long offset); short comparePoint(in nsIDOMNode parent, in unsigned long offset);
/** /**
* Returns whether the range intersects node. * Returns whether the range intersects node.

View file

@ -5275,7 +5275,7 @@ EditorBase::GetIMESelectionStartOffsetIn(nsINode* aTextNode)
return -1; return -1;
} }
int32_t minOffset = INT32_MAX; uint32_t minOffset = UINT32_MAX;
static const SelectionType kIMESelectionTypes[] = { static const SelectionType kIMESelectionTypes[] = {
SelectionType::eIMERawClause, SelectionType::eIMERawClause,
SelectionType::eIMESelectedRawClause, SelectionType::eIMESelectedRawClause,
@ -5295,15 +5295,11 @@ EditorBase::GetIMESelectionStartOffsetIn(nsINode* aTextNode)
if (NS_WARN_IF(range->GetStartParent() != aTextNode)) { if (NS_WARN_IF(range->GetStartParent() != aTextNode)) {
// ignore the start offset... // ignore the start offset...
} else { } else {
MOZ_ASSERT(range->StartOffset() >= 0,
"start offset shouldn't be negative");
minOffset = std::min(minOffset, range->StartOffset()); minOffset = std::min(minOffset, range->StartOffset());
} }
if (NS_WARN_IF(range->GetEndParent() != aTextNode)) { if (NS_WARN_IF(range->GetEndParent() != aTextNode)) {
// ignore the end offset... // ignore the end offset...
} else { } else {
MOZ_ASSERT(range->EndOffset() >= 0,
"start offset shouldn't be negative");
minOffset = std::min(minOffset, range->EndOffset()); minOffset = std::min(minOffset, range->EndOffset());
} }
} }

View file

@ -427,7 +427,7 @@ HTMLEditRules::AfterEditInner(EditAction action,
NS_ENSURE_STATE(selection); NS_ENSURE_STATE(selection);
nsCOMPtr<nsIDOMNode> rangeStartParent, rangeEndParent; nsCOMPtr<nsIDOMNode> rangeStartParent, rangeEndParent;
int32_t rangeStartOffset = 0, rangeEndOffset = 0; uint32_t rangeStartOffset = 0, rangeEndOffset = 0;
// do we have a real range to act on? // do we have a real range to act on?
bool bDamagedRange = false; bool bDamagedRange = false;
if (mDocChangeRange) { if (mDocChangeRange) {
@ -535,8 +535,8 @@ HTMLEditRules::AfterEditInner(EditAction action,
mHTMLEditor->HandleInlineSpellCheck(action, selection, mHTMLEditor->HandleInlineSpellCheck(action, selection,
GetAsDOMNode(mRangeItem->startNode), GetAsDOMNode(mRangeItem->startNode),
mRangeItem->startOffset, mRangeItem->startOffset,
rangeStartParent, rangeStartOffset, rangeStartParent, static_cast<int32_t>(rangeStartOffset),
rangeEndParent, rangeEndOffset); rangeEndParent, static_cast<int32_t>(rangeEndOffset));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// detect empty doc // detect empty doc
@ -5151,9 +5151,8 @@ HTMLEditRules::NormalizeSelection(Selection* inSelection)
RefPtr<nsRange> range = inSelection->GetRangeAt(0); RefPtr<nsRange> range = inSelection->GetRangeAt(0);
NS_ENSURE_TRUE(range, NS_ERROR_NULL_POINTER); NS_ENSURE_TRUE(range, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMNode> startNode, endNode; nsCOMPtr<nsIDOMNode> startNode, endNode;
int32_t startOffset, endOffset; uint32_t startOffset, endOffset;
nsCOMPtr<nsIDOMNode> newStartNode, newEndNode; nsCOMPtr<nsIDOMNode> newStartNode, newEndNode;
int32_t newStartOffset, newEndOffset;
rv = range->GetStartContainer(getter_AddRefs(startNode)); rv = range->GetStartContainer(getter_AddRefs(startNode));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -5166,22 +5165,22 @@ HTMLEditRules::NormalizeSelection(Selection* inSelection)
// adjusted values default to original values // adjusted values default to original values
newStartNode = startNode; newStartNode = startNode;
newStartOffset = startOffset; uint32_t newStartOffset = startOffset;
newEndNode = endNode; newEndNode = endNode;
newEndOffset = endOffset; uint32_t newEndOffset = endOffset;
// some locals we need for whitespace code // some locals we need for whitespace code
nsCOMPtr<nsINode> unused; nsCOMPtr<nsINode> unused;
int32_t offset; int32_t offset = -1;
WSType wsType; WSType wsType;
// let the whitespace code do the heavy lifting // let the whitespace code do the heavy lifting
WSRunObject wsEndObj(mHTMLEditor, endNode, endOffset); WSRunObject wsEndObj(mHTMLEditor, endNode, static_cast<int32_t>(endOffset));
// is there any intervening visible whitespace? if so we can't push selection past that, // is there any intervening visible whitespace? if so we can't push selection past that,
// it would visibly change maening of users selection // it would visibly change maening of users selection
nsCOMPtr<nsINode> endNode_(do_QueryInterface(endNode)); nsCOMPtr<nsINode> endNode_(do_QueryInterface(endNode));
wsEndObj.PriorVisibleNode(endNode_, endOffset, address_of(unused), wsEndObj.PriorVisibleNode(endNode_, static_cast<int32_t>(endOffset),
&offset, &wsType); address_of(unused), &offset, &wsType);
if (wsType != WSType::text && wsType != WSType::normalWS) { if (wsType != WSType::text && wsType != WSType::normalWS) {
// eThisBlock and eOtherBlock conveniently distinquish cases // eThisBlock and eOtherBlock conveniently distinquish cases
// of going "down" into a block and "up" out of a block. // of going "down" into a block and "up" out of a block.
@ -5191,36 +5190,44 @@ HTMLEditRules::NormalizeSelection(Selection* inSelection)
GetAsDOMNode(mHTMLEditor->GetRightmostChild(wsEndObj.mStartReasonNode, GetAsDOMNode(mHTMLEditor->GetRightmostChild(wsEndObj.mStartReasonNode,
true)); true));
if (child) { if (child) {
newEndNode = EditorBase::GetNodeLocation(child, &newEndOffset); int32_t offset = -1;
++newEndOffset; // offset *after* child newEndNode = EditorBase::GetNodeLocation(child, &offset);
// offset *after* child
newEndOffset = static_cast<uint32_t>(offset + 1);
} }
// else block is empty - we can leave selection alone here, i think. // else block is empty - we can leave selection alone here, i think.
} else if (wsEndObj.mStartReason == WSType::thisBlock) { } else if (wsEndObj.mStartReason == WSType::thisBlock) {
// endpoint is just after start of this block // endpoint is just after start of this block
nsCOMPtr<nsIDOMNode> child; nsCOMPtr<nsIDOMNode> child;
NS_ENSURE_STATE(mHTMLEditor); NS_ENSURE_STATE(mHTMLEditor);
mHTMLEditor->GetPriorHTMLNode(endNode, endOffset, address_of(child)); mHTMLEditor->GetPriorHTMLNode(endNode, static_cast<int32_t>(endOffset),
address_of(child));
if (child) { if (child) {
newEndNode = EditorBase::GetNodeLocation(child, &newEndOffset); int32_t offset = -1;
++newEndOffset; // offset *after* child newEndNode = EditorBase::GetNodeLocation(child, &offset);
// offset *after* child
newEndOffset = static_cast<uint32_t>(offset + 1);
} }
// else block is empty - we can leave selection alone here, i think. // else block is empty - we can leave selection alone here, i think.
} else if (wsEndObj.mStartReason == WSType::br) { } else if (wsEndObj.mStartReason == WSType::br) {
// endpoint is just after break. lets adjust it to before it. // endpoint is just after break. lets adjust it to before it.
int32_t offset = -1;
newEndNode = newEndNode =
EditorBase::GetNodeLocation(GetAsDOMNode(wsEndObj.mStartReasonNode), EditorBase::GetNodeLocation(GetAsDOMNode(wsEndObj.mStartReasonNode),
&newEndOffset); &offset);
newEndOffset = static_cast<uint32_t>(offset);;
} }
} }
// similar dealio for start of range // similar dealio for start of range
WSRunObject wsStartObj(mHTMLEditor, startNode, startOffset); WSRunObject wsStartObj(mHTMLEditor, startNode,
static_cast<int32_t>(startOffset));
// is there any intervening visible whitespace? if so we can't push selection past that, // is there any intervening visible whitespace? if so we can't push selection past that,
// it would visibly change maening of users selection // it would visibly change maening of users selection
nsCOMPtr<nsINode> startNode_(do_QueryInterface(startNode)); nsCOMPtr<nsINode> startNode_(do_QueryInterface(startNode));
wsStartObj.NextVisibleNode(startNode_, startOffset, address_of(unused), wsStartObj.NextVisibleNode(startNode_, static_cast<int32_t>(startOffset),
&offset, &wsType); address_of(unused), &offset, &wsType);
if (wsType != WSType::text && wsType != WSType::normalWS) { if (wsType != WSType::text && wsType != WSType::normalWS) {
// eThisBlock and eOtherBlock conveniently distinquish cases // eThisBlock and eOtherBlock conveniently distinquish cases
// of going "down" into a block and "up" out of a block. // of going "down" into a block and "up" out of a block.
@ -5230,23 +5237,31 @@ HTMLEditRules::NormalizeSelection(Selection* inSelection)
GetAsDOMNode(mHTMLEditor->GetLeftmostChild(wsStartObj.mEndReasonNode, GetAsDOMNode(mHTMLEditor->GetLeftmostChild(wsStartObj.mEndReasonNode,
true)); true));
if (child) { if (child) {
newStartNode = EditorBase::GetNodeLocation(child, &newStartOffset); int32_t offset = -1;
newStartNode = EditorBase::GetNodeLocation(child, &offset);
newStartOffset = static_cast<uint32_t>(offset);
} }
// else block is empty - we can leave selection alone here, i think. // else block is empty - we can leave selection alone here, i think.
} else if (wsStartObj.mEndReason == WSType::thisBlock) { } else if (wsStartObj.mEndReason == WSType::thisBlock) {
// startpoint is just before end of this block // startpoint is just before end of this block
nsCOMPtr<nsIDOMNode> child; nsCOMPtr<nsIDOMNode> child;
NS_ENSURE_STATE(mHTMLEditor); NS_ENSURE_STATE(mHTMLEditor);
mHTMLEditor->GetNextHTMLNode(startNode, startOffset, address_of(child)); mHTMLEditor->GetNextHTMLNode(startNode, static_cast<int32_t>(startOffset),
address_of(child));
if (child) { if (child) {
newStartNode = EditorBase::GetNodeLocation(child, &newStartOffset); int32_t offset = -1;
newStartNode = EditorBase::GetNodeLocation(child, &offset);
newStartOffset = static_cast<uint32_t>(offset);
} }
// else block is empty - we can leave selection alone here, i think. // else block is empty - we can leave selection alone here, i think.
} else if (wsStartObj.mEndReason == WSType::br) { } else if (wsStartObj.mEndReason == WSType::br) {
// startpoint is just before a break. lets adjust it to after it. // startpoint is just before a break. lets adjust it to after it.
int32_t offset = -1;
newStartNode = newStartNode =
EditorBase::GetNodeLocation(GetAsDOMNode(wsStartObj.mEndReasonNode), EditorBase::GetNodeLocation(GetAsDOMNode(wsStartObj.mEndReasonNode),
&newStartOffset); &offset);
// offset *after* break
newStartOffset = static_cast<uint32_t>(offset + 1);
++newStartOffset; // offset *after* break ++newStartOffset; // offset *after* break
} }
} }
@ -7974,7 +7989,7 @@ HTMLEditRules::UpdateDocChangeRange(nsRange* aRange)
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// Positive result means mDocChangeRange start is after aRange start. // Positive result means mDocChangeRange start is after aRange start.
if (result > 0) { if (result > 0) {
int32_t startOffset; uint32_t startOffset;
rv = aRange->GetStartOffset(&startOffset); rv = aRange->GetStartOffset(&startOffset);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = mDocChangeRange->SetStart(startNode, startOffset); rv = mDocChangeRange->SetStart(startNode, startOffset);
@ -7988,9 +8003,9 @@ HTMLEditRules::UpdateDocChangeRange(nsRange* aRange)
// Negative result means mDocChangeRange end is before aRange end. // Negative result means mDocChangeRange end is before aRange end.
if (result < 0) { if (result < 0) {
nsCOMPtr<nsIDOMNode> endNode; nsCOMPtr<nsIDOMNode> endNode;
int32_t endOffset;
rv = aRange->GetEndContainer(getter_AddRefs(endNode)); rv = aRange->GetEndContainer(getter_AddRefs(endNode));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
uint32_t endOffset;
rv = aRange->GetEndOffset(&endOffset); rv = aRange->GetEndOffset(&endOffset);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = mDocChangeRange->SetEnd(endNode, endOffset); rv = mDocChangeRange->SetEnd(endNode, endOffset);

View file

@ -2405,21 +2405,19 @@ HTMLEditor::GetSelectedElement(const nsAString& aTagName,
NS_ENSURE_STATE(range); NS_ENSURE_STATE(range);
nsCOMPtr<nsIDOMNode> startParent; nsCOMPtr<nsIDOMNode> startParent;
int32_t startOffset, endOffset;
nsresult rv = range->GetStartContainer(getter_AddRefs(startParent)); nsresult rv = range->GetStartContainer(getter_AddRefs(startParent));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = range->GetStartOffset(&startOffset); uint32_t startOffset = range->StartOffset();
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNode> endParent; nsCOMPtr<nsIDOMNode> endParent;
rv = range->GetEndContainer(getter_AddRefs(endParent)); rv = range->GetEndContainer(getter_AddRefs(endParent));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = range->GetEndOffset(&endOffset); uint32_t endOffset = range->EndOffset();
NS_ENSURE_SUCCESS(rv, rv);
// Optimization for a single selected element // Optimization for a single selected element
if (startParent && startParent == endParent && endOffset - startOffset == 1) { if (startParent && startParent == endParent && endOffset - startOffset == 1) {
nsCOMPtr<nsIDOMNode> selectedNode = GetChildAt(startParent, startOffset); nsCOMPtr<nsIDOMNode> selectedNode =
GetChildAt(startParent, static_cast<int32_t>(startOffset));
NS_ENSURE_SUCCESS(rv, NS_OK); NS_ENSURE_SUCCESS(rv, NS_OK);
if (selectedNode) { if (selectedNode) {
selectedNode->GetNodeName(domTagName); selectedNode->GetNodeName(domTagName);

View file

@ -145,14 +145,13 @@ HTMLEditor::LoadHTML(const nsAString& aInputString)
rv = range->GetStartContainer(getter_AddRefs(parent)); rv = range->GetStartContainer(getter_AddRefs(parent));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(parent, NS_ERROR_NULL_POINTER); NS_ENSURE_TRUE(parent, NS_ERROR_NULL_POINTER);
int32_t childOffset; uint32_t childOffset = range->StartOffset();
rv = range->GetStartOffset(&childOffset);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNode> nodeToInsert; nsCOMPtr<nsIDOMNode> nodeToInsert;
docfrag->GetFirstChild(getter_AddRefs(nodeToInsert)); docfrag->GetFirstChild(getter_AddRefs(nodeToInsert));
while (nodeToInsert) { while (nodeToInsert) {
rv = InsertNode(nodeToInsert, parent, childOffset++); rv = InsertNode(nodeToInsert, parent,
static_cast<int32_t>(childOffset++));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
docfrag->GetFirstChild(getter_AddRefs(nodeToInsert)); docfrag->GetFirstChild(getter_AddRefs(nodeToInsert));
} }

View file

@ -1078,7 +1078,7 @@ HTMLEditor::GetInlinePropertyBase(nsIAtom& aProperty,
if (content->GetAsText()) { if (content->GetAsText()) {
if (!isCollapsed && first && firstNodeInRange) { if (!isCollapsed && first && firstNodeInRange) {
firstNodeInRange = false; firstNodeInRange = false;
if (range->StartOffset() == (int32_t)content->Length()) { if (range->StartOffset() == content->Length()) {
continue; continue;
} }
} else if (content == endNode && !endOffset) { } else if (content == endNode && !endOffset) {

View file

@ -2932,11 +2932,10 @@ HTMLEditor::GetCellFromRange(nsRange* aRange,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(startParent, NS_ERROR_FAILURE); NS_ENSURE_TRUE(startParent, NS_ERROR_FAILURE);
int32_t startOffset; uint32_t startOffset = aRange->StartOffset();
rv = aRange->GetStartOffset(&startOffset);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNode> childNode = GetChildAt(startParent, startOffset); nsCOMPtr<nsIDOMNode> childNode =
GetChildAt(startParent, static_cast<int32_t>(startOffset));
// This means selection is probably at a text node (or end of doc?) // This means selection is probably at a text node (or end of doc?)
if (!childNode) { if (!childNode) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -2947,15 +2946,11 @@ HTMLEditor::GetCellFromRange(nsRange* aRange,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(startParent, NS_ERROR_FAILURE); NS_ENSURE_TRUE(startParent, NS_ERROR_FAILURE);
int32_t endOffset;
rv = aRange->GetEndOffset(&endOffset);
NS_ENSURE_SUCCESS(rv, rv);
// If a cell is deleted, the range is collapse // If a cell is deleted, the range is collapse
// (startOffset == endOffset) // (startOffset == aRange->EndOffset())
// so tell caller the cell wasn't found // so tell caller the cell wasn't found
if (startParent == endParent && if (startParent == endParent &&
endOffset == startOffset+1 && aRange->EndOffset() == startOffset+1 &&
HTMLEditUtils::IsTableCell(childNode)) { HTMLEditUtils::IsTableCell(childNode)) {
// Should we also test if frame is selected? (Use GetCellDataAt()) // Should we also test if frame is selected? (Use GetCellDataAt())
// (Let's not for now -- more efficient) // (Let's not for now -- more efficient)

View file

@ -240,13 +240,15 @@ ContentIsInTraversalRange(nsRange* aRange, nsIDOMNode* aNextNode, bool aIsPreMod
nsCOMPtr<nsIDOMNode> sNode; nsCOMPtr<nsIDOMNode> sNode;
nsCOMPtr<nsIDOMNode> eNode; nsCOMPtr<nsIDOMNode> eNode;
int32_t sOffset; uint32_t sOffset;
int32_t eOffset; uint32_t eOffset;
aRange->GetStartContainer(getter_AddRefs(sNode)); aRange->GetStartContainer(getter_AddRefs(sNode));
aRange->GetStartOffset(&sOffset); aRange->GetStartOffset(&sOffset);
aRange->GetEndContainer(getter_AddRefs(eNode)); aRange->GetEndContainer(getter_AddRefs(eNode));
aRange->GetEndOffset(&eOffset); aRange->GetEndOffset(&eOffset);
return ContentIsInTraversalRange(content, aIsPreMode, sNode, sOffset, eNode, eOffset); return ContentIsInTraversalRange(content, aIsPreMode,
sNode, static_cast<int32_t>(sOffset),
eNode, static_cast<int32_t>(eOffset));
} }
//------------------------------------------------------------ //------------------------------------------------------------

View file

@ -510,7 +510,6 @@ nsTextServicesDocument::LastSelectedBlock(TSDBlockSelectionStatus *aSelStatus,
nsCOMPtr<nsIContentIterator> iter; nsCOMPtr<nsIContentIterator> iter;
RefPtr<nsRange> range; RefPtr<nsRange> range;
nsCOMPtr<nsIDOMNode> parent; nsCOMPtr<nsIDOMNode> parent;
int32_t rangeCount, offset;
if (isCollapsed) { if (isCollapsed) {
// We have a caret. Check if the caret is in a text node. // We have a caret. Check if the caret is in a text node.
@ -537,6 +536,7 @@ nsTextServicesDocument::LastSelectedBlock(TSDBlockSelectionStatus *aSelStatus,
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
uint32_t offset;
rv = range->GetStartOffset(&offset); rv = range->GetStartOffset(&offset);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
@ -596,7 +596,8 @@ nsTextServicesDocument::LastSelectedBlock(TSDBlockSelectionStatus *aSelStatus,
// position to the end of the document, then walk forwards // position to the end of the document, then walk forwards
// till you find a text node, then find the beginning of it's block. // till you find a text node, then find the beginning of it's block.
rv = CreateDocumentContentRootToNodeOffsetRange(parent, offset, false, rv = CreateDocumentContentRootToNodeOffsetRange(
parent, static_cast<int32_t>(offset), false,
getter_AddRefs(range)); getter_AddRefs(range));
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
@ -690,6 +691,7 @@ nsTextServicesDocument::LastSelectedBlock(TSDBlockSelectionStatus *aSelStatus,
// beginning of its text block, and make it the current // beginning of its text block, and make it the current
// block. // block.
int32_t rangeCount;
rv = selection->GetRangeCount(&rangeCount); rv = selection->GetRangeCount(&rangeCount);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
@ -797,6 +799,7 @@ nsTextServicesDocument::LastSelectedBlock(TSDBlockSelectionStatus *aSelStatus,
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
uint32_t offset;
rv = range->GetEndOffset(&offset); rv = range->GetEndOffset(&offset);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
@ -804,8 +807,8 @@ nsTextServicesDocument::LastSelectedBlock(TSDBlockSelectionStatus *aSelStatus,
return rv; return rv;
} }
rv = CreateDocumentContentRootToNodeOffsetRange(parent, offset, false, rv = CreateDocumentContentRootToNodeOffsetRange(
getter_AddRefs(range)); parent, static_cast<int32_t>(offset), false, getter_AddRefs(range));
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
UNLOCK_DOC(this); UNLOCK_DOC(this);
@ -2377,14 +2380,16 @@ nsTextServicesDocument::GetCollapsedSelection(nsITextServicesDocument::TSDBlockS
nsCOMPtr<nsINode> parent = do_QueryInterface(domParent); nsCOMPtr<nsINode> parent = do_QueryInterface(domParent);
MOZ_ASSERT(parent); MOZ_ASSERT(parent);
int32_t offset; uint32_t offset;
rv = range->GetStartOffset(&offset); rv = range->GetStartOffset(&offset);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
int32_t e1s1 = nsContentUtils::ComparePoints(eStart->mNode, eStartOffset, int32_t e1s1 = nsContentUtils::ComparePoints(eStart->mNode, eStartOffset,
domParent, offset); domParent,
static_cast<int32_t>(offset));
int32_t e2s1 = nsContentUtils::ComparePoints(eEnd->mNode, eEndOffset, int32_t e2s1 = nsContentUtils::ComparePoints(eEnd->mNode, eEndOffset,
domParent, offset); domParent,
static_cast<int32_t>(offset));
if (e1s1 > 0 || e2s1 < 0) { if (e1s1 > 0 || e2s1 < 0) {
// We're done if the caret is outside the current text block. // We're done if the caret is outside the current text block.
@ -2401,8 +2406,8 @@ nsTextServicesDocument::GetCollapsedSelection(nsITextServicesDocument::TSDBlockS
NS_ENSURE_TRUE(entry, NS_ERROR_FAILURE); NS_ENSURE_TRUE(entry, NS_ERROR_FAILURE);
if (entry->mNode == domParent.get() && if (entry->mNode == domParent.get() &&
entry->mNodeOffset <= offset && entry->mNodeOffset <= static_cast<int32_t>(offset) &&
offset <= entry->mNodeOffset + entry->mLength) { static_cast<int32_t>(offset) <= entry->mNodeOffset + entry->mLength) {
*aSelStatus = nsITextServicesDocument::eBlockContains; *aSelStatus = nsITextServicesDocument::eBlockContains;
*aSelOffset = entry->mStrOffset + (offset - entry->mNodeOffset); *aSelOffset = entry->mStrOffset + (offset - entry->mNodeOffset);
*aSelLength = 0; *aSelLength = 0;
@ -2440,7 +2445,7 @@ nsTextServicesDocument::GetCollapsedSelection(nsITextServicesDocument::TSDBlockS
// If the parent has children, position the iterator // If the parent has children, position the iterator
// on the child that is to the left of the offset. // on the child that is to the left of the offset.
uint32_t childIndex = (uint32_t)offset; uint32_t childIndex = offset;
if (childIndex > 0) { if (childIndex > 0) {
uint32_t numChildren = parent->GetChildCount(); uint32_t numChildren = parent->GetChildCount();
@ -2526,8 +2531,8 @@ nsTextServicesDocument::GetCollapsedSelection(nsITextServicesDocument::TSDBlockS
NS_ENSURE_TRUE(entry, NS_ERROR_FAILURE); NS_ENSURE_TRUE(entry, NS_ERROR_FAILURE);
if (entry->mNode == node->AsDOMNode() && if (entry->mNode == node->AsDOMNode() &&
entry->mNodeOffset <= offset && entry->mNodeOffset <= static_cast<int32_t>(offset) &&
offset <= entry->mNodeOffset + entry->mLength) { static_cast<int32_t>(offset) <= entry->mNodeOffset + entry->mLength) {
*aSelStatus = nsITextServicesDocument::eBlockContains; *aSelStatus = nsITextServicesDocument::eBlockContains;
*aSelOffset = entry->mStrOffset + (offset - entry->mNodeOffset); *aSelOffset = entry->mStrOffset + (offset - entry->mNodeOffset);
*aSelLength = 0; *aSelLength = 0;
@ -2817,9 +2822,12 @@ nsTextServicesDocument::GetRangeEndPoints(nsRange* aRange,
NS_ENSURE_TRUE(aStartParent, NS_ERROR_FAILURE); NS_ENSURE_TRUE(aStartParent, NS_ERROR_FAILURE);
rv = aRange->GetStartOffset(aStartOffset); uint32_t offset;
rv = aRange->GetStartOffset(&offset);
NS_ENSURE_SUCCESS(rv, rv); if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
*aStartOffset = static_cast<int32_t>(offset);
rv = aRange->GetEndContainer(aEndParent); rv = aRange->GetEndContainer(aEndParent);
@ -2827,7 +2835,12 @@ nsTextServicesDocument::GetRangeEndPoints(nsRange* aRange,
NS_ENSURE_TRUE(aEndParent, NS_ERROR_FAILURE); NS_ENSURE_TRUE(aEndParent, NS_ERROR_FAILURE);
return aRange->GetEndOffset(aEndOffset); rv = aRange->GetEndOffset(&offset);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
*aEndOffset = static_cast<int32_t>(offset);
return NS_OK;
} }
nsresult nsresult

View file

@ -609,7 +609,7 @@ nsFind::NextNode(nsIDOMRange* aSearchRange,
// beginning/end of the search range. // beginning/end of the search range.
nsCOMPtr<nsIDOMNode> startNode; nsCOMPtr<nsIDOMNode> startNode;
nsCOMPtr<nsIDOMNode> endNode; nsCOMPtr<nsIDOMNode> endNode;
int32_t startOffset, endOffset; uint32_t startOffset, endOffset;
if (aContinueOk) { if (aContinueOk) {
#ifdef DEBUG_FIND #ifdef DEBUG_FIND
printf("Match in progress: continuing past endpoint\n"); printf("Match in progress: continuing past endpoint\n");
@ -645,7 +645,8 @@ nsFind::NextNode(nsIDOMRange* aSearchRange,
} }
} }
rv = InitIterator(startNode, startOffset, endNode, endOffset); rv = InitIterator(startNode, static_cast<int32_t>(startOffset),
endNode, static_cast<int32_t>(endOffset));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (!aStartPoint) { if (!aStartPoint) {
aStartPoint = aSearchRange; aStartPoint = aSearchRange;
@ -665,14 +666,18 @@ nsFind::NextNode(nsIDOMRange* aSearchRange,
if (mFindBackward) { if (mFindBackward) {
aStartPoint->GetEndContainer(getter_AddRefs(node)); aStartPoint->GetEndContainer(getter_AddRefs(node));
if (mIterNode.get() == node.get()) { if (mIterNode.get() == node.get()) {
aStartPoint->GetEndOffset(&mIterOffset); uint32_t endOffset;
aStartPoint->GetEndOffset(&endOffset);
mIterOffset = static_cast<int32_t>(endOffset);
} else { } else {
mIterOffset = -1; // sign to start from end mIterOffset = -1; // sign to start from end
} }
} else { } else {
aStartPoint->GetStartContainer(getter_AddRefs(node)); aStartPoint->GetStartContainer(getter_AddRefs(node));
if (mIterNode.get() == node.get()) { if (mIterNode.get() == node.get()) {
aStartPoint->GetStartOffset(&mIterOffset); uint32_t startOffset;
aStartPoint->GetStartOffset(&startOffset);
mIterOffset = static_cast<int32_t>(startOffset);
} else { } else {
mIterOffset = 0; mIterOffset = 0;
} }
@ -997,7 +1002,7 @@ nsFind::Find(const nsAString& aPatText, nsIDOMRange* aSearchRange,
// Get the end point, so we know when to end searches: // Get the end point, so we know when to end searches:
nsCOMPtr<nsIDOMNode> endNode; nsCOMPtr<nsIDOMNode> endNode;
int32_t endOffset; uint32_t endOffset;
aEndPoint->GetEndContainer(getter_AddRefs(endNode)); aEndPoint->GetEndContainer(getter_AddRefs(endNode));
aEndPoint->GetEndOffset(&endOffset); aEndPoint->GetEndOffset(&endOffset);
@ -1132,8 +1137,8 @@ nsFind::Find(const nsAString& aPatText, nsIDOMRange* aSearchRange,
// Have we gone past the endpoint yet? If we have, and we're not in the // Have we gone past the endpoint yet? If we have, and we're not in the
// middle of a match, return. // middle of a match, return.
if (mIterNode == endNode && if (mIterNode == endNode &&
((mFindBackward && findex < endOffset) || ((mFindBackward && findex < static_cast<int32_t>(endOffset)) ||
(!mFindBackward && findex > endOffset))) { (!mFindBackward && findex > static_cast<int32_t>(endOffset)))) {
ResetAll(); ResetAll();
return NS_OK; return NS_OK;
} }

View file

@ -518,7 +518,7 @@ nsWebBrowserFind::GetSearchLimits(nsIDOMRange* aSearchRange,
nsCOMPtr<nsIDOMRange> range; nsCOMPtr<nsIDOMRange> range;
nsCOMPtr<nsIDOMNode> node; nsCOMPtr<nsIDOMNode> node;
int32_t offset; uint32_t offset;
// Forward, not wrapping: SelEnd to DocEnd // Forward, not wrapping: SelEnd to DocEnd
if (!mFindBackwards && !aWrap) { if (!mFindBackwards && !aWrap) {

View file

@ -356,19 +356,18 @@ mozInlineSpellStatus::FinishNavigationEvent(mozInlineSpellWordUtil& aWordUtil)
NS_ASSERTION(mAnchorRange, "No anchor for navigation!"); NS_ASSERTION(mAnchorRange, "No anchor for navigation!");
nsCOMPtr<nsIDOMNode> newAnchorNode, oldAnchorNode; nsCOMPtr<nsIDOMNode> newAnchorNode, oldAnchorNode;
int32_t newAnchorOffset, oldAnchorOffset;
// get the DOM position of the old caret, the range should be collapsed // get the DOM position of the old caret, the range should be collapsed
nsresult rv = mOldNavigationAnchorRange->GetStartContainer( nsresult rv = mOldNavigationAnchorRange->GetStartContainer(
getter_AddRefs(oldAnchorNode)); getter_AddRefs(oldAnchorNode));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = mOldNavigationAnchorRange->GetStartOffset(&oldAnchorOffset); uint32_t oldAnchorOffset = mOldNavigationAnchorRange->StartOffset();
NS_ENSURE_SUCCESS(rv, rv);
// find the word on the old caret position, this is the one that we MAY need // find the word on the old caret position, this is the one that we MAY need
// to check // to check
RefPtr<nsRange> oldWord; RefPtr<nsRange> oldWord;
rv = aWordUtil.GetRangeForWord(oldAnchorNode, oldAnchorOffset, rv = aWordUtil.GetRangeForWord(oldAnchorNode,
static_cast<int32_t>(oldAnchorOffset),
getter_AddRefs(oldWord)); getter_AddRefs(oldWord));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -380,14 +379,15 @@ mozInlineSpellStatus::FinishNavigationEvent(mozInlineSpellWordUtil& aWordUtil)
// get the DOM position of the new caret, the range should be collapsed // get the DOM position of the new caret, the range should be collapsed
rv = mAnchorRange->GetStartContainer(getter_AddRefs(newAnchorNode)); rv = mAnchorRange->GetStartContainer(getter_AddRefs(newAnchorNode));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = mAnchorRange->GetStartOffset(&newAnchorOffset); uint32_t newAnchorOffset = mAnchorRange->StartOffset();
NS_ENSURE_SUCCESS(rv, rv);
// see if the new cursor position is in the word of the old cursor position // see if the new cursor position is in the word of the old cursor position
bool isInRange = false; bool isInRange = false;
if (! mForceNavigationWordCheck) { if (! mForceNavigationWordCheck) {
rv = oldWord->IsPointInRange(newAnchorNode, rv = oldWord->IsPointInRange(
newAnchorOffset + mNewNavigationPositionOffset, newAnchorNode,
static_cast<int32_t>(
newAnchorOffset + mNewNavigationPositionOffset),
&isInRange); &isInRange);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }
@ -421,11 +421,9 @@ mozInlineSpellStatus::FillNoCheckRangeFromAnchor(
nsresult rv = mAnchorRange->GetStartContainer(getter_AddRefs(anchorNode)); nsresult rv = mAnchorRange->GetStartContainer(getter_AddRefs(anchorNode));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
int32_t anchorOffset; uint32_t anchorOffset = mAnchorRange->StartOffset();
rv = mAnchorRange->GetStartOffset(&anchorOffset); return aWordUtil.GetRangeForWord(anchorNode,
NS_ENSURE_SUCCESS(rv, rv); static_cast<int32_t>(anchorOffset),
return aWordUtil.GetRangeForWord(anchorNode, anchorOffset,
getter_AddRefs(mNoCheckRange)); getter_AddRefs(mNoCheckRange));
} }
@ -1214,7 +1212,7 @@ mozInlineSpellChecker::MakeSpellCheckRange(
return rv; return rv;
} }
} else { } else {
int32_t endOffset = -1; uint32_t endOffset;
endNode = nsRange::GetParentAndOffsetAfter(endNode, &endOffset); endNode = nsRange::GetParentAndOffsetAfter(endNode, &endOffset);
rv = range->SetStartAndEnd(startNode, aStartOffset, endNode, endOffset); rv = range->SetStartAndEnd(startNode, aStartOffset, endNode, endOffset);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {

View file

@ -4747,9 +4747,11 @@ PresShell::ClipListToRange(nsDisplayListBuilder *aBuilder,
frame->GetOffsets(frameStartOffset, frameEndOffset); frame->GetOffsets(frameStartOffset, frameEndOffset);
int32_t hilightStart = int32_t hilightStart =
atStart ? std::max(aRange->StartOffset(), frameStartOffset) : frameStartOffset; atStart ? std::max(static_cast<int32_t>(aRange->StartOffset()),
frameStartOffset) : frameStartOffset;
int32_t hilightEnd = int32_t hilightEnd =
atEnd ? std::min(aRange->EndOffset(), frameEndOffset) : frameEndOffset; atEnd ? std::min(static_cast<int32_t>(aRange->EndOffset()),
frameEndOffset) : frameEndOffset;
if (hilightStart < hilightEnd) { if (hilightStart < hilightEnd) {
// determine the location of the start and end edges of the range. // determine the location of the start and end edges of the range.
nsPoint startPoint, endPoint; nsPoint startPoint, endPoint;

View file

@ -1836,7 +1836,7 @@ nsImageFrame::ShouldDisplaySelection()
int32_t thisOffset = parentContent->IndexOf(mContent); int32_t thisOffset = parentContent->IndexOf(mContent);
nsCOMPtr<nsIDOMNode> parentNode = do_QueryInterface(parentContent); nsCOMPtr<nsIDOMNode> parentNode = do_QueryInterface(parentContent);
nsCOMPtr<nsIDOMNode> rangeNode; nsCOMPtr<nsIDOMNode> rangeNode;
int32_t rangeOffset; uint32_t rangeOffset;
nsCOMPtr<nsIDOMRange> range; nsCOMPtr<nsIDOMRange> range;
selection->GetRangeAt(0,getter_AddRefs(range)); selection->GetRangeAt(0,getter_AddRefs(range));
if (range) if (range)
@ -1844,12 +1844,16 @@ nsImageFrame::ShouldDisplaySelection()
range->GetStartContainer(getter_AddRefs(rangeNode)); range->GetStartContainer(getter_AddRefs(rangeNode));
range->GetStartOffset(&rangeOffset); range->GetStartOffset(&rangeOffset);
if (parentNode && rangeNode && (rangeNode == parentNode) && rangeOffset == thisOffset) if (parentNode && rangeNode && rangeNode == parentNode &&
{ static_cast<int32_t>(rangeOffset) == thisOffset) {
range->GetEndContainer(getter_AddRefs(rangeNode)); range->GetEndContainer(getter_AddRefs(rangeNode));
range->GetEndOffset(&rangeOffset); range->GetEndOffset(&rangeOffset);
if ((rangeNode == parentNode) && (rangeOffset == (thisOffset +1))) //+1 since that would mean this whole content is selected only // +1 since that would mean this whole content is selected only
return false; //do not allow nsFrame do draw any further selection if (rangeNode == parentNode &&
static_cast<int32_t>(rangeOffset) == thisOffset + 1) {
// Do not allow nsFrame do draw any further selection
return false;
}
} }
} }
} }

View file

@ -4119,13 +4119,15 @@ Selection::GetType(int16_t* aType)
static inline bool static inline bool
RangeMatchesBeginPoint(nsRange* aRange, nsINode* aNode, int32_t aOffset) RangeMatchesBeginPoint(nsRange* aRange, nsINode* aNode, int32_t aOffset)
{ {
return aRange->GetStartParent() == aNode && aRange->StartOffset() == aOffset; return aRange->GetStartParent() == aNode &&
static_cast<int32_t>(aRange->StartOffset()) == aOffset;
} }
static inline bool static inline bool
RangeMatchesEndPoint(nsRange* aRange, nsINode* aNode, int32_t aOffset) RangeMatchesEndPoint(nsRange* aRange, nsINode* aNode, int32_t aOffset)
{ {
return aRange->GetEndParent() == aNode && aRange->EndOffset() == aOffset; return aRange->GetEndParent() == aNode &&
static_cast<int32_t>(aRange->EndOffset()) == aOffset;
} }
// Selection::EqualsRangeAtPoint // Selection::EqualsRangeAtPoint

View file

@ -822,7 +822,7 @@ nsTypeAheadFind::GetSearchContainers(nsISupports *aContainer,
getter_AddRefs(mStartPointRange), nullptr); getter_AddRefs(mStartPointRange), nullptr);
} }
else { else {
int32_t startOffset; uint32_t startOffset;
nsCOMPtr<nsIDOMNode> startNode; nsCOMPtr<nsIDOMNode> startNode;
if (aFindPrev) { if (aFindPrev) {
currentSelectionRange->GetStartContainer(getter_AddRefs(startNode)); currentSelectionRange->GetStartContainer(getter_AddRefs(startNode));
@ -860,7 +860,7 @@ nsTypeAheadFind::RangeStartsInsideLink(nsIDOMRange *aRange,
nsCOMPtr<nsIDOMNode> startNode; nsCOMPtr<nsIDOMNode> startNode;
nsCOMPtr<nsIContent> startContent, origContent; nsCOMPtr<nsIContent> startContent, origContent;
aRange->GetStartContainer(getter_AddRefs(startNode)); aRange->GetStartContainer(getter_AddRefs(startNode));
int32_t startOffset; uint32_t startOffset;
aRange->GetStartOffset(&startOffset); aRange->GetStartOffset(&startOffset);
startContent = do_QueryInterface(startNode); startContent = do_QueryInterface(startNode);
@ -880,9 +880,10 @@ nsTypeAheadFind::RangeStartsInsideLink(nsIDOMRange *aRange,
const nsTextFragment *textFrag = startContent->GetText(); const nsTextFragment *textFrag = startContent->GetText();
if (textFrag) { if (textFrag) {
// look for non whitespace character before start offset // look for non whitespace character before start offset
for (int32_t index = 0; index < startOffset; index++) { for (uint32_t index = 0; index < startOffset; index++) {
// FIXME: take content language into account when deciding whitespace. // FIXME: take content language into account when deciding whitespace.
if (!mozilla::dom::IsSpaceCharacter(textFrag->CharAt(index))) { if (!mozilla::dom::IsSpaceCharacter(
textFrag->CharAt(static_cast<int32_t>(index)))) {
*aIsStartingLink = false; // not at start of a node *aIsStartingLink = false; // not at start of a node
break; break;
@ -1227,12 +1228,14 @@ nsTypeAheadFind::IsRangeVisible(nsIPresShell *aPresShell,
return true; // Don't need it to be on screen, just in rendering tree return true; // Don't need it to be on screen, just in rendering tree
// Get the next in flow frame that contains the range start // Get the next in flow frame that contains the range start
int32_t startRangeOffset, startFrameOffset, endFrameOffset; int32_t startFrameOffset, endFrameOffset;
uint32_t startRangeOffset;
aRange->GetStartOffset(&startRangeOffset); aRange->GetStartOffset(&startRangeOffset);
while (true) { while (true) {
frame->GetOffsets(startFrameOffset, endFrameOffset); frame->GetOffsets(startFrameOffset, endFrameOffset);
if (startRangeOffset < endFrameOffset) if (static_cast<int32_t>(startRangeOffset) < endFrameOffset) {
break; break;
}
nsIFrame *nextContinuationFrame = frame->GetNextContinuation(); nsIFrame *nextContinuationFrame = frame->GetNextContinuation();
if (nextContinuationFrame) if (nextContinuationFrame)