Implement the ScriptObjectOwner interface, and adapt to fixed selection interfaces.

This commit is contained in:
sfraser%netscape.com 1999-04-15 20:19:26 +00:00
Родитель 9fdd2ed645
Коммит c0ae174df0
5 изменённых файлов: 222 добавлений и 64 удалений

Просмотреть файл

@ -32,8 +32,11 @@
#include "nsIDOMText.h"
#include "nsIContentIterator.h"
#include "nsIDOMNodeList.h"
#include "nsIScriptGlobalObject.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
nsVoidArray* nsRange::mStartAncestors = nsnull;
nsVoidArray* nsRange::mEndAncestors = nsnull;
nsVoidArray* nsRange::mStartAncestorOffsets = nsnull;
@ -247,7 +250,8 @@ nsRange::nsRange() :
mStartParent(),
mStartOffset(0),
mEndParent(),
mEndOffset(0)
mEndOffset(0),
mScriptObject(nsnull)
{
NS_INIT_REFCNT();
}
@ -276,7 +280,7 @@ nsresult nsRange::QueryInterface(const nsIID& aIID,
}
if (aIID.Equals(kISupportsIID))
{
*aInstancePtrResult = (void*)(nsISupports*)this;
*aInstancePtrResult = (void*)(nsISupports*)(nsIDOMRange *)this;
NS_ADDREF_THIS();
return NS_OK;
}
@ -286,7 +290,13 @@ nsresult nsRange::QueryInterface(const nsIID& aIID,
NS_ADDREF_THIS();
return NS_OK;
}
return !NS_OK;
if (aIID.Equals(kIScriptObjectOwnerIID)) {
nsIScriptObjectOwner* tmp = this;
*aInstancePtrResult = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
/******************************************************
@ -1488,8 +1498,6 @@ nsresult nsRange::OwnerChildInserted(nsIContent* aParentNode, PRInt32 aOffset)
parent->GetRangeList(theRangeList);
if (!theRangeList) return NS_OK;
PRInt32 loop = 0;
nsCOMPtr<nsRange> theRange;
nsCOMPtr<nsIDOMNode> domNode;
nsresult res;
@ -1497,7 +1505,9 @@ nsresult nsRange::OwnerChildInserted(nsIContent* aParentNode, PRInt32 aOffset)
if (NS_FAILED(res)) return res;
if (!domNode) return NS_ERROR_UNEXPECTED;
while (theRange = do_QueryInterface(NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop)))))
PRInt32 loop = 0;
nsRange* theRange;
while ((theRange = NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop)))) != nsnull)
{
// sanity check - do range and content agree over ownership?
res = theRange->ContentOwnsUs(domNode);
@ -1534,8 +1544,6 @@ nsresult nsRange::OwnerChildRemoved(nsIContent* aParentNode, PRInt32 aOffset, ns
parent->GetRangeList(theRangeList);
if (!theRangeList) return NS_OK;
PRInt32 loop = 0;
nsCOMPtr<nsRange> theRange;
nsCOMPtr<nsIDOMNode> domNode;
nsresult res;
@ -1543,8 +1551,9 @@ nsresult nsRange::OwnerChildRemoved(nsIContent* aParentNode, PRInt32 aOffset, ns
if (NS_FAILED(res)) return res;
if (!domNode) return NS_ERROR_UNEXPECTED;
// any ranges that are in the parentNode may need to have offsets updated
while (theRange = do_QueryInterface(NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop)))))
PRInt32 loop = 0;
nsRange* theRange;
while ((theRange = NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop)))) != nsnull)
{
// sanity check - do range and content agree over ownership?
res = theRange->ContentOwnsUs(domNode);
@ -1610,8 +1619,6 @@ nsresult nsRange::TextOwnerChanged(nsIContent* aTextNode, PRInt32 aStartChanged,
aTextNode->GetRangeList(theRangeList);
// the caller already checked to see if there was a range list
PRInt32 loop = 0;
nsCOMPtr<nsRange> theRange;
nsCOMPtr<nsIDOMNode> domNode;
nsresult res;
@ -1619,8 +1626,9 @@ nsresult nsRange::TextOwnerChanged(nsIContent* aTextNode, PRInt32 aStartChanged,
if (NS_FAILED(res)) return res;
if (!domNode) return NS_ERROR_UNEXPECTED;
// any ranges that are in the textNode may need to have offsets updated
while (theRange = do_QueryInterface(NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop)))))
PRInt32 loop = 0;
nsRange* theRange;
while ((theRange = NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop)))) != nsnull)
{
// sanity check - do range and content agree over ownership?
res = theRange->ContentOwnsUs(domNode);
@ -1661,3 +1669,28 @@ nsresult nsRange::TextOwnerChanged(nsIContent* aTextNode, PRInt32 aStartChanged,
return NS_OK;
}
// BEGIN nsIScriptContextOwner interface implementations
NS_IMETHODIMP
nsRange::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
nsIScriptGlobalObject *globalObj = aContext->GetGlobalObject();
if (nsnull == mScriptObject) {
res = NS_NewScriptRange(aContext, (nsISupports *)(nsIDOMRange *)this, globalObj, (void**)&mScriptObject);
}
*aScriptObject = mScriptObject;
NS_RELEASE(globalObj);
return res;
}
NS_IMETHODIMP
nsRange::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
// END nsIScriptContextOwner interface implementations

Просмотреть файл

@ -25,10 +25,12 @@
#include "nsIDOMDocumentFragment.h"
#include "nsIContent.h"
#include "nsIDOMNode.h"
#include "nsIScriptObjectOwner.h"
class nsVoidArray;
class nsRange : public nsIDOMRange
class nsRange : public nsIDOMRange,
public nsIScriptObjectOwner
{
public:
NS_DECL_ISUPPORTS
@ -79,6 +81,11 @@ public:
NS_IMETHOD ToString(nsString& aReturn);
/*BEGIN nsIScriptObjectOwner interface implementations*/
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
/*END nsIScriptObjectOwner interface implementations*/
// nsRange interface extensions
static NS_METHOD OwnerGone(nsIContent* aParentNode);
@ -142,6 +149,10 @@ public:
nsresult RemoveFromListOf(nsCOMPtr<nsIDOMNode> aNode);
nsresult ContentOwnsUs(nsCOMPtr<nsIDOMNode> domNode);
protected:
void* mScriptObject;
};
// Make a new nsIDOMRange object

Просмотреть файл

@ -32,8 +32,11 @@
#include "nsIDOMText.h"
#include "nsIContentIterator.h"
#include "nsIDOMNodeList.h"
#include "nsIScriptGlobalObject.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
nsVoidArray* nsRange::mStartAncestors = nsnull;
nsVoidArray* nsRange::mEndAncestors = nsnull;
nsVoidArray* nsRange::mStartAncestorOffsets = nsnull;
@ -247,7 +250,8 @@ nsRange::nsRange() :
mStartParent(),
mStartOffset(0),
mEndParent(),
mEndOffset(0)
mEndOffset(0),
mScriptObject(nsnull)
{
NS_INIT_REFCNT();
}
@ -276,7 +280,7 @@ nsresult nsRange::QueryInterface(const nsIID& aIID,
}
if (aIID.Equals(kISupportsIID))
{
*aInstancePtrResult = (void*)(nsISupports*)this;
*aInstancePtrResult = (void*)(nsISupports*)(nsIDOMRange *)this;
NS_ADDREF_THIS();
return NS_OK;
}
@ -286,7 +290,13 @@ nsresult nsRange::QueryInterface(const nsIID& aIID,
NS_ADDREF_THIS();
return NS_OK;
}
return !NS_OK;
if (aIID.Equals(kIScriptObjectOwnerIID)) {
nsIScriptObjectOwner* tmp = this;
*aInstancePtrResult = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
/******************************************************
@ -1488,8 +1498,6 @@ nsresult nsRange::OwnerChildInserted(nsIContent* aParentNode, PRInt32 aOffset)
parent->GetRangeList(theRangeList);
if (!theRangeList) return NS_OK;
PRInt32 loop = 0;
nsCOMPtr<nsRange> theRange;
nsCOMPtr<nsIDOMNode> domNode;
nsresult res;
@ -1497,7 +1505,9 @@ nsresult nsRange::OwnerChildInserted(nsIContent* aParentNode, PRInt32 aOffset)
if (NS_FAILED(res)) return res;
if (!domNode) return NS_ERROR_UNEXPECTED;
while (theRange = do_QueryInterface(NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop)))))
PRInt32 loop = 0;
nsRange* theRange;
while ((theRange = NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop)))) != nsnull)
{
// sanity check - do range and content agree over ownership?
res = theRange->ContentOwnsUs(domNode);
@ -1534,8 +1544,6 @@ nsresult nsRange::OwnerChildRemoved(nsIContent* aParentNode, PRInt32 aOffset, ns
parent->GetRangeList(theRangeList);
if (!theRangeList) return NS_OK;
PRInt32 loop = 0;
nsCOMPtr<nsRange> theRange;
nsCOMPtr<nsIDOMNode> domNode;
nsresult res;
@ -1543,8 +1551,9 @@ nsresult nsRange::OwnerChildRemoved(nsIContent* aParentNode, PRInt32 aOffset, ns
if (NS_FAILED(res)) return res;
if (!domNode) return NS_ERROR_UNEXPECTED;
// any ranges that are in the parentNode may need to have offsets updated
while (theRange = do_QueryInterface(NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop)))))
PRInt32 loop = 0;
nsRange* theRange;
while ((theRange = NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop)))) != nsnull)
{
// sanity check - do range and content agree over ownership?
res = theRange->ContentOwnsUs(domNode);
@ -1610,8 +1619,6 @@ nsresult nsRange::TextOwnerChanged(nsIContent* aTextNode, PRInt32 aStartChanged,
aTextNode->GetRangeList(theRangeList);
// the caller already checked to see if there was a range list
PRInt32 loop = 0;
nsCOMPtr<nsRange> theRange;
nsCOMPtr<nsIDOMNode> domNode;
nsresult res;
@ -1619,8 +1626,9 @@ nsresult nsRange::TextOwnerChanged(nsIContent* aTextNode, PRInt32 aStartChanged,
if (NS_FAILED(res)) return res;
if (!domNode) return NS_ERROR_UNEXPECTED;
// any ranges that are in the textNode may need to have offsets updated
while (theRange = do_QueryInterface(NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop)))))
PRInt32 loop = 0;
nsRange* theRange;
while ((theRange = NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop)))) != nsnull)
{
// sanity check - do range and content agree over ownership?
res = theRange->ContentOwnsUs(domNode);
@ -1661,3 +1669,28 @@ nsresult nsRange::TextOwnerChanged(nsIContent* aTextNode, PRInt32 aStartChanged,
return NS_OK;
}
// BEGIN nsIScriptContextOwner interface implementations
NS_IMETHODIMP
nsRange::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
nsIScriptGlobalObject *globalObj = aContext->GetGlobalObject();
if (nsnull == mScriptObject) {
res = NS_NewScriptRange(aContext, (nsISupports *)(nsIDOMRange *)this, globalObj, (void**)&mScriptObject);
}
*aScriptObject = mScriptObject;
NS_RELEASE(globalObj);
return res;
}
NS_IMETHODIMP
nsRange::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
// END nsIScriptContextOwner interface implementations

Просмотреть файл

@ -25,10 +25,12 @@
#include "nsIDOMDocumentFragment.h"
#include "nsIContent.h"
#include "nsIDOMNode.h"
#include "nsIScriptObjectOwner.h"
class nsVoidArray;
class nsRange : public nsIDOMRange
class nsRange : public nsIDOMRange,
public nsIScriptObjectOwner
{
public:
NS_DECL_ISUPPORTS
@ -79,6 +81,11 @@ public:
NS_IMETHOD ToString(nsString& aReturn);
/*BEGIN nsIScriptObjectOwner interface implementations*/
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
/*END nsIScriptObjectOwner interface implementations*/
// nsRange interface extensions
static NS_METHOD OwnerGone(nsIContent* aParentNode);
@ -142,6 +149,10 @@ public:
nsresult RemoveFromListOf(nsCOMPtr<nsIDOMNode> aNode);
nsresult ContentOwnsUs(nsCOMPtr<nsIDOMNode> domNode);
protected:
void* mScriptObject;
};
// Make a new nsIDOMRange object

Просмотреть файл

@ -25,6 +25,7 @@
#include "nsIDOMRange.h"
#include "nsIFrameSelection.h"
#include "nsIDOMSelection.h"
#include "nsIDOMSelectionListener.h"
#include "nsIFocusTracker.h"
#include "nsIComponentManager.h"
#include "nsLayoutCID.h"
@ -34,11 +35,14 @@
#include "nsRange.h"
#include "nsISupportsArray.h"
#include "nsIDOMEvent.h"
#include "nsIDOMSelectionListener.h"
#include "nsIScriptObjectOwner.h"
#include "nsIScriptGlobalObject.h"
static NS_DEFINE_IID(kIEnumeratorIID, NS_IENUMERATOR_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIFrameSelectionIID, NS_IFRAMESELECTION_IID);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
static NS_DEFINE_IID(kIDOMSelectionIID, NS_IDOMSELECTION_IID);
static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
static NS_DEFINE_IID(kIDOMRangeIID, NS_IDOMRANGE_IID);
@ -66,7 +70,8 @@ enum {FORWARD =1, BACKWARD = 0};
class nsRangeListIterator;
class nsRangeList : public nsIFrameSelection,
public nsIDOMSelection
public nsIDOMSelection,
public nsIScriptObjectOwner
{
public:
/*interfaces for addref and release and queryinterface*/
@ -87,8 +92,8 @@ public:
NS_IMETHOD GetFocusNode(nsIDOMNode** aFocusNode);
NS_IMETHOD GetFocusOffset(PRInt32* aFocusOffset);
NS_IMETHOD GetIsCollapsed(PRBool* aIsCollapsed);
NS_IMETHOD GetAnchorNodeAndOffset(nsIDOMNode** aAnchorNode, PRInt32* aOffset);
NS_IMETHOD GetFocusNodeAndOffset(nsIDOMNode** aFocusNode, PRInt32* aOffset);
NS_IMETHOD GetRangeCount(PRInt32* aRangeCount);
NS_IMETHOD GetRangeAt(PRInt32 aIndex, nsIDOMRange** aReturn);
NS_IMETHOD ClearSelection();
NS_IMETHOD Collapse(nsIDOMNode* aParentNode, PRInt32 aOffset);
NS_IMETHOD Extend(nsIDOMNode* aParentNode, PRInt32 aOffset);
@ -102,6 +107,11 @@ public:
NS_IMETHOD RemoveSelectionListener(nsIDOMSelectionListener* aListenerToRemove);
/*END nsIDOMSelection interface implementations*/
/*BEGIN nsIScriptObjectOwner interface implementations*/
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
/*END nsIScriptObjectOwner interface implementations*/
nsRangeList();
virtual ~nsRangeList();
@ -147,9 +157,11 @@ private:
PRUint32 mBatching;
PRBool mChangesDuringBatching;
PRBool mNotifyFrames;
nsCOMPtr<nsISupportsArray> mSelectionListeners;
// for nsIScriptContextOwner
void* mScriptObject;
};
class nsRangeListIterator : public nsIBidirectionalEnumerator
@ -358,10 +370,12 @@ nsRangeListIterator::QueryInterface(REFNSIID aIID, void** aInstancePtr)
////////////END nsIRangeListIterator methods
#ifdef XP_MAC
#pragma mark -
#endif
////////////BEGIN nsRangeList methods
nsRangeList::nsRangeList()
{
NS_INIT_REFCNT();
@ -370,6 +384,7 @@ nsRangeList::nsRangeList()
mBatching = 0;
mChangesDuringBatching = PR_FALSE;
mNotifyFrames = PR_TRUE;
mScriptObject = nsnull;
}
@ -423,6 +438,12 @@ nsRangeList::QueryInterface(REFNSIID aIID, void** aInstancePtr)
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
nsIScriptObjectOwner* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIEnumeratorIID)) {
nsRangeListIterator *iterator = new nsRangeListIterator(this);
return iterator->QueryInterface(kIEnumeratorIID, aInstancePtr);
@ -542,6 +563,9 @@ nsRangeList::Clear()
#ifdef XP_MAC
#pragma mark -
#endif
//BEGIN nsIFrameSelection methods
@ -1214,11 +1238,12 @@ nsRangeList::NotifySelectionListeners()
//END nsIFrameSelection methods
//BEGIN nsIDOMSelection interface implementations
#ifdef XP_MAC
#pragma mark -
#endif
//BEGIN nsIDOMSelection interface implementations
/** ClearSelection zeroes the selection
*/
NS_IMETHODIMP
@ -1320,6 +1345,9 @@ nsRangeList::Collapse(nsIDOMNode* aParentNode, PRInt32 aOffset)
NS_IMETHODIMP
nsRangeList::GetIsCollapsed(PRBool* aIsCollapsed)
{
if (!aIsCollapsed)
return NS_ERROR_NULL_POINTER;
if (!mRangeArray || (mRangeArray->Count() == 0))
{
*aIsCollapsed = PR_TRUE;
@ -1344,6 +1372,51 @@ nsRangeList::GetIsCollapsed(PRBool* aIsCollapsed)
return (range->GetIsCollapsed(aIsCollapsed));
}
NS_IMETHODIMP
nsRangeList::GetRangeCount(PRInt32* aRangeCount)
{
if (!aRangeCount)
return NS_ERROR_NULL_POINTER;
if (mRangeArray)
{
*aRangeCount = mRangeArray->Count();
}
else
{
*aRangeCount = 0;
}
return NS_OK;
}
NS_IMETHODIMP
nsRangeList::GetRangeAt(PRInt32 aIndex, nsIDOMRange** aReturn)
{
if (!aReturn)
return NS_ERROR_NULL_POINTER;
if (!mRangeArray)
return NS_ERROR_INVALID_ARG;
if (aIndex < 0 || aIndex >= mRangeArray->Count())
return NS_ERROR_INVALID_ARG;
// the result of all this is one additional ref on the item, as
// the caller would expect.
//
// ElementAt addrefs once
// do_QueryInterface addrefs once
// when the COMPtr goes out of scope, it releases.
//
nsISupports* element = mRangeArray->ElementAt((PRUint32)aIndex);
nsCOMPtr<nsIDOMRange> foundRange = do_QueryInterface(element);
*aReturn = foundRange;
return NS_OK;
}
/*
Notes which might come in handy for extend:
@ -1520,37 +1593,34 @@ nsRangeList::DeleteFromDocument()
}
/*
* Return the anchor node and offset for the anchor point
*/
NS_IMETHODIMP
nsRangeList::GetAnchorNodeAndOffset(nsIDOMNode** outAnchorNode, PRInt32 *outAnchorOffset)
{
if (!outAnchorNode || !outAnchorOffset)
return NS_ERROR_NULL_POINTER;
//END nsIDOMSelection interface implementations
*outAnchorNode = mAnchorNode;
*outAnchorOffset = mAnchorOffset;
NS_IF_ADDREF(*outAnchorNode);
return NS_OK;
#ifdef XP_MAC
#pragma mark -
#endif
// BEGIN nsIScriptContextOwner interface implementations
NS_IMETHODIMP
nsRangeList::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
nsIScriptGlobalObject *globalObj = aContext->GetGlobalObject();
if (nsnull == mScriptObject) {
res = NS_NewScriptSelection(aContext, (nsISupports *)(nsIDOMSelection *)this, globalObj, (void**)&mScriptObject);
}
*aScriptObject = mScriptObject;
NS_RELEASE(globalObj);
return res;
}
/*
* Return the anchor node and offset for the focus point
*/
NS_IMETHODIMP
nsRangeList::GetFocusNodeAndOffset(nsIDOMNode** outFocusNode, PRInt32 *outFocusOffset)
nsRangeList::SetScriptObject(void *aScriptObject)
{
if (!outFocusNode || !outFocusOffset)
return NS_ERROR_NULL_POINTER;
*outFocusNode = mFocusNode;
*outFocusOffset = mFocusOffset;
NS_IF_ADDREF(*outFocusNode);
mScriptObject = aScriptObject;
return NS_OK;
}
//END nsIDOMSelection interface implementations
// END nsIScriptContextOwner interface implementations