Bug 357445: Some cleanup of range code. r/sr=jst

This commit is contained in:
cvshook%sicking.cc 2006-10-21 01:30:54 +00:00
parent 12d1cf1fc3
commit 5a6d9399ce
11 changed files with 646 additions and 945 deletions

View File

@ -60,6 +60,7 @@ nsIMutationObserver.h \
nsINameSpaceManager.h \
nsINode.h \
nsINodeInfo.h \
nsIRange.h \
nsIRangeUtils.h \
nsIScriptElement.h \
nsIStyleSheetLinkingElement.h \

View File

@ -88,6 +88,7 @@ class nsIScriptGlobalObject;
template<class E> class nsCOMArray;
class nsIPref;
class nsVoidArray;
class nsIRange;
struct JSRuntime;
#ifdef MOZ_XTF
class nsIXTFService;
@ -143,14 +144,6 @@ public:
static PRBool IsCallerTrustedForWrite();
/*
* Returns true if the nodes are both in the same document or
* if neither is in a document.
* Returns false if the nodes are not in the same document.
*/
static PRBool InSameDoc(nsIDOMNode *aNode,
nsIDOMNode *aOther);
/**
* Do not ever pass null pointers to this method. If one of your
* nsIContents is null, you have to decide for yourself what
@ -241,6 +234,17 @@ public:
nsIDOM3Node::DOCUMENT_POSITION_PRECEDING;
}
/**
* 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! The two nodes MUST be in the same connected subtree!
* if they are not the result is undefined.
*/
static PRInt32 ComparePoints(nsINode* aParent1, PRInt32 aOffset1,
nsINode* aParent2, PRInt32 aOffset2);
/**
* Find the first child of aParent with a resolved tag matching
* aNamespace and aTag. Both the explicit and anonymous children of
@ -787,7 +791,7 @@ public:
* @param aRange The range containing aNode in its start- or endpoint.
* @param aCreated [out] Set to PR_TRUE if a new list was created.
*/
static nsresult AddToRangeList(nsINode *aNode, nsIDOMRange *aRange,
static nsresult AddToRangeList(nsINode *aNode, nsIRange *aRange,
PRBool *aCreated);
/**
@ -798,7 +802,7 @@ public:
* @param aRange The range to remove.
* @return PR_TRUE if aRange was the last range in the list.
*/
static PRBool RemoveFromRangeList(nsINode *aNode, nsIDOMRange *aRange);
static PRBool RemoveFromRangeList(nsINode *aNode, nsIRange *aRange);
/**
* Look up the list of ranges containing aNode.

View File

@ -53,9 +53,9 @@ class nsEventChainPreVisitor;
class nsEventChainPostVisitor;
class nsIEventListenerManager;
class nsIPrincipal;
class nsIDOMRange;
class nsVoidArray;
class nsIMutationObserver;
class nsIRange;
// This bit will be set if the node doesn't have nsSlots
#define NODE_DOESNT_HAVE_SLOTS 0x00000001U
@ -446,13 +446,13 @@ public:
* Inform node that it owns one or both range endpoints
* @param aRange the range the node owns
*/
virtual nsresult RangeAdd(nsIDOMRange* aRange);
virtual nsresult RangeAdd(nsIRange* aRange);
/**
* Inform node that it no longer owns either range endpoint
* @param aRange the range the node no longer owns
*/
virtual void RangeRemove(nsIDOMRange* aRange);
virtual void RangeRemove(nsIRange* aRange);
/**
* Get the list of ranges that have either endpoint in this node

118
content/base/public/nsIRange.h Executable file
View File

@ -0,0 +1,118 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla.org code.
*
* The Initial Developer of the Original Code is Mozilla.com.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Boris Zbarsky <bzbarsky@mit.edu> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsIRange_h___
#define nsIRange_h___
#include "nsISupports.h"
#include "nsCOMPtr.h"
#include "nsContentUtils.h"
#include "nsINode.h"
// IID for the nsIRange interface
#define NS_IRANGE_IID \
{ 0x267c8c4e, 0x7c97, 0x4a35, \
{ 0xaa, 0x08, 0x55, 0xa5, 0xbe, 0x3a, 0xc5, 0x74 } }
class nsIRange : public nsISupports {
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IRANGE_IID)
nsIRange()
: mStartOffset(0),
mEndOffset(0),
mIsPositioned(PR_FALSE),
mIsDetached(PR_FALSE)
{
}
nsINode* GetStartParent()
{
return mStartParent;
}
nsINode* GetEndParent()
{
return mEndParent;
}
PRInt32 StartOffset()
{
return mStartOffset;
}
PRInt32 EndOffset()
{
return mEndOffset;
}
PRBool IsPositioned()
{
return mIsPositioned;
}
PRBool IsDetached()
{
return mIsDetached;
}
nsINode* GetCommonAncestor()
{
return mIsPositioned ?
nsContentUtils::GetCommonAncestor(mStartParent, mEndParent) :
nsnull;
}
PRBool Collapsed()
{
return mIsPositioned && mStartParent == mEndParent &&
mStartOffset == mEndOffset;
}
protected:
nsCOMPtr<nsINode> mStartParent;
nsCOMPtr<nsINode> mEndParent;
PRInt32 mStartOffset;
PRInt32 mEndOffset;
PRPackedBool mIsPositioned;
PRPackedBool mIsDetached;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIRange, NS_IRANGE_IID)
#endif /* nsIRange_h___ */

View File

@ -50,6 +50,7 @@
#include "nsLayoutCID.h"
#include "nsVoidArray.h"
#include "nsContentUtils.h"
#include "nsINode.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
@ -148,41 +149,33 @@ ContentToParentOffset(nsIContent *aContent, nsIDOMNode **aParent,
// the traversal of the range in the specified mode.
//
static PRBool
ContentIsInTraversalRange(nsIContent *aContent, PRBool aIsPreMode,
nsIDOMNode *aStartNode, PRInt32 aStartOffset,
nsIDOMNode *aEndNode, PRInt32 aEndOffset)
ContentIsInTraversalRange(nsIContent *aContent, PRBool aIsPreMode,
nsINode *aStartNode, PRInt32 aStartOffset,
nsINode *aEndNode, PRInt32 aEndOffset)
{
if (!aStartNode || !aEndNode || !aContent)
return PR_FALSE;
nsCOMPtr<nsIDOMCharacterData> cData(do_QueryInterface(aContent));
if (cData)
{
// If a chardata node contains an end point of the traversal range,
// it is always in the traversal range.
nsCOMPtr<nsIContent> startContent(do_QueryInterface(aStartNode));
nsCOMPtr<nsIContent> endContent(do_QueryInterface(aEndNode));
if (aContent == startContent || aContent == endContent)
return PR_TRUE;
// If a chardata node contains an end point of the traversal range,
// it is always in the traversal range.
if (aContent->IsNodeOfType(nsINode::eDATA_NODE) &&
(aContent == aStartNode || aContent == aEndNode)) {
return PR_TRUE;
}
nsCOMPtr<nsIDOMNode> parentNode;
PRInt32 indx = 0;
ContentToParentOffset(aContent, getter_AddRefs(parentNode), &indx);
if (!parentNode)
nsIContent* parent = aContent->GetParent();
if (!parent)
return PR_FALSE;
PRInt32 indx = parent->IndexOf(aContent);
if (!aIsPreMode)
++indx;
return (nsRange::ComparePoints(aStartNode, aStartOffset,
parentNode, indx) <= 0) &&
(nsRange::ComparePoints(aEndNode, aEndOffset, parentNode, indx) >= 0);
return (nsContentUtils::ComparePoints(aStartNode, aStartOffset,
parent, indx) <= 0) &&
(nsContentUtils::ComparePoints(aEndNode, aEndOffset,
parent, indx) >= 0);
}
@ -374,49 +367,42 @@ nsContentIterator::Init(nsIContent* aRoot)
nsresult
nsContentIterator::Init(nsIDOMRange* aRange)
{
if (!aRange)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> dN;
nsCOMPtr<nsIRange> range = do_QueryInterface(aRange);
NS_ENSURE_TRUE(range, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIContent> startCon;
nsCOMPtr<nsIDOMNode> startDOM;
nsCOMPtr<nsIContent> endCon;
nsCOMPtr<nsIDOMNode> endDOM;
PRInt32 startIndx;
PRInt32 endIndx;
mIsDone = PR_FALSE;
// get common content parent
if (NS_FAILED(aRange->GetCommonAncestorContainer(getter_AddRefs(dN))) || !dN)
return NS_ERROR_FAILURE;
mCommonParent = do_QueryInterface(dN);
nsINode* ancestor = range->GetCommonAncestor();
mCommonParent = ancestor && ancestor->IsNodeOfType(nsINode::eCONTENT) ?
NS_STATIC_CAST(nsIContent*, ancestor) : nsnull;
NS_ENSURE_TRUE(mCommonParent, NS_ERROR_FAILURE);
// get the start node and offset, convert to nsIContent
aRange->GetStartContainer(getter_AddRefs(startDOM));
if (!startDOM)
return NS_ERROR_ILLEGAL_VALUE;
startCon = do_QueryInterface(startDOM);
if (!startCon)
return NS_ERROR_FAILURE;
aRange->GetStartOffset(&startIndx);
// get the end node and offset, convert to nsIContent
aRange->GetEndContainer(getter_AddRefs(endDOM));
if (!endDOM)
return NS_ERROR_ILLEGAL_VALUE;
endCon = do_QueryInterface(endDOM);
if (!endCon)
startIndx = range->StartOffset();
nsINode* startNode = range->GetStartParent();
if (!startNode || !startNode->IsNodeOfType(nsINode::eCONTENT)) {
return NS_ERROR_FAILURE;
}
startCon = NS_STATIC_CAST(nsIContent*, startNode);
aRange->GetEndOffset(&endIndx);
nsCOMPtr<nsIDOMCharacterData> cData(do_QueryInterface(startCon));
// get the end node and offset, convert to nsIContent
endIndx = range->EndOffset();
nsINode* endNode = range->GetEndParent();
if (!endNode || !endNode->IsNodeOfType(nsINode::eCONTENT)) {
return NS_ERROR_FAILURE;
}
endCon = NS_STATIC_CAST(nsIContent*, endNode);
PRBool startIsData = startCon->IsNodeOfType(nsINode::eDATA_NODE);
// short circuit when start node == end node
if (startDOM == endDOM)
if (startCon == endCon)
{
// Check to see if we have a collapsed range, if so,
// there is nothing to iterate over.
@ -425,13 +411,13 @@ nsContentIterator::Init(nsIDOMRange* aRange)
// since we always want to be able to iterate text nodes at
// the end points of a range.
if (!cData && startIndx == endIndx)
if (!startIsData && startIndx == endIndx)
{
MakeEmpty();
return NS_OK;
}
if (cData)
if (startIsData)
{
// It's a textnode.
@ -448,7 +434,7 @@ nsContentIterator::Init(nsIDOMRange* aRange)
nsIContent *cChild = nsnull;
if (!cData && ContentHasChildren(startCon))
if (!startIsData && ContentHasChildren(startCon))
cChild = startCon->GetChildAt(startIndx);
if (!cChild) // no children, must be a text node
@ -459,7 +445,7 @@ nsContentIterator::Init(nsIDOMRange* aRange)
// character in the cdata node, should we set mFirst to
// the next sibling?
if (!cData)
if (!startIsData)
{
mFirst = GetNextSibling(startCon, nsnull);
@ -467,7 +453,7 @@ nsContentIterator::Init(nsIDOMRange* aRange)
// The range could be 'degenerate', ie not collapsed
// but still contain no content.
if (mFirst && !ContentIsInTraversalRange(mFirst, mPre, startDOM, startIndx, endDOM, endIndx))
if (mFirst && !ContentIsInTraversalRange(mFirst, mPre, startCon, startIndx, endCon, endIndx))
mFirst = nsnull;
}
else
@ -488,7 +474,7 @@ nsContentIterator::Init(nsIDOMRange* aRange)
// The range could be 'degenerate', ie not collapsed
// but still contain no content.
if (mFirst && !ContentIsInTraversalRange(mFirst, mPre, startDOM, startIndx, endDOM, endIndx))
if (mFirst && !ContentIsInTraversalRange(mFirst, mPre, startCon, startIndx, endCon, endIndx))
mFirst = nsnull;
}
}
@ -496,9 +482,9 @@ nsContentIterator::Init(nsIDOMRange* aRange)
// Find last node in range.
cData = do_QueryInterface(endCon);
PRBool endIsData = endCon->IsNodeOfType(nsINode::eDATA_NODE);
if (cData || !ContentHasChildren(endCon) || endIndx == 0)
if (endIsData || !ContentHasChildren(endCon) || endIndx == 0)
{
if (mPre)
mLast = endCon;
@ -508,11 +494,11 @@ nsContentIterator::Init(nsIDOMRange* aRange)
// character in the cdata node, should we set mLast to
// the prev sibling?
if (!cData)
if (!endIsData)
{
mLast = GetPrevSibling(endCon, nsnull);
if (!ContentIsInTraversalRange(mLast, mPre, startDOM, startIndx, endDOM, endIndx))
if (!ContentIsInTraversalRange(mLast, mPre, startCon, startIndx, endCon, endIndx))
mLast = nsnull;
}
else
@ -535,7 +521,7 @@ nsContentIterator::Init(nsIDOMRange* aRange)
{
mLast = GetDeepLastChild(cChild, nsnull);
if (!ContentIsInTraversalRange(mLast, mPre, startDOM, startIndx, endDOM, endIndx))
if (!ContentIsInTraversalRange(mLast, mPre, startCon, startIndx, endCon, endIndx))
mLast = nsnull;
}
else // post-order
@ -1087,8 +1073,8 @@ nsContentIterator::PositionAt(nsIContent* aCurNode)
}
if (!firstNode || !lastNode ||
!ContentIsInTraversalRange(mCurNode, mPre, firstNode, firstOffset,
lastNode, lastOffset))
!ContentIsInTraversalRange(mCurNode, mPre, mFirst, firstOffset,
mLast, lastOffset))
{
mIsDone = PR_TRUE;
return NS_ERROR_FAILURE;

View File

@ -1120,27 +1120,6 @@ nsContentUtils::IsCallerTrustedForWrite()
return IsCallerTrustedForCapability("UniversalBrowserWrite");
}
// static
PRBool
nsContentUtils::InSameDoc(nsIDOMNode* aNode, nsIDOMNode* aOther)
{
if (!aNode || !aOther) {
return PR_FALSE;
}
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
nsCOMPtr<nsIContent> other(do_QueryInterface(aOther));
if (content && other) {
// XXXcaa Don't bother to check that either node is in a
// document. Editor relies on us returning true if neither
// node is in a document. See bug 154401.
return content->GetDocument() == other->GetDocument();
}
return PR_FALSE;
}
// static
PRBool
nsContentUtils::ContentIsDescendantOf(nsINode* aPossibleDescendant,
@ -1388,6 +1367,63 @@ nsContentUtils::ComparePosition(nsINode* aNode1,
nsIDOM3Node::DOCUMENT_POSITION_CONTAINED_BY);
}
/* static */
PRInt32
nsContentUtils::ComparePoints(nsINode* aParent1, PRInt32 aOffset1,
nsINode* aParent2, PRInt32 aOffset2)
{
if (aParent1 == aParent2) {
return aOffset1 < aOffset2 ? -1 :
aOffset1 > aOffset2 ? 1 :
0;
}
nsTArray<nsINode*> parents1, parents2;
nsINode* node1 = aParent1;
nsINode* node2 = aParent2;
do {
parents1.AppendElement(node1);
node1 = node1->GetNodeParent();
} while (node1);
do {
parents2.AppendElement(node2);
node2 = node2->GetNodeParent();
} while (node2);
PRUint32 pos1 = parents1.Length() - 1;
PRUint32 pos2 = parents2.Length() - 1;
NS_ASSERTION(parents1.ElementAt(pos1) == parents2.ElementAt(pos2),
"disconnected nodes");
// Find where the parent chains differ
nsINode* parent = parents1.ElementAt(pos1);
PRUint32 len;
for (len = PR_MIN(pos1, pos2); len > 0; --len) {
nsINode* child1 = parents1.ElementAt(--pos1);
nsINode* child2 = parents2.ElementAt(--pos2);
if (child1 != child2) {
return parent->IndexOf(child1) < parent->IndexOf(child2) ? -1 : 1;
}
parent = child1;
}
// 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);
return aOffset1 <= parent->IndexOf(child2) ? -1 : 1;
}
nsINode* child1 = parents1.ElementAt(--pos1);
return parent->IndexOf(child1) < aOffset2 ? -1 : 1;
}
nsIContent*
nsContentUtils::FindFirstChildWithResolvedTag(nsIContent* aParent,
PRInt32 aNamespace,
@ -3064,7 +3100,7 @@ nsContentUtils::RemoveListenerManager(nsINode *aNode)
/* static */
nsresult
nsContentUtils::AddToRangeList(nsINode *aNode, nsIDOMRange *aRange,
nsContentUtils::AddToRangeList(nsINode *aNode, nsIRange *aRange,
PRBool *aCreated)
{
*aCreated = PR_FALSE;
@ -3125,7 +3161,7 @@ nsContentUtils::AddToRangeList(nsINode *aNode, nsIDOMRange *aRange,
/* static */
PRBool
nsContentUtils::RemoveFromRangeList(nsINode *aNode, nsIDOMRange *aRange)
nsContentUtils::RemoveFromRangeList(nsINode *aNode, nsIRange *aRange)
{
if (!sRangeListsHash.ops) {
// We've already been shut down, don't bother removing a range...

View File

@ -200,7 +200,7 @@ nsINode::UnsetProperty(PRUint16 aCategory, nsIAtom *aPropertyName,
}
nsresult
nsINode::RangeAdd(nsIDOMRange* aRange)
nsINode::RangeAdd(nsIRange* aRange)
{
PRBool created;
nsresult rv = nsContentUtils::AddToRangeList(this, aRange, &created);
@ -213,7 +213,7 @@ nsINode::RangeAdd(nsIDOMRange* aRange)
}
void
nsINode::RangeRemove(nsIDOMRange* aRange)
nsINode::RangeRemove(nsIRange* aRange)
{
if (!HasFlag(NODE_HAS_RANGELIST)) {
return;

File diff suppressed because it is too large Load Diff

View File

@ -42,6 +42,7 @@
#ifndef nsRange_h___
#define nsRange_h___
#include "nsIRange.h"
#include "nsIDOMRange.h"
#include "nsIRangeUtils.h"
#include "nsIDOMNSRange.h"
@ -60,9 +61,6 @@ class nsRangeUtils : public nsIRangeUtils
public:
NS_DECL_ISUPPORTS
nsRangeUtils();
virtual ~nsRangeUtils();
// nsIRangeUtils interface
NS_IMETHOD_(PRInt32) ComparePoints(nsIDOMNode* aParent1, PRInt32 aOffset1,
nsIDOMNode* aParent2, PRInt32 aOffset2);
@ -77,15 +75,18 @@ public:
// -------------------------------------------------------------------------------
class nsRange : public nsIDOMRange,
class nsRange : public nsIRange,
public nsIDOMRange,
public nsIDOMNSRange
{
public:
NS_DECL_ISUPPORTS
nsRange();
nsRange()
{
}
virtual ~nsRange();
NS_DECL_ISUPPORTS
// nsIDOMRange interface
NS_DECL_NSIDOMRANGE
@ -101,12 +102,6 @@ public:
NS_IMETHOD NSDetach();
/*END nsIDOMNSRange interface implementations*/
NS_IMETHOD GetHasGeneratedBefore(PRBool *aBool);
NS_IMETHOD GetHasGeneratedAfter(PRBool *aBool);
NS_IMETHOD SetHasGeneratedBefore(PRBool aBool);
NS_IMETHOD SetHasGeneratedAfter(PRBool aBool);
NS_IMETHOD SetBeforeAndAfter(PRBool aBefore, PRBool aAfter);
// nsRange interface extensions
static NS_METHOD OwnerGone(nsIContent* aParentNode);
@ -115,52 +110,18 @@ public:
static NS_METHOD OwnerChildRemoved(nsIContent* aParentNode, PRInt32 aOffset, nsIContent* aRemovedNode);
static NS_METHOD OwnerChildReplaced(nsIContent* aParentNode, PRInt32 aOffset, nsIContent* aReplacedNode);
static nsresult TextOwnerChanged(nsIContent *aTextNode,
const nsVoidArray *aRangeList,
PRInt32 aStartOffset,
PRInt32 aEndOffset,
PRInt32 aReplaceLength);
protected:
PRPackedBool mBeforeGenContent;
PRPackedBool mAfterGenContent;
PRPackedBool mIsPositioned;
PRPackedBool mIsDetached;
PRInt32 mStartOffset;
PRInt32 mEndOffset;
nsCOMPtr<nsIDOMNode> mStartParent;
nsCOMPtr<nsIDOMNode> mEndParent;
private:
// no copy's or assigns
nsRange(const nsRange&);
nsRange& operator=(const nsRange&);
public:
// helper routines
static PRInt32 IndexOf(nsIDOMNode* aNode);
static nsresult PopRanges(nsIDOMNode* aDestNode, PRInt32 aOffset, nsIContent* aSourceNode);
static nsresult CloneParentsBetween(nsIDOMNode* aAncestor,
nsIDOMNode* aNode,
nsIDOMNode** closestAncestor,
nsIDOMNode** farthestAncestor);
/**
* 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.
*/
static PRInt32 ComparePoints(nsIDOMNode* aParent1, PRInt32 aOffset1,
nsIDOMNode* aParent2, PRInt32 aOffset2);
/**
* Utility routine to detect if a content node intersects a range
*/
@ -178,34 +139,8 @@ public:
PRBool *outNodeAfter);
protected:
// CollapseRangeAfterDelete() should only be called from DeleteContents()
// or ExtractContents() since it makes certain assumptions about the state
// of the range used. It's purpose is to collapse the range according to
// the range spec after the removal of nodes within the range.
static nsresult CollapseRangeAfterDelete(nsIDOMRange *aRange);
static PRInt32 GetNodeLength(nsIDOMNode *aNode);
nsresult DoSetRange(nsIDOMNode* aStartN, PRInt32 aStartOffset,
nsIDOMNode* aEndN, PRInt32 aEndOffset);
static PRBool IsIncreasing(nsIDOMNode* aStartN, PRInt32 aStartOff,
nsIDOMNode* aEndN, PRInt32 aEndOff);
PRBool IsDetached(){return mIsDetached;}
nsresult ComparePointToRange(nsIDOMNode* aParent, PRInt32 aOffset, PRInt32* aResult);
nsresult AddToListOf(nsIDOMNode* aNode);
void RemoveFromListOf(nsIDOMNode* aNode);
nsresult ContentOwnsUs(nsIDOMNode* domNode);
nsresult GetIsPositioned(PRBool* aIsPositioned);
nsresult IsValidBoundary(nsIDOMNode* aNode);
void DoSetRange(nsINode* aStartN, PRInt32 aStartOffset,
nsINode* aEndN, PRInt32 aEndOffset);
};
// Make a new nsIDOMRange object
@ -214,15 +149,4 @@ nsresult NS_NewRange(nsIDOMRange** aInstancePtrResult);
// Make a new nsIRangeUtils object
nsresult NS_NewRangeUtils(nsIRangeUtils** aInstancePtrResult);
/*************************************************************************************
* Utility routine to create a pair of dom points to represent
* the start and end locations of a single node. Return false
* if we dont' succeed.
************************************************************************************/
PRBool GetNodeBracketPoints(nsIContent* aNode,
nsCOMPtr<nsIDOMNode>* outParent,
PRInt32* outStartOffset,
PRInt32* outEndOffset);
#endif /* nsRange_h___ */

View File

@ -234,19 +234,6 @@ public:
*/
void ForgetCurrentSubmission();
/**
* Compare two nodes in the same tree (Negative result means a < b, 0 ==,
* positive >). This function may fail if the nodes are not in a tree
* or are in different trees.
*
* @param a the first node
* @param b the second node
* @param retval whether a < b (negative), a == b (0), or a > b (positive)
*/
static nsresult CompareNodes(nsIDOMNode* a,
nsIDOMNode* b,
PRInt32* retval);
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
protected:
@ -1108,55 +1095,6 @@ nsHTMLFormElement::NotifySubmitObservers(nsIURI* aActionURL,
}
// static
nsresult
nsHTMLFormElement::CompareNodes(nsIDOMNode* a, nsIDOMNode* b, PRInt32* retval)
{
nsresult rv;
nsCOMPtr<nsIDOMNode> parentANode;
PRInt32 indexA;
rv = a->GetParentNode(getter_AddRefs(parentANode));
NS_ENSURE_SUCCESS(rv, rv);
if (!parentANode) {
return NS_ERROR_UNEXPECTED;
}
{
// To get the index, we must turn them both into contents
// and do IndexOf(). Ick.
nsCOMPtr<nsIContent> parentA(do_QueryInterface(parentANode));
nsCOMPtr<nsIContent> contentA(do_QueryInterface(a));
if (!parentA || !contentA) {
return NS_ERROR_UNEXPECTED;
}
indexA = parentA->IndexOf(contentA);
}
nsCOMPtr<nsIDOMNode> parentBNode;
PRInt32 indexB;
rv = b->GetParentNode(getter_AddRefs(parentBNode));
NS_ENSURE_SUCCESS(rv, rv);
if (!parentBNode) {
return NS_ERROR_UNEXPECTED;
}
{
// To get the index, we must turn them both into contents
// and do IndexOf(). Ick.
nsCOMPtr<nsIContent> parentB(do_QueryInterface(parentBNode));
nsCOMPtr<nsIContent> bContent(do_QueryInterface(b));
if (!parentB || !bContent) {
return NS_ERROR_UNEXPECTED;
}
indexB = parentB->IndexOf(bContent);
}
*retval = nsRange::ComparePoints(parentANode, indexA, parentBNode, indexB);
return NS_OK;
}
nsresult
nsHTMLFormElement::WalkFormElements(nsIFormSubmission* aFormSubmission,
nsIContent* aSubmitElement)

View File

@ -173,6 +173,17 @@ static void printRange(nsIDOMRange *aDomRange);
//#define DEBUG_TABLE_SELECTION 1
static PRInt32
CompareDOMPoints(nsIDOMNode* aParent1, PRInt32 aOffset1,
nsIDOMNode* aParent2, PRInt32 aOffset2)
{
nsCOMPtr<nsINode> parent1 = do_QueryInterface(aParent1);
nsCOMPtr<nsINode> parent2 = do_QueryInterface(aParent2);
NS_ASSERTION(parent1 && parent2, "not real nodes?");
return nsContentUtils::ComparePoints(parent1, aOffset1, parent2, aOffset2);
}
struct CachedOffsetForFrame {
CachedOffsetForFrame()
@ -1628,8 +1639,8 @@ nsFrameSelection::SelectLines(nsDirection aSelectionDirection,
nsresult result;
// normalize the order before we start to avoid piles of conditions later
relativePosition = nsRange::ComparePoints(aAnchorNode, aAnchorOffset,
aCurrentNode, aCurrentOffset);
relativePosition = CompareDOMPoints(aAnchorNode, aAnchorOffset,
aCurrentNode, aCurrentOffset);
if (0 == relativePosition)
return NS_ERROR_FAILURE;
else if (relativePosition < 0)
@ -1679,7 +1690,7 @@ nsFrameSelection::SelectLines(nsDirection aSelectionDirection,
startNode = do_QueryInterface(startContent);
// If we have already overshot the endpoint, back out
if (nsRange::ComparePoints(startNode, startOffset, endNode, endOffset) >= 0)
if (CompareDOMPoints(startNode, startOffset, endNode, endOffset) >= 0)
return NS_ERROR_FAILURE;
aPos.mStartOffset = endOffset;
@ -1706,7 +1717,7 @@ nsFrameSelection::SelectLines(nsDirection aSelectionDirection,
endContent = aPos.mResultContent;
endNode = do_QueryInterface(endContent);
if (nsRange::ComparePoints(startNode, startOffset, endNode, endOffset) < 0)
if (CompareDOMPoints(startNode, startOffset, endNode, endOffset) < 0)
{
TakeFocus(startContent, startOffset, startOffset, PR_FALSE, PR_TRUE);
return TakeFocus(endContent, endOffset, endOffset, PR_TRUE, PR_TRUE);
@ -2189,8 +2200,8 @@ nsFrameSelection::AdjustForMaintainedSelection(nsIContent *aContent,
}
}
PRInt32 relativePosition = nsRange::ComparePoints(rangenode, rangeOffset,
domNode, aOffset);
PRInt32 relativePosition = CompareDOMPoints(rangenode, rangeOffset,
domNode, aOffset);
// if == 0 or -1 do nothing if < 0 then we need to swap direction
if (relativePosition > 0
&& (mDomSelections[index]->GetDirection() == eDirNext))
@ -2272,8 +2283,8 @@ nsFrameSelection::HandleDrag(nsIFrame *aFrame, nsPoint aPoint)
mMaintainRange->GetStartContainer(getter_AddRefs(rangenode));
mMaintainRange->GetStartOffset(&rangeOffset);
nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(offsets.content);
PRInt32 relativePosition = nsRange::ComparePoints(rangenode, rangeOffset,
domNode, offsets.offset);
PRInt32 relativePosition = CompareDOMPoints(rangenode, rangeOffset,
domNode, offsets.offset);
nsDirection direction = relativePosition > 0 ? eDirPrevious : eDirNext;
nsSelectionAmount amount = mMaintainedAmount;
@ -4220,8 +4231,8 @@ CompareToRangeStart(nsIDOMNode* aCompareNode, PRInt32 aCompareOffset,
rv = aRange->GetStartOffset(&startOffset);
NS_ENSURE_SUCCESS(rv, rv);
*cmp = nsRange::ComparePoints(aCompareNode, aCompareOffset,
startNode, startOffset);
*cmp = CompareDOMPoints(aCompareNode, aCompareOffset,
startNode, startOffset);
return NS_OK;
}
@ -4237,8 +4248,8 @@ CompareToRangeEnd(nsIDOMNode* aCompareNode, PRInt32 aCompareOffset,
rv = aRange->GetEndOffset(&endOffset);
NS_ENSURE_SUCCESS(rv, rv);
*cmp = nsRange::ComparePoints(aCompareNode, aCompareOffset,
endNode, endOffset);
*cmp = CompareDOMPoints(aCompareNode, aCompareOffset,
endNode, endOffset);
return NS_OK;
}
@ -6404,18 +6415,18 @@ nsTypedSelection::Extend(nsIDOMNode* aParentNode, PRInt32 aOffset)
if (NS_FAILED(res))
return res;
PRInt32 result1 = nsRange::ComparePoints(FetchAnchorNode(),
FetchAnchorOffset(),
FetchFocusNode(),
FetchFocusOffset());
PRInt32 result1 = CompareDOMPoints(FetchAnchorNode(),
FetchAnchorOffset(),
FetchFocusNode(),
FetchFocusOffset());
//compare old cursor to new cursor
PRInt32 result2 = nsRange::ComparePoints(FetchFocusNode(),
FetchFocusOffset(),
aParentNode, aOffset);
PRInt32 result2 = CompareDOMPoints(FetchFocusNode(),
FetchFocusOffset(),
aParentNode, aOffset);
//compare anchor to new cursor
PRInt32 result3 = nsRange::ComparePoints(FetchAnchorNode(),
FetchAnchorOffset(),
aParentNode, aOffset);
PRInt32 result3 = CompareDOMPoints(FetchAnchorNode(),
FetchAnchorOffset(),
aParentNode, aOffset);
if (result2 == 0) //not selecting anywhere
return NS_OK;