--- a/dom/base/Selection.cpp
+++ b/dom/base/Selection.cpp
@@ -1397,23 +1397,24 @@ Selection::GetType(int16_t* aType)
//
// Compares the range beginning or ending point, and returns true if it
// exactly matches the given DOM point.
static inline bool
RangeMatchesBeginPoint(nsRange* aRange, nsINode* aNode, int32_t aOffset)
{
return aRange->GetStartContainer() == aNode &&
- aRange->StartOffset() == aOffset;
+ static_cast<int32_t>(aRange->StartOffset()) == aOffset;
}
static inline bool
RangeMatchesEndPoint(nsRange* aRange, nsINode* aNode, int32_t aOffset)
{
- return aRange->GetEndContainer() == aNode && aRange->EndOffset() == aOffset;
+ return aRange->GetEndContainer() == aNode &&
+ static_cast<int32_t>(aRange->EndOffset()) == aOffset;
}
// Selection::EqualsRangeAtPoint
//
// Utility method for checking equivalence of two ranges.
bool
Selection::EqualsRangeAtPoint(
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -2769,16 +2769,19 @@ nsContentUtils::PositionIsBefore(nsINode
/* static */
int32_t
nsContentUtils::ComparePoints(nsINode* aParent1, int32_t aOffset1,
nsINode* aParent2, int32_t aOffset2,
bool* aDisconnected)
{
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 :
aOffset1 > aOffset2 ? 1 :
0;
}
AutoTArray<nsINode*, 32> parents1, parents2;
nsINode* node1 = aParent1;
nsINode* node2 = aParent2;
@@ -2819,20 +2822,24 @@ nsContentUtils::ComparePoints(nsINode* a
// The parent chains never differed, so one of the nodes is an ancestor of
// the other
NS_ASSERTION(!pos1 || !pos2,
"should have run out of parent chain for one of the nodes");
if (!pos1) {
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;
}
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;
}
/* static */
int32_t
nsContentUtils::ComparePoints(nsIDOMNode* aParent1, int32_t aOffset1,
nsIDOMNode* aParent2, int32_t aOffset2,
bool* aDisconnected)
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -399,16 +399,23 @@ public:
/**
* Utility routine to compare two "points", where a point is a
* node/offset pair
* Returns -1 if point1 < point2, 1, if point1 > point2,
* 0 if error or if point1 == point2.
* NOTE! If the two nodes aren't in the same connected subtree,
* the result is 1, and the optional aDisconnected parameter
* 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,
nsINode* aParent2, int32_t aOffset2,
bool* aDisconnected = nullptr);
static int32_t ComparePoints(nsIDOMNode* aParent1, int32_t aOffset1,
nsIDOMNode* aParent2, int32_t aOffset2,
bool* aDisconnected = nullptr);
--- a/dom/base/nsDocumentEncoder.cpp
+++ b/dom/base/nsDocumentEncoder.cpp
@@ -1564,20 +1564,23 @@ nsHTMLCopyEncoder::IncludeInContext(nsIN
nsGkAtoms::h5,
nsGkAtoms::h6);
}
nsresult
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;
nsCOMPtr<nsIDOMNode> startNode, endNode, common;
- int32_t startOffset, endOffset;
+ uint32_t startOffset, endOffset;
rv = inRange->GetCommonAncestorContainer(getter_AddRefs(common));
NS_ENSURE_SUCCESS(rv, rv);
rv = inRange->GetStartContainer(getter_AddRefs(startNode));
NS_ENSURE_SUCCESS(rv, rv);
rv = inRange->GetStartOffset(&startOffset);
NS_ENSURE_SUCCESS(rv, rv);
rv = inRange->GetEndContainer(getter_AddRefs(endNode));
@@ -1585,33 +1588,35 @@ nsHTMLCopyEncoder::PromoteRange(nsIDOMRa
rv = inRange->GetEndOffset(&endOffset);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNode> opStartNode;
nsCOMPtr<nsIDOMNode> opEndNode;
int32_t opStartOffset, opEndOffset;
// 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);
- 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);
// if both range endpoints are at the common ancestor, check for possible inclusion of ancestors
if ( (opStartNode == common) && (opEndNode == common) )
{
rv = PromoteAncestorChain(address_of(opStartNode), &opStartOffset, &opEndOffset);
NS_ENSURE_SUCCESS(rv, rv);
opEndNode = opStartNode;
}
// 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);
- rv = inRange->SetEnd(opEndNode, opEndOffset);
+ rv = inRange->SetEnd(opEndNode, static_cast<uint32_t>(opEndOffset));
return rv;
}
// PromoteAncestorChain will promote a range represented by [{*ioNode,*ioStartOffset} , {*ioNode,*ioEndOffset}]
// The promotion is different from that found in getPromotedPoint: it will only promote one endpoint if it can
// promote the other. Thus, instead of having a startnode/endNode, there is just the one ioNode.
nsresult
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -2507,42 +2507,40 @@ nsFocusManager::GetSelectionLocation(nsI
nsCOMPtr<nsISelection> domSelection;
if (frameSelection) {
domSelection = frameSelection->GetSelection(SelectionType::eNormal);
}
nsCOMPtr<nsIDOMNode> startNode, endNode;
bool isCollapsed = false;
nsCOMPtr<nsIContent> startContent, endContent;
- int32_t startOffset = 0;
+ uint32_t startOffset = 0;
if (domSelection) {
domSelection->GetIsCollapsed(&isCollapsed);
nsCOMPtr<nsIDOMRange> domRange;
rv = domSelection->GetRangeAt(0, getter_AddRefs(domRange));
if (domRange) {
domRange->GetStartContainer(getter_AddRefs(startNode));
domRange->GetEndContainer(getter_AddRefs(endNode));
domRange->GetStartOffset(&startOffset);
nsIContent *childContent = nullptr;
startContent = do_QueryInterface(startNode);
if (startContent && startContent->IsElement()) {
- NS_ASSERTION(startOffset >= 0, "Start offset cannot be negative");
childContent = startContent->GetChildAt(startOffset);
if (childContent) {
startContent = childContent;
}
}
endContent = do_QueryInterface(endNode);
if (endContent && endContent->IsElement()) {
- int32_t endOffset = 0;
+ uint32_t endOffset = 0;
domRange->GetEndOffset(&endOffset);
- NS_ASSERTION(endOffset >= 0, "End offset cannot be negative");
childContent = endContent->GetChildAt(endOffset);
if (childContent) {
endContent = childContent;
}
}
}
}
else {
@@ -2560,17 +2558,17 @@ nsFocusManager::GetSelectionLocation(nsI
if (startContent->NodeType() == nsIDOMNode::TEXT_NODE) {
nsAutoString nodeValue;
startContent->AppendTextTo(nodeValue);
bool isFormControl =
startContent->IsNodeOfType(nsINode::eHTML_FORM_CONTROL);
- if (nodeValue.Length() == (uint32_t)startOffset && !isFormControl &&
+ if (nodeValue.Length() == startOffset && !isFormControl &&
startContent != aDocument->GetRootElement()) {
// Yes, indeed we were at the end of the last node
nsCOMPtr<nsIFrameEnumerator> frameTraversal;
nsresult rv = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
presContext, startFrame,
eLeaf,
false, // aVisual
false, // aLockInScrollView
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -106,41 +106,47 @@ nsRange::CompareNodeToRange(nsINode* aNo
int32_t nodeStart, nodeEnd;
nsINode* parent = aNode->GetParentNode();
if (!parent) {
// can't make a parent/offset pair to represent start or
// end of the root node, because it has no parent.
// so instead represent it by (node,0) and (node,numChildren)
parent = aNode;
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 {
nodeStart = parent->IndexOf(aNode);
nodeEnd = nodeStart + 1;
+ MOZ_ASSERT(nodeStart < nodeEnd, "nodeStart shouldn't be INT32_MAX");
}
nsINode* rangeStartContainer = aRange->GetStartContainer();
nsINode* rangeEndContainer = aRange->GetEndContainer();
- int32_t rangeStartOffset = aRange->StartOffset();
- int32_t rangeEndOffset = aRange->EndOffset();
+ uint32_t rangeStartOffset = aRange->StartOffset();
+ uint32_t rangeEndOffset = aRange->EndOffset();
// is RANGE(start) <= NODE(start) ?
bool disconnected = false;
- *outNodeBefore = nsContentUtils::ComparePoints(rangeStartContainer,
- rangeStartOffset,
- parent, nodeStart,
- &disconnected) > 0;
+ *outNodeBefore =
+ nsContentUtils::ComparePoints(rangeStartContainer,
+ static_cast<int32_t>(rangeStartOffset),
+ parent, nodeStart,
+ &disconnected) > 0;
NS_ENSURE_TRUE(!disconnected, NS_ERROR_DOM_WRONG_DOCUMENT_ERR);
// is RANGE(end) >= NODE(end) ?
- *outNodeAfter = nsContentUtils::ComparePoints(rangeEndContainer,
- rangeEndOffset,
- parent, nodeEnd,
- &disconnected) < 0;
+ *outNodeAfter =
+ nsContentUtils::ComparePoints(rangeEndContainer,
+ static_cast<int32_t>(rangeEndOffset),
+ parent, nodeEnd,
+ &disconnected) < 0;
NS_ENSURE_TRUE(!disconnected, NS_ERROR_DOM_WRONG_DOCUMENT_ERR);
return NS_OK;
}
static nsINode*
GetNextRangeCommonAncestor(nsINode* aNode)
{
while (aNode && !aNode->IsCommonAncestorForRangeInSelection()) {
@@ -159,23 +165,27 @@ GetNextRangeCommonAncestor(nsINode* aNod
struct IsItemInRangeComparator
{
nsINode* mNode;
uint32_t mStartOffset;
uint32_t mEndOffset;
int operator()(const nsRange* const aRange) const
{
- int32_t cmp = nsContentUtils::ComparePoints(mNode, mEndOffset,
- aRange->GetStartContainer(),
- aRange->StartOffset());
+ int32_t cmp =
+ nsContentUtils::ComparePoints(
+ mNode, static_cast<int32_t>(mEndOffset),
+ aRange->GetStartContainer(),
+ static_cast<int32_t>(aRange->StartOffset()));
if (cmp == 1) {
- cmp = nsContentUtils::ComparePoints(mNode, mStartOffset,
- aRange->GetEndContainer(),
- aRange->EndOffset());
+ cmp =
+ nsContentUtils::ComparePoints(
+ mNode, static_cast<int32_t>(mStartOffset),
+ aRange->GetEndContainer(),
+ static_cast<int32_t>(aRange->EndOffset()));
if (cmp == -1) {
return 0;
}
return 1;
}
return -1;
}
};
@@ -261,18 +271,18 @@ nsRange::nsRange(nsINode* aNode)
#endif
{
MOZ_ASSERT(aNode, "range isn't in a document!");
mOwner = aNode->OwnerDoc();
}
/* static */
nsresult
-nsRange::CreateRange(nsINode* aStartContainer, int32_t aStartOffset,
- nsINode* aEndParent, int32_t aEndOffset,
+nsRange::CreateRange(nsINode* aStartContainer, uint32_t aStartOffset,
+ nsINode* aEndParent, uint32_t aEndOffset,
nsRange** aRange)
{
MOZ_ASSERT(aRange);
*aRange = nullptr;
RefPtr<nsRange> range = new nsRange(aStartContainer);
nsresult rv = range->SetStartAndEnd(aStartContainer, aStartOffset,
aEndParent, aEndOffset);
@@ -280,30 +290,30 @@ nsRange::CreateRange(nsINode* aStartCont
return rv;
}
range.forget(aRange);
return NS_OK;
}
/* static */
nsresult
-nsRange::CreateRange(nsIDOMNode* aStartContainer, int32_t aStartOffset,
- nsIDOMNode* aEndParent, int32_t aEndOffset,
+nsRange::CreateRange(nsIDOMNode* aStartContainer, uint32_t aStartOffset,
+ nsIDOMNode* aEndParent, uint32_t aEndOffset,
nsRange** aRange)
{
nsCOMPtr<nsINode> startContainer = do_QueryInterface(aStartContainer);
nsCOMPtr<nsINode> endContainer = do_QueryInterface(aEndParent);
return CreateRange(startContainer, aStartOffset,
endContainer, aEndOffset, aRange);
}
/* static */
nsresult
-nsRange::CreateRange(nsIDOMNode* aStartContainer, int32_t aStartOffset,
- nsIDOMNode* aEndParent, int32_t aEndOffset,
+nsRange::CreateRange(nsIDOMNode* aStartContainer, uint32_t aStartOffset,
+ nsIDOMNode* aEndParent, uint32_t aEndOffset,
nsIDOMRange** aRange)
{
RefPtr<nsRange> range;
nsresult rv = nsRange::CreateRange(aStartContainer, aStartOffset, aEndParent,
aEndOffset, getter_AddRefs(range));
range.forget(aRange);
return rv;
}
@@ -451,49 +461,58 @@ nsRange::CharacterDataChanged(nsIDocumen
// If the splitted text node is immediately before a range boundary point
// that refers to a child index (i.e. its parent is the boundary container)
// then we need to increment the corresponding offset to account for the new
// text node that will be inserted. If so, we need to prevent the next
// ContentInserted or ContentAppended for this range from incrementing it
// again (when the new text node is notified).
nsINode* parentNode = aContent->GetParentNode();
int32_t index = -1;
- if (parentNode == mEndContainer && mEndOffset > 0 &&
- (index = parentNode->IndexOf(aContent)) + 1 == mEndOffset) {
- newEndNode = mEndContainer;
- newEndOffset = mEndOffset + 1;
- mEndOffsetWasIncremented = true;
+ if (parentNode == mEndContainer && mEndOffset > 0) {
+ index = parentNode->IndexOf(aContent);
+ NS_WARNING_ASSERTION(index >= 0,
+ "Shouldn't be called during removing the node or something");
+ if (static_cast<uint32_t>(index + 1) == mEndOffset) {
+ newEndNode = mEndContainer;
+ newEndOffset = mEndOffset + 1;
+ MOZ_ASSERT(IsValidOffset(newEndOffset));
+ mEndOffsetWasIncremented = true;
+ }
}
- if (parentNode == mStartContainer && mStartOffset > 0 &&
- (index != -1 ? index : parentNode->IndexOf(aContent)) + 1 == mStartOffset) {
- newStartNode = mStartContainer;
- newStartOffset = mStartOffset + 1;
- mStartOffsetWasIncremented = true;
+ if (parentNode == mStartContainer && mStartOffset > 0) {
+ if (index <= 0) {
+ index = parentNode->IndexOf(aContent);
+ }
+ if (static_cast<uint32_t>(index + 1) == mStartOffset) {
+ newStartNode = mStartContainer;
+ newStartOffset = mStartOffset + 1;
+ MOZ_ASSERT(IsValidOffset(newStartOffset));
+ mStartOffsetWasIncremented = true;
+ }
}
#ifdef DEBUG
if (mStartOffsetWasIncremented || mEndOffsetWasIncremented) {
mAssertNextInsertOrAppendIndex =
(mStartOffsetWasIncremented ? newStartOffset : newEndOffset) - 1;
mAssertNextInsertOrAppendNode = aInfo->mDetails->mNextSibling;
}
#endif
}
// If the changed node contains our start boundary and the change starts
// before the boundary we'll need to adjust the offset.
- if (aContent == mStartContainer &&
- aInfo->mChangeStart < static_cast<uint32_t>(mStartOffset)) {
+ if (aContent == mStartContainer && aInfo->mChangeStart < mStartOffset) {
if (aInfo->mDetails) {
// splitText(), aInfo->mDetails->mNextSibling is the new text node
NS_ASSERTION(aInfo->mDetails->mType ==
CharacterDataChangeInfo::Details::eSplit,
"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");
- newStartOffset = static_cast<uint32_t>(mStartOffset) - aInfo->mChangeStart;
+ newStartOffset = mStartOffset - aInfo->mChangeStart;
newStartNode = aInfo->mDetails->mNextSibling;
if (MOZ_UNLIKELY(aContent == mRoot)) {
newRoot = IsValidBoundary(newStartNode);
}
bool isCommonAncestor =
IsInSelection() && mStartContainer == mEndContainer;
if (isCommonAncestor) {
@@ -502,92 +521,91 @@ nsRange::CharacterDataChanged(nsIDocumen
}
if (mStartContainer->IsDescendantOfCommonAncestorForRangeInSelection()) {
newStartNode->SetDescendantOfCommonAncestorForRangeInSelection();
}
} else {
// If boundary is inside changed text, position it before change
// else adjust start offset for the change in length.
newStartNode = mStartContainer;
- newStartOffset = static_cast<uint32_t>(mStartOffset) <= aInfo->mChangeEnd ?
+ newStartOffset = mStartOffset <= aInfo->mChangeEnd ?
aInfo->mChangeStart :
mStartOffset + aInfo->mChangeStart - aInfo->mChangeEnd +
aInfo->mReplaceLength;
}
}
// 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
// did so too (otherwise the range would end up with disconnected nodes).
- if (aContent == mEndContainer &&
- aInfo->mChangeStart < static_cast<uint32_t>(mEndOffset)) {
+ if (aContent == mEndContainer && aInfo->mChangeStart < mEndOffset) {
if (aInfo->mDetails && (aContent->GetParentNode() || newStartNode)) {
// splitText(), aInfo->mDetails->mNextSibling is the new text node
NS_ASSERTION(aInfo->mDetails->mType ==
CharacterDataChangeInfo::Details::eSplit,
"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");
- newEndOffset = static_cast<uint32_t>(mEndOffset) - aInfo->mChangeStart;
+ newEndOffset = mEndOffset - aInfo->mChangeStart;
newEndNode = aInfo->mDetails->mNextSibling;
bool isCommonAncestor =
IsInSelection() && mStartContainer == mEndContainer;
if (isCommonAncestor && !newStartNode) {
// The split occurs inside the range.
UnregisterCommonAncestor(mStartContainer);
RegisterCommonAncestor(mStartContainer->GetParentNode());
newEndNode->SetDescendantOfCommonAncestorForRangeInSelection();
} else if (mEndContainer->
IsDescendantOfCommonAncestorForRangeInSelection()) {
newEndNode->SetDescendantOfCommonAncestorForRangeInSelection();
}
} else {
newEndNode = mEndContainer;
- newEndOffset = static_cast<uint32_t>(mEndOffset) <= aInfo->mChangeEnd ?
+ newEndOffset = mEndOffset <= aInfo->mChangeEnd ?
aInfo->mChangeStart :
mEndOffset + aInfo->mChangeStart - aInfo->mChangeEnd +
aInfo->mReplaceLength;
}
}
if (aInfo->mDetails &&
aInfo->mDetails->mType == CharacterDataChangeInfo::Details::eMerge) {
// normalize(), aInfo->mDetails->mNextSibling is the merged text node
// that will be removed
nsIContent* removed = aInfo->mDetails->mNextSibling;
if (removed == mStartContainer) {
- newStartOffset = static_cast<uint32_t>(mStartOffset) + aInfo->mChangeStart;
+ newStartOffset = mStartOffset + aInfo->mChangeStart;
newStartNode = aContent;
if (MOZ_UNLIKELY(removed == mRoot)) {
newRoot = IsValidBoundary(newStartNode);
}
}
if (removed == mEndContainer) {
- newEndOffset = static_cast<uint32_t>(mEndOffset) + aInfo->mChangeStart;
+ newEndOffset = mEndOffset + aInfo->mChangeStart;
newEndNode = aContent;
if (MOZ_UNLIKELY(removed == mRoot)) {
newRoot = IsValidBoundary(newEndNode);
}
}
// When the removed text node's parent is one of our boundary nodes we may
// need to adjust the offset to account for the removed node. However,
// there will also be a ContentRemoved notification later so the only cases
// we need to handle here is when the removed node is the text node after
// the boundary. (The m*Offset > 0 check is an optimization - a boundary
// point before the first child is never affected by normalize().)
nsINode* parentNode = aContent->GetParentNode();
if (parentNode == mStartContainer && mStartOffset > 0 &&
- uint32_t(mStartOffset) < parentNode->GetChildCount() &&
+ mStartOffset < parentNode->GetChildCount() &&
removed == parentNode->GetChildAt(mStartOffset)) {
newStartNode = aContent;
newStartOffset = aInfo->mChangeStart;
}
if (parentNode == mEndContainer && mEndOffset > 0 &&
- uint32_t(mEndOffset) < parentNode->GetChildCount() &&
+ mEndOffset < parentNode->GetChildCount() &&
removed == parentNode->GetChildAt(mEndOffset)) {
newEndNode = aContent;
newEndOffset = aInfo->mChangeEnd;
}
}
if (newStartNode || newEndNode) {
if (!newStartNode) {
@@ -645,24 +663,30 @@ nsRange::ContentInserted(nsIDocument* aD
NS_ASSERTION(mIsPositioned, "shouldn't be notified if not positioned");
bool rangeChanged = false;
uint32_t newStartOffset = mStartOffset;
uint32_t newEndOffset = mEndOffset;
nsINode* container = NODE_FROM(aContainer, aDocument);
// Adjust position if a sibling was inserted.
- if (container == mStartContainer && aIndexInContainer < mStartOffset &&
+ if (container == mStartContainer &&
+ (NS_WARN_IF(aIndexInContainer < 0) ||
+ static_cast<uint32_t>(aIndexInContainer) < mStartOffset) &&
!mStartOffsetWasIncremented) {
++newStartOffset;
+ MOZ_ASSERT(IsValidOffset(newStartOffset));
rangeChanged = true;
}
- if (container == mEndContainer && aIndexInContainer < mEndOffset &&
+ if (container == mEndContainer &&
+ (NS_WARN_IF(aIndexInContainer < 0) ||
+ static_cast<uint32_t>(aIndexInContainer) < mEndOffset) &&
!mEndOffsetWasIncremented) {
++newEndOffset;
+ MOZ_ASSERT(IsValidOffset(newEndOffset));
rangeChanged = true;
}
if (container->IsSelectionDescendant() &&
!aChild->IsDescendantOfCommonAncestorForRangeInSelection()) {
MarkDescendants(aChild);
aChild->SetDescendantOfCommonAncestorForRangeInSelection();
}
@@ -700,29 +724,29 @@ nsRange::ContentRemoved(nsIDocument* aDo
bool gravitateEnd = false;
bool didCheckStartParentDescendant = false;
bool rangeChanged = false;
uint32_t newStartOffset = mStartOffset;
uint32_t newEndOffset = mEndOffset;
// Adjust position if a sibling was removed...
if (container == mStartContainer) {
- if (aIndexInContainer < mStartOffset) {
+ if (aIndexInContainer < static_cast<int32_t>(mStartOffset)) {
--newStartOffset;
rangeChanged = true;
}
} else { // ...or gravitate if an ancestor was removed.
didCheckStartParentDescendant = true;
gravitateStart =
nsContentUtils::ContentIsDescendantOf(mStartContainer, aChild);
}
// Do same thing for end boundry.
if (container == mEndContainer) {
- if (aIndexInContainer < mEndOffset) {
+ if (aIndexInContainer < static_cast<int32_t>(mEndOffset)) {
--newEndOffset;
rangeChanged = true;
}
} else if (didCheckStartParentDescendant &&
mStartContainer == mEndContainer) {
gravitateEnd = gravitateStart;
} else {
gravitateEnd = nsContentUtils::ContentIsDescendantOf(mEndContainer, aChild);
@@ -768,22 +792,25 @@ nsRange::ParentChainChanged(nsIContent *
// of mRoot is the last thing in DoSetRange.
DoSetRange(mStartContainer, mStartOffset, mEndContainer, mEndOffset, newRoot);
}
/******************************************************
* Utilities for comparing points: API from nsIDOMRange
******************************************************/
NS_IMETHODIMP
-nsRange::IsPointInRange(nsIDOMNode* aContainer, int32_t aOffset, bool* aResult)
+nsRange::IsPointInRange(nsIDOMNode* aContainer, uint32_t aOffset, bool* aResult)
{
nsCOMPtr<nsINode> container = do_QueryInterface(aContainer);
if (!container) {
return NS_ERROR_DOM_NOT_OBJECT_ERR;
}
+ if (NS_WARN_IF(!IsValidOffset(aOffset))) {
+ return NS_ERROR_DOM_INDEX_SIZE_ERR;
+ }
ErrorResult rv;
*aResult = IsPointInRange(*container, aOffset, rv);
return rv.StealNSResult();
}
bool
nsRange::IsPointInRange(nsINode& aContainer, uint32_t aOffset, ErrorResult& aRv)
@@ -796,17 +823,18 @@ nsRange::IsPointInRange(nsINode& aContai
}
return compareResult == 0;
}
// returns -1 if point is before range, 0 if point is in range,
// 1 if point is after range.
NS_IMETHODIMP
-nsRange::ComparePoint(nsIDOMNode* aContainer, int32_t aOffset, int16_t* aResult)
+nsRange::ComparePoint(nsIDOMNode* aContainer, uint32_t aOffset,
+ int16_t* aResult)
{
nsCOMPtr<nsINode> container = do_QueryInterface(aContainer);
NS_ENSURE_TRUE(container, NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
ErrorResult rv;
*aResult = ComparePoint(*container, aOffset, rv);
return rv.StealNSResult();
}
@@ -830,25 +858,28 @@ nsRange::ComparePoint(nsINode& aContaine
return 0;
}
if (aOffset > aContainer.Length()) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return 0;
}
- int32_t cmp;
- if ((cmp = nsContentUtils::ComparePoints(&aContainer, aOffset,
- mStartContainer,
- mStartOffset)) <= 0) {
-
+ int32_t cmp =
+ nsContentUtils::ComparePoints(&aContainer,
+ static_cast<int32_t>(aOffset),
+ mStartContainer,
+ static_cast<int32_t>(mStartOffset));
+ if (cmp <= 0) {
return cmp;
}
- if (nsContentUtils::ComparePoints(mEndContainer, mEndOffset,
- &aContainer, aOffset) == -1) {
+ if (nsContentUtils::ComparePoints(mEndContainer,
+ static_cast<int32_t>(mEndOffset),
+ &aContainer,
+ static_cast<int32_t>(aOffset)) == -1) {
return 1;
}
return 0;
}
NS_IMETHODIMP
nsRange::IntersectsNode(nsIDOMNode* aNode, bool* aResult)
@@ -881,22 +912,25 @@ nsRange::IntersectsNode(nsINode& aNode,
}
// Step 5.
int32_t nodeIndex = parent->IndexOf(&aNode);
// Steps 6-7.
// Note: if disconnected is true, ComparePoints returns 1.
bool disconnected = false;
- bool result = nsContentUtils::ComparePoints(mStartContainer, mStartOffset,
- parent, nodeIndex + 1,
- &disconnected) < 0 &&
- nsContentUtils::ComparePoints(parent, nodeIndex,
- mEndContainer, mEndOffset,
- &disconnected) < 0;
+ bool result =
+ nsContentUtils::ComparePoints(mStartContainer,
+ static_cast<int32_t>(mStartOffset),
+ parent, nodeIndex + 1,
+ &disconnected) < 0 &&
+ nsContentUtils::ComparePoints(parent, nodeIndex,
+ mEndContainer,
+ static_cast<int32_t>(mEndOffset),
+ &disconnected) < 0;
// Step 2.
if (disconnected) {
result = false;
}
return result;
}
@@ -905,18 +939,18 @@ nsRange::IntersectsNode(nsINode& aNode,
******************************************************/
// It's important that all setting of the range start/end points
// go through this function, which will do all the right voodoo
// for content notification of range ownership.
// Calling DoSetRange with either parent argument null will collapse
// the range to have both endpoints point to the other node
void
-nsRange::DoSetRange(nsINode* aStartN, int32_t aStartOffset,
- nsINode* aEndN, int32_t aEndOffset,
+nsRange::DoSetRange(nsINode* aStartN, uint32_t aStartOffset,
+ nsINode* aEndN, uint32_t aEndOffset,
nsINode* aRoot, bool aNotInsertedYet)
{
NS_PRECONDITION((aStartN && aEndN && aRoot) ||
(!aStartN && !aEndN && !aRoot),
"Set all or none");
NS_PRECONDITION(!aRoot || aNotInsertedYet ||
(nsContentUtils::ContentIsDescendantOf(aStartN, aRoot) &&
nsContentUtils::ContentIsDescendantOf(aEndN, aRoot) &&
@@ -932,16 +966,18 @@ nsRange::DoSetRange(nsINode* aStartN, in
static_cast<nsIContent*>(aEndN)->GetBindingParent()) ||
(!aRoot->GetParentNode() &&
(aRoot->IsNodeOfType(nsINode::eDOCUMENT) ||
aRoot->IsNodeOfType(nsINode::eATTRIBUTE) ||
aRoot->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT) ||
/*For backward compatibility*/
aRoot->IsNodeOfType(nsINode::eCONTENT))),
"Bad root");
+ MOZ_ASSERT(IsValidOffset(aStartOffset));
+ MOZ_ASSERT(IsValidOffset(aEndOffset));
if (mRoot != aRoot) {
if (mRoot) {
mRoot->RemoveMutationObserver(this);
}
if (aRoot) {
aRoot->AddMutationObserver(this);
}
@@ -1054,17 +1090,17 @@ nsRange::GetStartContainer(ErrorResult&
aRv.Throw(NS_ERROR_NOT_INITIALIZED);
return nullptr;
}
return mStartContainer;
}
NS_IMETHODIMP
-nsRange::GetStartOffset(int32_t* aStartOffset)
+nsRange::GetStartOffset(uint32_t* aStartOffset)
{
if (!mIsPositioned)
return NS_ERROR_NOT_INITIALIZED;
*aStartOffset = mStartOffset;
return NS_OK;
}
@@ -1096,17 +1132,17 @@ nsRange::GetEndContainer(ErrorResult& aR
aRv.Throw(NS_ERROR_NOT_INITIALIZED);
return nullptr;
}
return mEndContainer;
}
NS_IMETHODIMP
-nsRange::GetEndOffset(int32_t* aEndOffset)
+nsRange::GetEndOffset(uint32_t* aEndOffset)
{
if (!mIsPositioned)
return NS_ERROR_NOT_INITIALIZED;
*aEndOffset = mEndOffset;
return NS_OK;
}
@@ -1155,20 +1191,20 @@ nsRange::GetCommonAncestorContainer(nsID
*aCommonParent = nullptr;
}
return rv.StealNSResult();
}
/* static */
bool
-nsRange::IsValidOffset(nsINode* aNode, int32_t aOffset)
+nsRange::IsValidOffset(nsINode* aNode, uint32_t aOffset)
{
return aNode &&
- aOffset >= 0 &&
+ IsValidOffset(aOffset) &&
static_cast<size_t>(aOffset) <= aNode->Length();
}
nsINode*
nsRange::IsValidBoundary(nsINode* aNode)
{
if (!aNode) {
return nullptr;
@@ -1230,45 +1266,47 @@ nsRange::SetStart(nsINode& aNode, uint32
return;
}
AutoInvalidateSelection atEndOfBlock(this);
aRv = SetStart(&aNode, aOffset);
}
NS_IMETHODIMP
-nsRange::SetStart(nsIDOMNode* aContainer, int32_t aOffset)
+nsRange::SetStart(nsIDOMNode* aContainer, uint32_t aOffset)
{
nsCOMPtr<nsINode> container = do_QueryInterface(aContainer);
if (!container) {
return NS_ERROR_DOM_NOT_OBJECT_ERR;
}
ErrorResult rv;
SetStart(*container, aOffset, rv);
return rv.StealNSResult();
}
/* virtual */ nsresult
-nsRange::SetStart(nsINode* aContainer, int32_t aOffset)
+nsRange::SetStart(nsINode* aContainer, uint32_t aOffset)
{
nsINode* newRoot = IsValidBoundary(aContainer);
if (!newRoot) {
return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
}
if (!IsValidOffset(aContainer, 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(aContainer, aOffset,
- mEndContainer, mEndOffset) == 1) {
+ nsContentUtils::ComparePoints(aContainer,
+ static_cast<int32_t>(aOffset),
+ mEndContainer,
+ static_cast<int32_t>(mEndOffset)) == 1) {
DoSetRange(aContainer, aOffset, aContainer, aOffset, newRoot);
return NS_OK;
}
DoSetRange(aContainer, aOffset, mEndContainer, mEndOffset, mRoot);
return NS_OK;
@@ -1287,17 +1325,20 @@ nsRange::SetStartBefore(nsINode& aNode,
{
if (!nsContentUtils::LegacyIsCallerNativeCode() &&
!nsContentUtils::CanCallerAccess(&aNode)) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
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* container = GetContainerAndOffsetBefore(&aNode, &offset);
aRv = SetStart(container, offset);
}
NS_IMETHODIMP
nsRange::SetStartBefore(nsIDOMNode* aSibling)
{
nsCOMPtr<nsINode> sibling = do_QueryInterface(aSibling);
@@ -1323,17 +1364,20 @@ nsRange::SetStartAfter(nsINode& aNode, E
{
if (!nsContentUtils::LegacyIsCallerNativeCode() &&
!nsContentUtils::CanCallerAccess(&aNode)) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
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* container = GetContainerAndOffsetAfter(&aNode, &offset);
aRv = SetStart(container, offset);
}
NS_IMETHODIMP
nsRange::SetStartAfter(nsIDOMNode* aSibling)
{
nsCOMPtr<nsINode> sibling = do_QueryInterface(aSibling);
@@ -1362,58 +1406,60 @@ nsRange::SetEnd(nsINode& aNode, uint32_t
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
AutoInvalidateSelection atEndOfBlock(this);
aRv = SetEnd(&aNode, aOffset);
}
NS_IMETHODIMP
-nsRange::SetEnd(nsIDOMNode* aContainer, int32_t aOffset)
+nsRange::SetEnd(nsIDOMNode* aContainer, uint32_t aOffset)
{
nsCOMPtr<nsINode> container = do_QueryInterface(aContainer);
if (!container) {
return NS_ERROR_DOM_NOT_OBJECT_ERR;
}
ErrorResult rv;
SetEnd(*container, aOffset, rv);
return rv.StealNSResult();
}
/* virtual */ nsresult
-nsRange::SetEnd(nsINode* aContainer, int32_t aOffset)
+nsRange::SetEnd(nsINode* aContainer, uint32_t aOffset)
{
nsINode* newRoot = IsValidBoundary(aContainer);
if (!newRoot) {
return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
}
if (!IsValidOffset(aContainer, 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(mStartContainer, mStartOffset,
- aContainer, aOffset) == 1) {
+ nsContentUtils::ComparePoints(mStartContainer,
+ static_cast<int32_t>(mStartOffset),
+ aContainer,
+ static_cast<int32_t>(aOffset)) == 1) {
DoSetRange(aContainer, aOffset, aContainer, aOffset, newRoot);
return NS_OK;
}
DoSetRange(mStartContainer, mStartOffset, aContainer, aOffset, mRoot);
return NS_OK;
}
nsresult
-nsRange::SetStartAndEnd(nsINode* aStartContainer, int32_t aStartOffset,
- nsINode* aEndContainer, int32_t aEndOffset)
+nsRange::SetStartAndEnd(nsINode* aStartContainer, uint32_t aStartOffset,
+ nsINode* aEndContainer, uint32_t aEndOffset)
{
if (NS_WARN_IF(!aStartContainer) || NS_WARN_IF(!aEndContainer)) {
return NS_ERROR_INVALID_ARG;
}
nsINode* newStartRoot = IsValidBoundary(aStartContainer);
if (!newStartRoot) {
return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
@@ -1450,18 +1496,20 @@ nsRange::SetStartAndEnd(nsINode* aStartC
if (newStartRoot != newEndRoot) {
DoSetRange(aEndContainer, aEndOffset,
aEndContainer, 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(aStartContainer, aStartOffset,
- aEndContainer, aEndOffset) == 1) {
+ if (nsContentUtils::ComparePoints(aStartContainer,
+ static_cast<int32_t>(aStartOffset),
+ aEndContainer,
+ static_cast<int32_t>(aEndOffset)) == 1) {
DoSetRange(aEndContainer, aEndOffset,
aEndContainer, aEndOffset, newEndRoot);
return NS_OK;
}
// Otherwise, set the range as specified.
DoSetRange(aStartContainer, aStartOffset,
aEndContainer, aEndOffset, newStartRoot);
@@ -1481,17 +1529,20 @@ nsRange::SetEndBefore(nsINode& aNode, Er
{
if (!nsContentUtils::LegacyIsCallerNativeCode() &&
!nsContentUtils::CanCallerAccess(&aNode)) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
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* container = GetContainerAndOffsetBefore(&aNode, &offset);
aRv = SetEnd(container, offset);
}
NS_IMETHODIMP
nsRange::SetEndBefore(nsIDOMNode* aSibling)
{
nsCOMPtr<nsINode> sibling = do_QueryInterface(aSibling);
@@ -1517,17 +1568,20 @@ nsRange::SetEndAfter(nsINode& aNode, Err
{
if (!nsContentUtils::LegacyIsCallerNativeCode() &&
!nsContentUtils::CanCallerAccess(&aNode)) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
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* container = GetContainerAndOffsetAfter(&aNode, &offset);
aRv = SetEnd(container, offset);
}
NS_IMETHODIMP
nsRange::SetEndAfter(nsIDOMNode* aSibling)
{
nsCOMPtr<nsINode> sibling = do_QueryInterface(aSibling);
@@ -1597,17 +1651,19 @@ nsRange::SelectNode(nsINode& aNode, Erro
nsINode* container = aNode.GetParentNode();
nsINode* newRoot = IsValidBoundary(container);
if (!newRoot) {
aRv.Throw(NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
return;
}
int32_t index = container->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);
return;
}
AutoInvalidateSelection atEndOfBlock(this);
DoSetRange(container, index, container, index + 1, newRoot);
}
@@ -2054,33 +2110,35 @@ nsRange::CutContents(DocumentFragment**
// Batch possible DOMSubtreeModified events.
mozAutoSubtreeModified subtree(mRoot ? mRoot->OwnerDoc(): nullptr, nullptr);
// Save the range end points locally to avoid interference
// of Range gravity during our edits!
nsCOMPtr<nsINode> startContainer = mStartContainer;
- int32_t startOffset = mStartOffset;
+ uint32_t startOffset = mStartOffset;
nsCOMPtr<nsINode> endContainer = mEndContainer;
- int32_t endOffset = mEndOffset;
+ uint32_t endOffset = mEndOffset;
if (retval) {
// For extractContents(), abort early if there's a doctype (bug 719533).
// This can happen only if the common ancestor is a document, in which case
// we just need to find its doctype child and check if that's in the range.
nsCOMPtr<nsIDocument> commonAncestorDocument = do_QueryInterface(commonAncestor);
if (commonAncestorDocument) {
RefPtr<DocumentType> doctype = commonAncestorDocument->GetDoctype();
if (doctype &&
- nsContentUtils::ComparePoints(startContainer, startOffset,
+ nsContentUtils::ComparePoints(startContainer,
+ static_cast<int32_t>(startOffset),
doctype, 0) < 0 &&
nsContentUtils::ComparePoints(doctype, 0,
- endContainer, endOffset) < 0) {
+ endContainer,
+ static_cast<int32_t>(endOffset)) < 0) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
}
}
// Create and initialize a subtree iterator that will give
// us all the subtrees within the range.
@@ -2165,60 +2223,53 @@ nsRange::CutContents(DocumentFragment**
}
else
{
// Delete or extract everything after startOffset.
rv = charData->GetLength(&dataLength);
NS_ENSURE_SUCCESS(rv, rv);
- if (dataLength >= (uint32_t)startOffset)
- {
+ if (dataLength >= startOffset) {
nsMutationGuard guard;
nsCOMPtr<nsIDOMCharacterData> cutNode;
rv = SplitDataNode(charData, startOffset, getter_AddRefs(cutNode));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_STATE(!guard.Mutated(1) ||
ValidateCurrentNode(this, iter));
nodeToResult = do_QueryInterface(cutNode);
}
handled = true;
}
}
else if (node == endContainer)
{
// Delete or extract everything before endOffset.
-
- if (endOffset >= 0)
- {
- nsMutationGuard guard;
- nsCOMPtr<nsIDOMCharacterData> cutNode;
- /* The Range spec clearly states clones get cut and original nodes
- remain behind, so use false as the last parameter.
- */
- rv = SplitDataNode(charData, endOffset, getter_AddRefs(cutNode),
- false);
- NS_ENSURE_SUCCESS(rv, rv);
- NS_ENSURE_STATE(!guard.Mutated(1) ||
- ValidateCurrentNode(this, iter));
- nodeToResult = do_QueryInterface(cutNode);
- }
-
+ nsMutationGuard guard;
+ nsCOMPtr<nsIDOMCharacterData> cutNode;
+ /* The Range spec clearly states clones get cut and original nodes
+ remain behind, so use false as the last parameter.
+ */
+ rv = SplitDataNode(charData, endOffset, getter_AddRefs(cutNode),
+ false);
+ NS_ENSURE_SUCCESS(rv, rv);
+ NS_ENSURE_STATE(!guard.Mutated(1) ||
+ ValidateCurrentNode(this, iter));
+ nodeToResult = do_QueryInterface(cutNode);
handled = true;
}
}
if (!handled && (node == endContainer || node == startContainer))
{
if (node && node->IsElement() &&
((node == endContainer && endOffset == 0) ||
(node == startContainer &&
- int32_t(node->AsElement()->GetChildCount()) == startOffset)))
- {
+ node->AsElement()->GetChildCount() == startOffset))) {
if (retval) {
ErrorResult rv;
nodeToResult = node->CloneNode(false, rv);
NS_ENSURE_TRUE(!rv.Failed(), rv.StealNSResult());
}
handled = true;
}
}
@@ -2353,17 +2404,17 @@ nsRange::CompareBoundaryPoints(uint16_t
ErrorResult& rv)
{
if (!mIsPositioned || !aOtherRange.IsPositioned()) {
rv.Throw(NS_ERROR_NOT_INITIALIZED);
return 0;
}
nsINode *ourNode, *otherNode;
- int32_t ourOffset, otherOffset;
+ uint32_t ourOffset, otherOffset;
switch (aHow) {
case nsIDOMRange::START_TO_START:
ourNode = mStartContainer;
ourOffset = mStartOffset;
otherNode = aOtherRange.GetStartContainer();
otherOffset = aOtherRange.StartOffset();
break;
@@ -2391,18 +2442,20 @@ nsRange::CompareBoundaryPoints(uint16_t
return 0;
}
if (mRoot != aOtherRange.GetRoot()) {
rv.Throw(NS_ERROR_DOM_WRONG_DOCUMENT_ERR);
return 0;
}
- return nsContentUtils::ComparePoints(ourNode, ourOffset,
- otherNode, otherOffset);
+ return nsContentUtils::ComparePoints(ourNode,
+ static_cast<int32_t>(ourOffset),
+ otherNode,
+ static_cast<int32_t>(otherOffset));
}
/* static */ nsresult
nsRange::CloneParentsBetween(nsINode *aAncestor,
nsINode *aNode,
nsINode **aClosestAncestor,
nsINode **aFarthestAncestor)
{
@@ -2509,18 +2562,17 @@ nsRange::CloneContents(ErrorResult& aRv)
// correctly places this new subtree into the doc fragment.
while (!iter.IsDone())
{
nsCOMPtr<nsINode> node = iter.GetCurrentNode();
bool deepClone = !node->IsElement() ||
(!(node == mEndContainer && mEndOffset == 0) &&
!(node == mStartContainer &&
- mStartOffset ==
- int32_t(node->AsElement()->GetChildCount())));
+ mStartOffset == node->AsElement()->GetChildCount()));
// Clone the current subtree!
nsCOMPtr<nsINode> clone = node->CloneNode(deepClone, aRv);
if (aRv.Failed()) {
return nullptr;
}
@@ -2539,18 +2591,17 @@ nsRange::CloneContents(ErrorResult& aRv)
// data after it.
uint32_t dataLength = 0;
aRv = charData->GetLength(&dataLength);
if (aRv.Failed()) {
return nullptr;
}
- if (dataLength > (uint32_t)mEndOffset)
- {
+ if (dataLength > mEndOffset) {
aRv = charData->DeleteData(mEndOffset, dataLength - mEndOffset);
if (aRv.Failed()) {
return nullptr;
}
}
}
if (node == mStartContainer) {
@@ -2697,17 +2748,17 @@ void
nsRange::InsertNode(nsINode& aNode, ErrorResult& aRv)
{
if (!nsContentUtils::LegacyIsCallerNativeCode() &&
!nsContentUtils::CanCallerAccess(&aNode)) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
- int32_t tStartOffset = StartOffset();
+ uint32_t tStartOffset = StartOffset();
nsCOMPtr<nsINode> tStartContainer = GetStartContainer(aRv);
if (aRv.Failed()) {
return;
}
if (&aNode == tStartContainer) {
aRv.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
@@ -2758,28 +2809,30 @@ nsRange::InsertNode(nsINode& aNode, Erro
if (aRv.Failed()) {
return;
}
}
// 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
// needed in advance (bug 765799).
- int32_t newOffset;
+ uint32_t newOffset;
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 {
- uint32_t length;
- aRv = tChildList->GetLength(&length);
+ aRv = tChildList->GetLength(&newOffset);
if (aRv.Failed()) {
return;
}
-
- newOffset = length;
}
if (aNode.NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
newOffset += aNode.GetChildCount();
} else {
newOffset++;
}
@@ -3115,21 +3168,26 @@ static nsresult GetPartialTextRect(nsLay
return NS_OK;
}
/* static */ void
nsRange::CollectClientRectsAndText(nsLayoutUtils::RectCallback* aCollector,
Sequence<nsString>* aTextList,
nsRange* aRange,
nsINode* aStartContainer,
- int32_t aStartOffset,
+ uint32_t aStartOffset,
nsINode* aEndContainer,
- int32_t aEndOffset,
+ uint32_t aEndOffset,
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
nsCOMPtr<nsINode> startContainer = aStartContainer;
nsCOMPtr<nsINode> endContainer = aEndContainer;
// Flush out layout so our frames are up to date.
if (!aStartContainer->IsInUncomposedDoc()) {
return;
}
@@ -3150,23 +3208,25 @@ nsRange::CollectClientRectsAndText(nsLay
if (iter.IsDone()) {
// the range is collapsed, only continue if the cursor is in a text node
nsCOMPtr<nsIContent> content = do_QueryInterface(aStartContainer);
if (content && content->IsNodeOfType(nsINode::eTEXT)) {
nsTextFrame* textFrame = GetTextFrameForContent(content, aFlushLayout);
if (textFrame) {
int32_t outOffset;
nsIFrame* outFrame;
- textFrame->GetChildFrameContainingOffset(aStartOffset, false,
- &outOffset, &outFrame);
+ textFrame->GetChildFrameContainingOffset(
+ static_cast<int32_t>(aStartOffset), false,
+ &outOffset, &outFrame);
if (outFrame) {
nsIFrame* relativeTo =
nsLayoutUtils::GetContainingBlockForClientRect(outFrame);
nsRect r = outFrame->GetRectRelativeToSelf();
- ExtractRectFromOffset(outFrame, aStartOffset, &r, false, aClampToEdge);
+ ExtractRectFromOffset(outFrame, static_cast<int32_t>(aStartOffset),
+ &r, false, aClampToEdge);
r.width = 0;
r = nsLayoutUtils::TransformFrameRectToAncestor(outFrame, r, relativeTo);
aCollector->AddRect(r);
}
}
}
return;
}
@@ -3175,22 +3235,24 @@ nsRange::CollectClientRectsAndText(nsLay
nsCOMPtr<nsINode> node = iter.GetCurrentNode();
iter.Next();
nsCOMPtr<nsIContent> content = do_QueryInterface(node);
if (!content)
continue;
if (content->IsNodeOfType(nsINode::eTEXT)) {
if (node == startContainer) {
int32_t offset = startContainer == endContainer ?
- aEndOffset : content->GetText()->GetLength();
- GetPartialTextRect(aCollector, aTextList, content, aStartOffset, offset,
+ static_cast<int32_t>(aEndOffset) : content->GetText()->GetLength();
+ GetPartialTextRect(aCollector, aTextList, content,
+ static_cast<int32_t>(aStartOffset), offset,
aClampToEdge, aFlushLayout);
continue;
} else if (node == endContainer) {
- GetPartialTextRect(aCollector, aTextList, content, 0, aEndOffset,
+ GetPartialTextRect(aCollector, aTextList, content,
+ 0, static_cast<int32_t>(aEndOffset),
aClampToEdge, aFlushLayout);
continue;
}
}
nsIFrame* frame = content->GetPrimaryFrame();
if (frame) {
nsLayoutUtils::GetAllInFlowRectsAndTexts(frame,
@@ -3555,17 +3617,17 @@ ElementIsVisibleNoFlush(Element* aElemen
RefPtr<nsStyleContext> sc =
nsComputedDOMStyle::GetStyleContextNoFlush(aElement, nullptr, nullptr);
return sc && sc->StyleVisibility()->IsVisible();
}
static void
AppendTransformedText(InnerTextAccumulator& aResult,
nsGenericDOMDataNode* aTextNode,
- int32_t aStart, int32_t aEnd)
+ uint32_t aStart, uint32_t aEnd)
{
nsIFrame* frame = aTextNode->GetPrimaryFrame();
if (!IsVisibleAndNotInReplacedElement(frame)) {
return;
}
nsIFrame::RenderedText text = frame->GetRenderedText(aStart, aEnd);
aResult.Append(text.mString);
}
@@ -3664,17 +3726,17 @@ nsRange::GetInnerTextNoFlush(DOMString&
}
}
nsIContent* endNode = aEndContainer;
TreeTraversalState endState = AFTER_NODE;
if (aEndContainer->IsNodeOfType(nsINode::eTEXT)) {
endState = AT_NODE;
} else {
- if (uint32_t(aEndOffset) < aEndContainer->GetChildCount()) {
+ if (aEndOffset < aEndContainer->GetChildCount()) {
endNode = aEndContainer->GetChildAt(aEndOffset);
endState = AT_NODE;
}
}
while (currentNode != endNode || currentState != endState) {
nsIFrame* f = currentNode->GetPrimaryFrame();
bool isVisibleAndNotReplaced = IsVisibleAndNotInReplacedElement(f);
--- a/dom/base/nsRange.h
+++ b/dom/base/nsRange.h
@@ -42,24 +42,30 @@ class nsRange final : public nsIDOMRange
typedef mozilla::dom::DOMRect DOMRect;
typedef mozilla::dom::DOMRectList DOMRectList;
virtual ~nsRange();
public:
explicit nsRange(nsINode* aNode);
- static nsresult CreateRange(nsIDOMNode* aStartContainer, int32_t aStartOffset,
- nsIDOMNode* aEndContainer, int32_t aEndOffset,
+ static nsresult CreateRange(nsIDOMNode* aStartContainer,
+ uint32_t aStartOffset,
+ nsIDOMNode* aEndContainer,
+ uint32_t aEndOffset,
nsRange** aRange);
- static nsresult CreateRange(nsIDOMNode* aStartContainer, int32_t aStartOffset,
- nsIDOMNode* aEndContainer, int32_t aEndOffset,
+ static nsresult CreateRange(nsIDOMNode* aStartContainer,
+ uint32_t aStartOffset,
+ nsIDOMNode* aEndContainer,
+ uint32_t aEndOffset,
nsIDOMRange** aRange);
- static nsresult CreateRange(nsINode* aStartContainer, int32_t aStartOffset,
- nsINode* aEndContainer, int32_t aEndOffset,
+ static nsresult CreateRange(nsINode* aStartContainer,
+ uint32_t aStartOffset,
+ nsINode* aEndContainer,
+ uint32_t aEndOffset,
nsRange** aRange);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsRange, nsIDOMRange)
nsrefcnt GetRefCount() const
{
return mRefCnt;
@@ -78,22 +84,22 @@ public:
return mStartContainer;
}
nsINode* GetEndContainer() const
{
return mEndContainer;
}
- int32_t StartOffset() const
+ uint32_t StartOffset() const
{
return mStartOffset;
}
- int32_t EndOffset() const
+ uint32_t EndOffset() const
{
return mEndOffset;
}
bool IsPositioned() const
{
return mIsPositioned;
}
@@ -142,63 +148,76 @@ public:
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* aContainer, int32_t aOffset);
- nsresult SetEnd(nsINode* aContainer, int32_t aOffset);
+ nsresult SetStart(nsINode* aContainer, uint32_t aOffset);
+ nsresult SetEnd(nsINode* aContainer, uint32_t aOffset);
already_AddRefed<nsRange> CloneRange() const;
/**
* 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* aStartContainer, int32_t aStartOffset,
- nsINode* aEndContainer, int32_t aEndOffset);
+ nsresult SetStartAndEnd(nsINode* aStartContainer, uint32_t aStartOffset,
+ nsINode* aEndContainer, uint32_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 aContainer and aOffset.
*/
- nsresult CollapseTo(nsINode* aContainer, int32_t aOffset)
+ nsresult CollapseTo(nsINode* aContainer, uint32_t aOffset)
{
return SetStartAndEnd(aContainer, aOffset, aContainer, aOffset);
}
/**
* Retrieves node and offset for setting start or end of a range to
* before or after aNode.
*/
- static nsINode* GetContainerAndOffsetAfter(nsINode* aNode, int32_t* aOffset)
+ static nsINode* GetContainerAndOffsetAfter(nsINode* aNode, uint32_t* aOffset)
{
MOZ_ASSERT(aNode);
MOZ_ASSERT(aOffset);
+ *aOffset = 0;
nsINode* parentNode = aNode->GetParentNode();
- *aOffset = parentNode ? parentNode->IndexOf(aNode) : -1;
- if (*aOffset >= 0) {
- (*aOffset)++;
+ if (!parentNode) {
+ return nullptr;
}
+ int32_t indexInParent = parentNode->IndexOf(aNode);
+ if (NS_WARN_IF(indexInParent < 0)) {
+ return nullptr;
+ }
+ *aOffset = static_cast<uint32_t>(indexInParent) + 1;
return parentNode;
}
- static nsINode* GetContainerAndOffsetBefore(nsINode* aNode, int32_t* aOffset)
+ static nsINode* GetContainerAndOffsetBefore(nsINode* aNode, uint32_t* aOffset)
{
MOZ_ASSERT(aNode);
MOZ_ASSERT(aOffset);
+ *aOffset = 0;
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;
}
NS_IMETHOD GetUsedFontFaces(nsIDOMFontFaceList** aResult);
// nsIMutationObserver methods
NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
@@ -322,19 +341,19 @@ public:
/**
* This helper function gets rects and correlated text for the given range.
* @param aTextList optional where nullptr = don't retrieve text
*/
static void CollectClientRectsAndText(nsLayoutUtils::RectCallback* aCollector,
mozilla::dom::Sequence<nsString>* aTextList,
nsRange* aRange,
nsINode* aStartContainer,
- int32_t aStartOffset,
+ uint32_t aStartOffset,
nsINode* aEndContainer,
- int32_t aEndOffset,
+ uint32_t aEndOffset,
bool aClampToEdge, bool aFlushLayout);
/**
* Scan this range for -moz-user-select:none nodes and split it up into
* multiple ranges to exclude those nodes. The resulting ranges are put
* in aOutRanges. If no -moz-user-select:none node is found in the range
* then |this| is unmodified and is the only range in aOutRanges.
* Otherwise, |this| will be modified so that it ends before the first
@@ -345,24 +364,35 @@ 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);
+
+ /**
+ * 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
// 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,
+ void DoSetRange(nsINode* aStartN, uint32_t aStartOffset,
+ nsINode* aEndN, uint32_t aEndOffset,
nsINode* aRoot, bool aNotInsertedYet = false);
/**
* For a range for which IsInSelection() is true, return the common
* ancestor for the range. This method uses the selection bits and
* nsGkAtoms::range property on the nodes to quickly find the ancestor.
* That is, it's a faster version of GetCommonAncestor that only works
* for ranges in a Selection. The method will assert and the behavior
@@ -425,18 +455,18 @@ protected:
static bool mIsNested;
};
nsCOMPtr<nsIDocument> mOwner;
nsCOMPtr<nsINode> mRoot;
nsCOMPtr<nsINode> mStartContainer;
nsCOMPtr<nsINode> mEndContainer;
RefPtr<mozilla::dom::Selection> mSelection;
- int32_t mStartOffset;
- int32_t mEndOffset;
+ uint32_t mStartOffset;
+ uint32_t mEndOffset;
bool mIsPositioned : 1;
bool mMaySpanAnonymousSubtrees : 1;
bool mIsGenerated : 1;
bool mStartOffsetWasIncremented : 1;
bool mEndOffsetWasIncremented : 1;
bool mCalledByJS : 1;
#ifdef DEBUG
--- a/dom/interfaces/range/nsIDOMRange.idl
+++ b/dom/interfaces/range/nsIDOMRange.idl
@@ -11,24 +11,24 @@
* For more information on this interface please see
* http://www.w3.org/TR/DOM-Level-2-Traversal-Range/
*/
[builtinclass, uuid(1f94055c-42e7-4a30-96a1-6a804f1c2d1e)]
interface nsIDOMRange : nsISupports
{
readonly attribute nsIDOMNode startContainer;
- readonly attribute long startOffset;
+ readonly attribute unsigned long startOffset;
readonly attribute nsIDOMNode endContainer;
- readonly attribute long endOffset;
+ readonly attribute unsigned long endOffset;
readonly attribute boolean collapsed;
readonly attribute nsIDOMNode commonAncestorContainer;
- void setStart(in nsIDOMNode refNode, in long offset);
- void setEnd(in nsIDOMNode refNode, in long offset);
+ void setStart(in nsIDOMNode refNode, in unsigned long offset);
+ void setEnd(in nsIDOMNode refNode, in unsigned long offset);
void setStartBefore(in nsIDOMNode refNode);
void setStartAfter(in nsIDOMNode refNode);
void setEndBefore(in nsIDOMNode refNode);
void setEndAfter(in nsIDOMNode refNode);
void collapse(in boolean toStart);
void selectNode(in nsIDOMNode refNode);
void selectNodeContents(in nsIDOMNode refNode);
@@ -51,24 +51,24 @@ interface nsIDOMRange : nsISupports
// This method comes from
// http://html5.org/specs/dom-parsing.html#extensions-to-the-range-interface
nsIDOMDocumentFragment createContextualFragment(in DOMString fragment);
// This returns true if parent+offset equals either
// of the boundary points or is between them.
boolean isPointInRange(in nsIDOMNode parent,
- in long offset);
+ in unsigned long offset);
// comparePoint returns
// -1 if point is before the start boundary point,
// 0 if point is either of the boundary points or between them,
// 1 if point is after the end boundary point.
// 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.
*/
boolean intersectsNode(in nsIDOMNode node);
// These methods come from
// http://dev.w3.org/csswg/cssom-view/#extensions-to-the-range-interface
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -5314,17 +5314,17 @@ EditorBase::GetIMESelectionStartOffsetIn
MOZ_ASSERT(aTextNode, "aTextNode must not be nullptr");
nsCOMPtr<nsISelectionController> selectionController =
GetSelectionController();
if (NS_WARN_IF(!selectionController)) {
return -1;
}
- int32_t minOffset = INT32_MAX;
+ uint32_t minOffset = UINT32_MAX;
static const SelectionType kIMESelectionTypes[] = {
SelectionType::eIMERawClause,
SelectionType::eIMESelectedRawClause,
SelectionType::eIMEConvertedClause,
SelectionType::eIMESelectedClause
};
for (auto selectionType : kIMESelectionTypes) {
RefPtr<Selection> selection = GetSelection(selectionType);
@@ -5334,25 +5334,21 @@ EditorBase::GetIMESelectionStartOffsetIn
for (uint32_t i = 0; i < selection->RangeCount(); i++) {
RefPtr<nsRange> range = selection->GetRangeAt(i);
if (NS_WARN_IF(!range)) {
continue;
}
if (NS_WARN_IF(range->GetStartContainer() != aTextNode)) {
// ignore the start offset...
} else {
- MOZ_ASSERT(range->StartOffset() >= 0,
- "start offset shouldn't be negative");
minOffset = std::min(minOffset, range->StartOffset());
}
if (NS_WARN_IF(range->GetEndContainer() != aTextNode)) {
// ignore the end offset...
} else {
- MOZ_ASSERT(range->EndOffset() >= 0,
- "start offset shouldn't be negative");
minOffset = std::min(minOffset, range->EndOffset());
}
}
}
return minOffset < INT32_MAX ? minOffset : -1;
}
void
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -453,17 +453,17 @@ HTMLEditRules::AfterEditInner(EditAction
return NS_OK;
}
NS_ENSURE_STATE(mHTMLEditor);
RefPtr<Selection> selection = mHTMLEditor->GetSelection();
NS_ENSURE_STATE(selection);
nsCOMPtr<nsIDOMNode> rangeStartContainer, rangeEndContainer;
- int32_t rangeStartOffset = 0, rangeEndOffset = 0;
+ uint32_t rangeStartOffset = 0, rangeEndOffset = 0;
// do we have a real range to act on?
bool bDamagedRange = false;
if (mDocChangeRange) {
mDocChangeRange->GetStartContainer(getter_AddRefs(rangeStartContainer));
mDocChangeRange->GetEndContainer(getter_AddRefs(rangeEndContainer));
mDocChangeRange->GetStartOffset(&rangeStartOffset);
mDocChangeRange->GetEndOffset(&rangeEndOffset);
if (rangeStartContainer && rangeEndContainer) {
@@ -563,18 +563,18 @@ HTMLEditRules::AfterEditInner(EditAction
NS_ENSURE_STATE(mHTMLEditor);
nsresult rv =
mHTMLEditor->HandleInlineSpellCheck(
action, selection,
GetAsDOMNode(mRangeItem->mStartContainer),
mRangeItem->mStartOffset,
- rangeStartContainer, rangeStartOffset,
- rangeEndContainer, rangeEndOffset);
+ rangeStartContainer, static_cast<int32_t>(rangeStartOffset),
+ rangeEndContainer, static_cast<int32_t>(rangeEndOffset));
NS_ENSURE_SUCCESS(rv, rv);
// detect empty doc
rv = CreateBogusNodeIfNeeded(selection);
NS_ENSURE_SUCCESS(rv, rv);
// adjust selection HINT if needed
if (!mDidExplicitlySetInterline) {
@@ -5312,113 +5312,127 @@ HTMLEditRules::NormalizeSelection(Select
// we don't need to mess with cell selections, and we assume multirange selections are those.
if (rangeCount != 1) {
return NS_OK;
}
RefPtr<nsRange> range = inSelection->GetRangeAt(0);
NS_ENSURE_TRUE(range, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMNode> startNode, endNode;
- int32_t startOffset, endOffset;
+ uint32_t startOffset, endOffset;
nsCOMPtr<nsIDOMNode> newStartNode, newEndNode;
- int32_t newStartOffset, newEndOffset;
rv = range->GetStartContainer(getter_AddRefs(startNode));
NS_ENSURE_SUCCESS(rv, rv);
rv = range->GetStartOffset(&startOffset);
NS_ENSURE_SUCCESS(rv, rv);
rv = range->GetEndContainer(getter_AddRefs(endNode));
NS_ENSURE_SUCCESS(rv, rv);
rv = range->GetEndOffset(&endOffset);
NS_ENSURE_SUCCESS(rv, rv);
// adjusted values default to original values
newStartNode = startNode;
- newStartOffset = startOffset;
+ uint32_t newStartOffset = startOffset;
newEndNode = endNode;
- newEndOffset = endOffset;
+ uint32_t newEndOffset = endOffset;
// some locals we need for whitespace code
nsCOMPtr<nsINode> unused;
- int32_t offset;
+ int32_t offset = -1;
WSType wsType;
// 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,
// it would visibly change maening of users selection
nsCOMPtr<nsINode> endNode_(do_QueryInterface(endNode));
- wsEndObj.PriorVisibleNode(endNode_, endOffset, address_of(unused),
- &offset, &wsType);
+ wsEndObj.PriorVisibleNode(endNode_, static_cast<int32_t>(endOffset),
+ address_of(unused), &offset, &wsType);
if (wsType != WSType::text && wsType != WSType::normalWS) {
// eThisBlock and eOtherBlock conveniently distinquish cases
// of going "down" into a block and "up" out of a block.
if (wsEndObj.mStartReason == WSType::otherBlock) {
// endpoint is just after the close of a block.
nsCOMPtr<nsIDOMNode> child =
GetAsDOMNode(mHTMLEditor->GetRightmostChild(wsEndObj.mStartReasonNode,
true));
if (child) {
- newEndNode = EditorBase::GetNodeLocation(child, &newEndOffset);
- ++newEndOffset; // offset *after* child
+ int32_t offset = -1;
+ 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 if (wsEndObj.mStartReason == WSType::thisBlock) {
// endpoint is just after start of this block
nsCOMPtr<nsIDOMNode> child;
NS_ENSURE_STATE(mHTMLEditor);
- mHTMLEditor->GetPriorHTMLNode(endNode, endOffset, address_of(child));
+ mHTMLEditor->GetPriorHTMLNode(endNode, static_cast<int32_t>(endOffset),
+ address_of(child));
if (child) {
- newEndNode = EditorBase::GetNodeLocation(child, &newEndOffset);
- ++newEndOffset; // offset *after* child
+ int32_t offset = -1;
+ 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 if (wsEndObj.mStartReason == WSType::br) {
// endpoint is just after break. lets adjust it to before it.
+ int32_t offset = -1;
newEndNode =
EditorBase::GetNodeLocation(GetAsDOMNode(wsEndObj.mStartReasonNode),
- &newEndOffset);
+ &offset);
+ newEndOffset = static_cast<uint32_t>(offset);;
}
}
// 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,
// it would visibly change maening of users selection
nsCOMPtr<nsINode> startNode_(do_QueryInterface(startNode));
- wsStartObj.NextVisibleNode(startNode_, startOffset, address_of(unused),
- &offset, &wsType);
+ wsStartObj.NextVisibleNode(startNode_, static_cast<int32_t>(startOffset),
+ address_of(unused), &offset, &wsType);
if (wsType != WSType::text && wsType != WSType::normalWS) {
// eThisBlock and eOtherBlock conveniently distinquish cases
// of going "down" into a block and "up" out of a block.
if (wsStartObj.mEndReason == WSType::otherBlock) {
// startpoint is just before the start of a block.
nsCOMPtr<nsIDOMNode> child =
GetAsDOMNode(mHTMLEditor->GetLeftmostChild(wsStartObj.mEndReasonNode,
true));
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 if (wsStartObj.mEndReason == WSType::thisBlock) {
// startpoint is just before end of this block
nsCOMPtr<nsIDOMNode> child;
NS_ENSURE_STATE(mHTMLEditor);
- mHTMLEditor->GetNextHTMLNode(startNode, startOffset, address_of(child));
+ mHTMLEditor->GetNextHTMLNode(startNode, static_cast<int32_t>(startOffset),
+ address_of(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 if (wsStartObj.mEndReason == WSType::br) {
// startpoint is just before a break. lets adjust it to after it.
+ int32_t offset = -1;
newStartNode =
EditorBase::GetNodeLocation(GetAsDOMNode(wsStartObj.mEndReasonNode),
- &newStartOffset);
- ++newStartOffset; // offset *after* break
+ &offset);
+ // offset *after* break
+ newStartOffset = static_cast<uint32_t>(offset + 1);
}
}
// there is a demented possiblity we have to check for. We might have a very strange selection
// that is not collapsed and yet does not contain any editable content, and satisfies some of the
// above conditions that cause tweaking. In this case we don't want to tweak the selection into
// a block it was never in, etc. There are a variety of strategies one might use to try to
// detect these cases, but I think the most straightforward is to see if the adjusted locations
@@ -8188,33 +8202,33 @@ HTMLEditRules::UpdateDocChangeRange(nsRa
// The same test won't be needed further down since after we've set
// the start the range will be collapsed to that point.
result = 1;
rv = NS_OK;
}
NS_ENSURE_SUCCESS(rv, rv);
// Positive result means mDocChangeRange start is after aRange start.
if (result > 0) {
- int32_t startOffset;
+ uint32_t startOffset;
rv = aRange->GetStartOffset(&startOffset);
NS_ENSURE_SUCCESS(rv, rv);
rv = mDocChangeRange->SetStart(startNode, startOffset);
NS_ENSURE_SUCCESS(rv, rv);
}
// compare ends of ranges
rv = mDocChangeRange->CompareBoundaryPoints(nsIDOMRange::END_TO_END,
aRange, &result);
NS_ENSURE_SUCCESS(rv, rv);
// Negative result means mDocChangeRange end is before aRange end.
if (result < 0) {
nsCOMPtr<nsIDOMNode> endNode;
- int32_t endOffset;
rv = aRange->GetEndContainer(getter_AddRefs(endNode));
NS_ENSURE_SUCCESS(rv, rv);
+ uint32_t endOffset;
rv = aRange->GetEndOffset(&endOffset);
NS_ENSURE_SUCCESS(rv, rv);
rv = mDocChangeRange->SetEnd(endNode, endOffset);
NS_ENSURE_SUCCESS(rv, rv);
}
}
return NS_OK;
}
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -2413,32 +2413,30 @@ HTMLEditor::GetSelectedElement(const nsA
bool isLinkTag = IsLinkTag(TagName);
bool isNamedAnchorTag = IsNamedAnchorTag(TagName);
nsCOMPtr<nsIDOMElement> selectedElement;
RefPtr<nsRange> range = selection->GetRangeAt(0);
NS_ENSURE_STATE(range);
nsCOMPtr<nsIDOMNode> startContainer;
- int32_t startOffset, endOffset;
nsresult rv = range->GetStartContainer(getter_AddRefs(startContainer));
NS_ENSURE_SUCCESS(rv, rv);
- rv = range->GetStartOffset(&startOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ uint32_t startOffset = range->StartOffset();
nsCOMPtr<nsIDOMNode> endContainer;
rv = range->GetEndContainer(getter_AddRefs(endContainer));
NS_ENSURE_SUCCESS(rv, rv);
- rv = range->GetEndOffset(&endOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ uint32_t endOffset = range->EndOffset();
// Optimization for a single selected element
if (startContainer && startContainer == endContainer &&
endOffset - startOffset == 1) {
- nsCOMPtr<nsIDOMNode> selectedNode = GetChildAt(startContainer, startOffset);
+ nsCOMPtr<nsIDOMNode> selectedNode =
+ GetChildAt(startContainer, static_cast<int32_t>(startOffset));
NS_ENSURE_SUCCESS(rv, NS_OK);
if (selectedNode) {
selectedNode->GetNodeName(domTagName);
ToLowerCase(domTagName);
// Test for appropriate node type requested
if (anyTag || (TagName == domTagName) ||
(isLinkTag && HTMLEditUtils::IsLink(selectedNode)) ||
--- a/editor/libeditor/HTMLEditorDataTransfer.cpp
+++ b/editor/libeditor/HTMLEditorDataTransfer.cpp
@@ -136,24 +136,23 @@ HTMLEditor::LoadHTML(const nsAString& aI
nsCOMPtr<nsIDOMDocumentFragment> docfrag;
rv = range->CreateContextualFragment(aInputString, getter_AddRefs(docfrag));
NS_ENSURE_SUCCESS(rv, rv);
// put the fragment into the document
nsCOMPtr<nsIDOMNode> parent;
rv = range->GetStartContainer(getter_AddRefs(parent));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(parent, NS_ERROR_NULL_POINTER);
- int32_t childOffset;
- rv = range->GetStartOffset(&childOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ uint32_t childOffset = range->StartOffset();
nsCOMPtr<nsIDOMNode> nodeToInsert;
docfrag->GetFirstChild(getter_AddRefs(nodeToInsert));
while (nodeToInsert) {
- rv = InsertNode(nodeToInsert, parent, childOffset++);
+ rv = InsertNode(nodeToInsert, parent,
+ static_cast<int32_t>(childOffset++));
NS_ENSURE_SUCCESS(rv, rv);
docfrag->GetFirstChild(getter_AddRefs(nodeToInsert));
}
}
return rules->DidDoAction(selection, &ruleInfo, rv);
}
--- a/editor/libeditor/HTMLStyleEditor.cpp
+++ b/editor/libeditor/HTMLStyleEditor.cpp
@@ -1068,17 +1068,17 @@ HTMLEditor::GetInlinePropertyBase(nsIAto
// just ignore any non-editable nodes
if (content->GetAsText() && (!IsEditable(content) ||
IsEmptyTextNode(this, content))) {
continue;
}
if (content->GetAsText()) {
if (!isCollapsed && first && firstNodeInRange) {
firstNodeInRange = false;
- if (range->StartOffset() == (int32_t)content->Length()) {
+ if (range->StartOffset() == content->Length()) {
continue;
}
} else if (content == endNode && !endOffset) {
continue;
}
} else if (content->IsElement()) {
// handle non-text leaf nodes here
continue;
--- a/editor/libeditor/HTMLTableEditor.cpp
+++ b/editor/libeditor/HTMLTableEditor.cpp
@@ -2922,40 +2922,35 @@ HTMLEditor::GetCellFromRange(nsRange* aR
*aCell = nullptr;
nsCOMPtr<nsIDOMNode> startContainer;
nsresult rv = aRange->GetStartContainer(getter_AddRefs(startContainer));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(startContainer, NS_ERROR_FAILURE);
- int32_t startOffset;
- rv = aRange->GetStartOffset(&startOffset);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIDOMNode> childNode = GetChildAt(startContainer, startOffset);
+ uint32_t startOffset = aRange->StartOffset();
+
+ nsCOMPtr<nsIDOMNode> childNode =
+ GetChildAt(startContainer, static_cast<int32_t>(startOffset));
// This means selection is probably at a text node (or end of doc?)
if (!childNode) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMNode> endContainer;
rv = aRange->GetEndContainer(getter_AddRefs(endContainer));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(startContainer, NS_ERROR_FAILURE);
- int32_t endOffset;
- rv = aRange->GetEndOffset(&endOffset);
- NS_ENSURE_SUCCESS(rv, rv);
-
// If a cell is deleted, the range is collapse
- // (startOffset == endOffset)
+ // (startOffset == aRange->EndOffset())
// so tell caller the cell wasn't found
if (startContainer == endContainer &&
- endOffset == startOffset+1 &&
+ aRange->EndOffset() == startOffset+1 &&
HTMLEditUtils::IsTableCell(childNode)) {
// Should we also test if frame is selected? (Use GetCellDataAt())
// (Let's not for now -- more efficient)
nsCOMPtr<nsIDOMElement> cellElement = do_QueryInterface(childNode);
*aCell = cellElement.get();
NS_ADDREF(*aCell);
return NS_OK;
}
--- a/editor/txtsvc/nsFilteredContentIterator.cpp
+++ b/editor/txtsvc/nsFilteredContentIterator.cpp
@@ -236,23 +236,25 @@ ContentIsInTraversalRange(nsIContent *aC
static bool
ContentIsInTraversalRange(nsRange* aRange, nsIDOMNode* aNextNode, bool aIsPreMode)
{
nsCOMPtr<nsIContent> content(do_QueryInterface(aNextNode));
NS_ENSURE_TRUE(content && aRange, false);
nsCOMPtr<nsIDOMNode> sNode;
nsCOMPtr<nsIDOMNode> eNode;
- int32_t sOffset;
- int32_t eOffset;
+ uint32_t sOffset;
+ uint32_t eOffset;
aRange->GetStartContainer(getter_AddRefs(sNode));
aRange->GetStartOffset(&sOffset);
aRange->GetEndContainer(getter_AddRefs(eNode));
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));
}
//------------------------------------------------------------
// Helper function to advance to the next or previous node
nsresult
nsFilteredContentIterator::AdvanceNode(nsIDOMNode* aNode, nsIDOMNode*& aNewNode, eDirectionType aDir)
{
nsCOMPtr<nsIDOMNode> nextNode;
--- a/editor/txtsvc/nsTextServicesDocument.cpp
+++ b/editor/txtsvc/nsTextServicesDocument.cpp
@@ -505,17 +505,16 @@ nsTextServicesDocument::LastSelectedBloc
RefPtr<Selection> selection = domSelection->AsSelection();
bool isCollapsed = selection->IsCollapsed();
nsCOMPtr<nsIContentIterator> iter;
RefPtr<nsRange> range;
nsCOMPtr<nsIDOMNode> parent;
- int32_t rangeCount, offset;
if (isCollapsed) {
// We have a caret. Check if the caret is in a text node.
// If it is, make the text node's block the current block.
// If the caret isn't in a text node, search forwards in
// the document, till we find a text node.
range = selection->GetRangeAt(0);
@@ -532,16 +531,17 @@ nsTextServicesDocument::LastSelectedBloc
return rv;
}
if (!parent) {
UNLOCK_DOC(this);
return NS_ERROR_FAILURE;
}
+ uint32_t offset;
rv = range->GetStartOffset(&offset);
if (NS_FAILED(rv)) {
UNLOCK_DOC(this);
return rv;
}
if (IsTextNode(parent)) {
@@ -591,18 +591,19 @@ nsTextServicesDocument::LastSelectedBloc
rv = SetSelectionInternal(*aSelOffset, *aSelLength, false);
}
} else {
// The caret isn't in a text node. Create an iterator
// based on a range that extends from the current caret
// position to the end of the document, then walk forwards
// till you find a text node, then find the beginning of it's block.
- rv = CreateDocumentContentRootToNodeOffsetRange(parent, offset, false,
- getter_AddRefs(range));
+ rv = CreateDocumentContentRootToNodeOffsetRange(
+ parent, static_cast<int32_t>(offset), false,
+ getter_AddRefs(range));
if (NS_FAILED(rv)) {
UNLOCK_DOC(this);
return rv;
}
rv = range->GetCollapsed(&isCollapsed);
@@ -685,16 +686,17 @@ nsTextServicesDocument::LastSelectedBloc
}
// If we get here, we have an uncollapsed selection!
// Look backwards through each range in the selection till you
// find the first text node. If you find one, find the
// beginning of its text block, and make it the current
// block.
+ int32_t rangeCount;
rv = selection->GetRangeCount(&rangeCount);
if (NS_FAILED(rv)) {
UNLOCK_DOC(this);
return rv;
}
NS_ASSERTION(rangeCount > 0, "Unexpected range count!");
@@ -792,25 +794,26 @@ nsTextServicesDocument::LastSelectedBloc
return rv;
}
if (!parent) {
UNLOCK_DOC(this);
return NS_ERROR_FAILURE;
}
+ uint32_t offset;
rv = range->GetEndOffset(&offset);
if (NS_FAILED(rv)) {
UNLOCK_DOC(this);
return rv;
}
- rv = CreateDocumentContentRootToNodeOffsetRange(parent, offset, false,
- getter_AddRefs(range));
+ rv = CreateDocumentContentRootToNodeOffsetRange(
+ parent, static_cast<int32_t>(offset), false, getter_AddRefs(range));
if (NS_FAILED(rv)) {
UNLOCK_DOC(this);
return rv;
}
rv = range->GetCollapsed(&isCollapsed);
@@ -2372,42 +2375,44 @@ nsTextServicesDocument::GetCollapsedSele
nsCOMPtr<nsIDOMNode> domParent;
rv = range->GetStartContainer(getter_AddRefs(domParent));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsINode> parent = do_QueryInterface(domParent);
MOZ_ASSERT(parent);
- int32_t offset;
+ uint32_t offset;
rv = range->GetStartOffset(&offset);
NS_ENSURE_SUCCESS(rv, rv);
int32_t e1s1 = nsContentUtils::ComparePoints(eStart->mNode, eStartOffset,
- domParent, offset);
+ domParent,
+ static_cast<int32_t>(offset));
int32_t e2s1 = nsContentUtils::ComparePoints(eEnd->mNode, eEndOffset,
- domParent, offset);
+ domParent,
+ static_cast<int32_t>(offset));
if (e1s1 > 0 || e2s1 < 0) {
// We're done if the caret is outside the current text block.
return NS_OK;
}
if (parent->NodeType() == nsIDOMNode::TEXT_NODE) {
// Good news, the caret is in a text node. Look
// through the offset table for the entry that
// matches its parent and offset.
for (int32_t i = 0; i < tableCount; i++) {
OffsetEntry* entry = mOffsetTable[i];
NS_ENSURE_TRUE(entry, NS_ERROR_FAILURE);
if (entry->mNode == domParent.get() &&
- entry->mNodeOffset <= offset &&
- offset <= entry->mNodeOffset + entry->mLength) {
+ entry->mNodeOffset <= static_cast<int32_t>(offset) &&
+ static_cast<int32_t>(offset) <= entry->mNodeOffset + entry->mLength) {
*aSelStatus = nsITextServicesDocument::eBlockContains;
*aSelOffset = entry->mStrOffset + (offset - entry->mNodeOffset);
*aSelLength = 0;
return NS_OK;
}
}
@@ -2435,17 +2440,17 @@ nsTextServicesDocument::GetCollapsedSele
nsIContent* saveNode;
if (parent->HasChildren()) {
// XXX: We need to make sure that all of parent's
// children are in the text block.
// If the parent has children, position the iterator
// on the child that is to the left of the offset.
- uint32_t childIndex = (uint32_t)offset;
+ uint32_t childIndex = offset;
if (childIndex > 0) {
uint32_t numChildren = parent->GetChildCount();
NS_ASSERTION(childIndex <= numChildren, "Invalid selection offset!");
if (childIndex > numChildren) {
childIndex = numChildren;
}
@@ -2521,18 +2526,18 @@ nsTextServicesDocument::GetCollapsedSele
offset = 0;
}
for (int32_t i = 0; i < tableCount; i++) {
OffsetEntry* entry = mOffsetTable[i];
NS_ENSURE_TRUE(entry, NS_ERROR_FAILURE);
if (entry->mNode == node->AsDOMNode() &&
- entry->mNodeOffset <= offset &&
- offset <= entry->mNodeOffset + entry->mLength) {
+ entry->mNodeOffset <= static_cast<int32_t>(offset) &&
+ static_cast<int32_t>(offset) <= entry->mNodeOffset + entry->mLength) {
*aSelStatus = nsITextServicesDocument::eBlockContains;
*aSelOffset = entry->mStrOffset + (offset - entry->mNodeOffset);
*aSelLength = 0;
// Now move the caret so that it is actually in the text node.
// We do this to keep things in sync.
//
// In most cases, the user shouldn't see any movement in the caret
@@ -2815,27 +2820,35 @@ nsTextServicesDocument::GetRangeEndPoint
aEndContainer && aEndOffset, NS_ERROR_NULL_POINTER);
nsresult rv = aRange->GetStartContainer(aStartContainer);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(aStartContainer, NS_ERROR_FAILURE);
- rv = aRange->GetStartOffset(aStartOffset);
-
- NS_ENSURE_SUCCESS(rv, rv);
+ uint32_t offset;
+ rv = aRange->GetStartOffset(&offset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ *aStartOffset = static_cast<int32_t>(offset);
rv = aRange->GetEndContainer(aEndContainer);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(aEndContainer, 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
nsTextServicesDocument::CreateRange(nsIDOMNode* aStartContainer,
int32_t aStartOffset,
nsIDOMNode* aEndContainer,
int32_t aEndOffset,
nsRange** aRange)
--- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -347,49 +347,49 @@ nsresult
mozInlineSpellStatus::FinishNavigationEvent(mozInlineSpellWordUtil& aWordUtil)
{
nsCOMPtr<nsIEditor> editor = do_QueryReferent(mSpellChecker->mEditor);
if (! editor)
return NS_ERROR_FAILURE; // editor is gone
NS_ASSERTION(mAnchorRange, "No anchor for navigation!");
nsCOMPtr<nsIDOMNode> newAnchorNode, oldAnchorNode;
- int32_t newAnchorOffset, oldAnchorOffset;
// get the DOM position of the old caret, the range should be collapsed
nsresult rv = mOldNavigationAnchorRange->GetStartContainer(
getter_AddRefs(oldAnchorNode));
NS_ENSURE_SUCCESS(rv, rv);
- rv = mOldNavigationAnchorRange->GetStartOffset(&oldAnchorOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ uint32_t oldAnchorOffset = mOldNavigationAnchorRange->StartOffset();
// find the word on the old caret position, this is the one that we MAY need
// to check
RefPtr<nsRange> oldWord;
- rv = aWordUtil.GetRangeForWord(oldAnchorNode, oldAnchorOffset,
+ rv = aWordUtil.GetRangeForWord(oldAnchorNode,
+ static_cast<int32_t>(oldAnchorOffset),
getter_AddRefs(oldWord));
NS_ENSURE_SUCCESS(rv, rv);
// aWordUtil.GetRangeForWord flushes pending notifications, check editor again.
editor = do_QueryReferent(mSpellChecker->mEditor);
if (! editor)
return NS_ERROR_FAILURE; // editor is gone
// get the DOM position of the new caret, the range should be collapsed
rv = mAnchorRange->GetStartContainer(getter_AddRefs(newAnchorNode));
NS_ENSURE_SUCCESS(rv, rv);
- rv = mAnchorRange->GetStartOffset(&newAnchorOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ uint32_t newAnchorOffset = mAnchorRange->StartOffset();
// see if the new cursor position is in the word of the old cursor position
bool isInRange = false;
if (! mForceNavigationWordCheck) {
- rv = oldWord->IsPointInRange(newAnchorNode,
- newAnchorOffset + mNewNavigationPositionOffset,
- &isInRange);
+ rv = oldWord->IsPointInRange(
+ newAnchorNode,
+ static_cast<int32_t>(
+ newAnchorOffset + mNewNavigationPositionOffset),
+ &isInRange);
NS_ENSURE_SUCCESS(rv, rv);
}
if (isInRange) {
// caller should give up
mRange = nullptr;
} else {
// check the old word
@@ -412,21 +412,19 @@ mozInlineSpellStatus::FinishNavigationEv
nsresult
mozInlineSpellStatus::FillNoCheckRangeFromAnchor(
mozInlineSpellWordUtil& aWordUtil)
{
nsCOMPtr<nsIDOMNode> anchorNode;
nsresult rv = mAnchorRange->GetStartContainer(getter_AddRefs(anchorNode));
NS_ENSURE_SUCCESS(rv, rv);
- int32_t anchorOffset;
- rv = mAnchorRange->GetStartOffset(&anchorOffset);
- NS_ENSURE_SUCCESS(rv, rv);
-
- return aWordUtil.GetRangeForWord(anchorNode, anchorOffset,
+ uint32_t anchorOffset = mAnchorRange->StartOffset();
+ return aWordUtil.GetRangeForWord(anchorNode,
+ static_cast<int32_t>(anchorOffset),
getter_AddRefs(mNoCheckRange));
}
// mozInlineSpellStatus::GetDocument
//
// Returns the nsIDOMDocument object for the document for the
// current spellchecker.
@@ -1211,17 +1209,17 @@ mozInlineSpellChecker::MakeSpellCheckRan
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;
+ uint32_t endOffset;
endNode = nsRange::GetContainerAndOffsetAfter(endNode, &endOffset);
rv = range->SetStartAndEnd(startNode, aStartOffset, endNode, endOffset);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
range.swap(*aRange);
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -4790,19 +4790,21 @@ PresShell::ClipListToRange(nsDisplayList
if (content) {
bool atStart = (content == aRange->GetStartContainer());
bool atEnd = (content == aRange->GetEndContainer());
if ((atStart || atEnd) && frame->IsTextFrame()) {
int32_t frameStartOffset, frameEndOffset;
frame->GetOffsets(frameStartOffset, frameEndOffset);
int32_t hilightStart =
- atStart ? std::max(aRange->StartOffset(), frameStartOffset) : frameStartOffset;
+ atStart ? std::max(static_cast<int32_t>(aRange->StartOffset()),
+ frameStartOffset) : frameStartOffset;
int32_t hilightEnd =
- atEnd ? std::min(aRange->EndOffset(), frameEndOffset) : frameEndOffset;
+ atEnd ? std::min(static_cast<int32_t>(aRange->EndOffset()),
+ frameEndOffset) : frameEndOffset;
if (hilightStart < hilightEnd) {
// determine the location of the start and end edges of the range.
nsPoint startPoint, endPoint;
frame->GetPointFromOffset(hilightStart, &startPoint);
frame->GetPointFromOffset(hilightEnd, &endPoint);
// The clip rectangle is determined by taking the the start and
// end points of the range, offset from the reference frame.
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -1891,30 +1891,34 @@ nsImageFrame::ShouldDisplaySelection()
if (rangeCount == 1) //if not one then let code drop to nsFrame::Paint
{
nsCOMPtr<nsIContent> parentContent = mContent->GetParent();
if (parentContent)
{
int32_t thisOffset = parentContent->IndexOf(mContent);
nsCOMPtr<nsIDOMNode> parentNode = do_QueryInterface(parentContent);
nsCOMPtr<nsIDOMNode> rangeNode;
- int32_t rangeOffset;
+ uint32_t rangeOffset;
nsCOMPtr<nsIDOMRange> range;
selection->GetRangeAt(0,getter_AddRefs(range));
if (range)
{
range->GetStartContainer(getter_AddRefs(rangeNode));
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->GetEndOffset(&rangeOffset);
- if ((rangeNode == parentNode) && (rangeOffset == (thisOffset +1))) //+1 since that would mean this whole content is selected only
- return false; //do not allow nsFrame do draw any further selection
+ // +1 since that would mean this whole content is selected only
+ if (rangeNode == parentNode &&
+ static_cast<int32_t>(rangeOffset) == thisOffset + 1) {
+ // Do not allow nsFrame do draw any further selection
+ return false;
+ }
}
}
}
}
}
}
}
#endif
--- a/toolkit/components/find/nsFind.cpp
+++ b/toolkit/components/find/nsFind.cpp
@@ -596,17 +596,17 @@ nsFind::NextNode(nsIDOMRange* aSearchRan
nsCOMPtr<nsIContent> content;
if (!mIterator || aContinueOk) {
// If we are continuing, that means we have a match in progress. In that
// case, we want to continue from the end point (where we are now) to the
// beginning/end of the search range.
nsCOMPtr<nsIDOMNode> startNode;
nsCOMPtr<nsIDOMNode> endNode;
- int32_t startOffset, endOffset;
+ uint32_t startOffset, endOffset;
if (aContinueOk) {
#ifdef DEBUG_FIND
printf("Match in progress: continuing past endpoint\n");
#endif
if (mFindBackward) {
aSearchRange->GetStartContainer(getter_AddRefs(startNode));
aSearchRange->GetStartOffset(&startOffset);
aEndPoint->GetStartContainer(getter_AddRefs(endNode));
@@ -632,17 +632,18 @@ nsFind::NextNode(nsIDOMRange* aSearchRan
} else { // forward
aStartPoint->GetStartContainer(getter_AddRefs(startNode));
aStartPoint->GetStartOffset(&startOffset);
aEndPoint->GetEndContainer(getter_AddRefs(endNode));
aEndPoint->GetEndOffset(&endOffset);
}
}
- 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);
if (!aStartPoint) {
aStartPoint = aSearchRange;
}
content = do_QueryInterface(mIterator->GetCurrentNode());
#ifdef DEBUG_FIND
nsCOMPtr<nsIDOMNode> dnode(do_QueryInterface(content));
@@ -652,24 +653,28 @@ nsFind::NextNode(nsIDOMRange* aSearchRan
if (content && content->IsNodeOfType(nsINode::eTEXT) &&
!SkipNode(content)) {
mIterNode = do_QueryInterface(content);
// Also set mIterOffset if appropriate:
nsCOMPtr<nsIDOMNode> node;
if (mFindBackward) {
aStartPoint->GetEndContainer(getter_AddRefs(node));
if (mIterNode.get() == node.get()) {
- aStartPoint->GetEndOffset(&mIterOffset);
+ uint32_t endOffset;
+ aStartPoint->GetEndOffset(&endOffset);
+ mIterOffset = static_cast<int32_t>(endOffset);
} else {
mIterOffset = -1; // sign to start from end
}
} else {
aStartPoint->GetStartContainer(getter_AddRefs(node));
if (mIterNode.get() == node.get()) {
- aStartPoint->GetStartOffset(&mIterOffset);
+ uint32_t startOffset;
+ aStartPoint->GetStartOffset(&startOffset);
+ mIterOffset = static_cast<int32_t>(startOffset);
} else {
mIterOffset = 0;
}
}
#ifdef DEBUG_FIND
printf("Setting initial offset to %d\n", mIterOffset);
#endif
return NS_OK;
@@ -983,17 +988,17 @@ nsFind::Find(const char16_t* aPatText, n
bool wordBreakPrev = false;
// Place to save the range start point in case we find a match:
nsCOMPtr<nsIDOMNode> matchAnchorNode;
int32_t matchAnchorOffset = 0;
// Get the end point, so we know when to end searches:
nsCOMPtr<nsIDOMNode> endNode;
- int32_t endOffset;
+ uint32_t endOffset;
aEndPoint->GetEndContainer(getter_AddRefs(endNode));
aEndPoint->GetEndOffset(&endOffset);
char16_t c = 0;
char16_t patc = 0;
char16_t prevChar = 0;
char16_t prevCharInMatch = 0;
while (1) {
@@ -1118,18 +1123,18 @@ nsFind::Find(const char16_t* aPatText, n
frag = nullptr;
continue;
}
}
// Have we gone past the endpoint yet? If we have, and we're not in the
// middle of a match, return.
if (mIterNode == endNode &&
- ((mFindBackward && findex < endOffset) ||
- (!mFindBackward && findex > endOffset))) {
+ ((mFindBackward && findex < static_cast<int32_t>(endOffset)) ||
+ (!mFindBackward && findex > static_cast<int32_t>(endOffset)))) {
ResetAll();
return NS_OK;
}
// Save the previous character for word boundary detection
prevChar = c;
// The two characters we'll be comparing:
c = (t2b ? t2b[findex] : CHAR_TO_UNICHAR(t1b[findex]));
--- a/toolkit/components/find/nsWebBrowserFind.cpp
+++ b/toolkit/components/find/nsWebBrowserFind.cpp
@@ -511,17 +511,17 @@ nsWebBrowserFind::GetSearchLimits(nsIDOM
uint32_t childCount = bodyContent->GetChildCount();
// There are four possible range endpoints we might use:
// DocumentStart, SelectionStart, SelectionEnd, DocumentEnd.
nsCOMPtr<nsIDOMRange> range;
nsCOMPtr<nsIDOMNode> node;
- int32_t offset;
+ uint32_t offset;
// Forward, not wrapping: SelEnd to DocEnd
if (!mFindBackwards && !aWrap) {
// This isn't quite right, since the selection's ranges aren't
// necessarily in order; but they usually will be.
aSel->GetRangeAt(count - 1, getter_AddRefs(range));
if (!range) {
return NS_ERROR_UNEXPECTED;
--- a/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
+++ b/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
@@ -843,17 +843,17 @@ nsTypeAheadFind::GetSearchContainers(nsI
// Ensure visible range, move forward if necessary
// This uses ignores the return value, but usese the side effect of
// IsRangeVisible. It returns the first visible range after searchRange
IsRangeVisible(presShell, presContext, mSearchRange,
aIsFirstVisiblePreferred, true,
getter_AddRefs(mStartPointRange), nullptr);
}
else {
- int32_t startOffset;
+ uint32_t startOffset;
nsCOMPtr<nsIDOMNode> startNode;
if (aFindPrev) {
currentSelectionRange->GetStartContainer(getter_AddRefs(startNode));
currentSelectionRange->GetStartOffset(&startOffset);
} else {
currentSelectionRange->GetEndContainer(getter_AddRefs(startNode));
currentSelectionRange->GetEndOffset(&startOffset);
}
@@ -881,17 +881,17 @@ nsTypeAheadFind::RangeStartsInsideLink(n
{
*aIsInsideLink = false;
*aIsStartingLink = true;
// ------- Get nsIContent to test -------
nsCOMPtr<nsIDOMNode> startNode;
nsCOMPtr<nsIContent> startContent, origContent;
aRange->GetStartContainer(getter_AddRefs(startNode));
- int32_t startOffset;
+ uint32_t startOffset;
aRange->GetStartOffset(&startOffset);
startContent = do_QueryInterface(startNode);
if (!startContent) {
NS_NOTREACHED("startContent should never be null");
return;
}
origContent = startContent;
@@ -901,19 +901,20 @@ nsTypeAheadFind::RangeStartsInsideLink(n
if (childContent) {
startContent = childContent;
}
}
else if (startOffset > 0) {
const nsTextFragment *textFrag = startContent->GetText();
if (textFrag) {
// 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.
- 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
break;
}
}
}
}
@@ -1230,22 +1231,24 @@ nsTypeAheadFind::IsRangeVisible(nsIPresS
(frame->GetStateBits() & NS_FRAME_INDEPENDENT_SELECTION);
}
// ---- We have a frame ----
if (!aMustBeInViewPort)
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
- int32_t startRangeOffset, startFrameOffset, endFrameOffset;
+ int32_t startFrameOffset, endFrameOffset;
+ uint32_t startRangeOffset;
aRange->GetStartOffset(&startRangeOffset);
while (true) {
frame->GetOffsets(startFrameOffset, endFrameOffset);
- if (startRangeOffset < endFrameOffset)
+ if (static_cast<int32_t>(startRangeOffset) < endFrameOffset) {
break;
+ }
nsIFrame *nextContinuationFrame = frame->GetNextContinuation();
if (nextContinuationFrame)
frame = nextContinuationFrame;
else
break;
}