зеркало из https://github.com/mozilla/pjs.git
Bug 357445: Some cleanup of range code. r/sr=jst
This commit is contained in:
Родитель
ced58a8672
Коммит
a513afbc8a
|
@ -60,6 +60,7 @@ nsIMutationObserver.h \
|
|||
nsINameSpaceManager.h \
|
||||
nsINode.h \
|
||||
nsINodeInfo.h \
|
||||
nsIRange.h \
|
||||
nsIRangeUtils.h \
|
||||
nsIScriptElement.h \
|
||||
nsIStyleSheetLinkingElement.h \
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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___ */
|
|
@ -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;
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -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;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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___ */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче