1998-11-11 22:06:16 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Netscape Public License
|
|
|
|
* Version 1.0 (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/NPL/
|
|
|
|
*
|
|
|
|
* 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 Communicator client code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
|
|
|
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
|
|
|
* Netscape Communications Corporation. All Rights Reserved.
|
|
|
|
*/
|
|
|
|
#include "nsGenericElement.h"
|
|
|
|
|
1999-01-12 16:37:24 +00:00
|
|
|
#include "nsDOMAttribute.h"
|
|
|
|
#include "nsDOMAttributeMap.h"
|
1998-11-11 22:06:16 +00:00
|
|
|
#include "nsIAtom.h"
|
|
|
|
#include "nsIDocument.h"
|
|
|
|
#include "nsIDOMEventReceiver.h"
|
|
|
|
#include "nsIDOMNodeList.h"
|
1998-11-30 07:59:11 +00:00
|
|
|
#include "nsIDOMDocument.h"
|
|
|
|
#include "nsIDOMDocumentFragment.h"
|
1998-12-17 07:22:28 +00:00
|
|
|
#include "nsIDOMRange.h"
|
1999-01-25 22:17:15 +00:00
|
|
|
#include "nsIDOMText.h"
|
1998-12-30 08:28:16 +00:00
|
|
|
#include "nsRange.h"
|
1998-11-11 22:06:16 +00:00
|
|
|
#include "nsIEventListenerManager.h"
|
|
|
|
#include "nsILinkHandler.h"
|
|
|
|
#include "nsIScriptContextOwner.h"
|
|
|
|
#include "nsIScriptGlobalObject.h"
|
|
|
|
#include "nsIScriptObjectOwner.h"
|
|
|
|
#include "nsISizeOfHandler.h"
|
|
|
|
#include "nsISupportsArray.h"
|
|
|
|
#include "nsIURL.h"
|
1999-06-18 17:34:08 +00:00
|
|
|
#ifdef NECKO
|
1999-07-07 08:19:38 +00:00
|
|
|
#include "nsNeckoUtil.h"
|
1999-06-18 17:34:08 +00:00
|
|
|
#endif // NECKO
|
1998-11-11 22:06:16 +00:00
|
|
|
#include "nsFrame.h"
|
|
|
|
#include "nsIPresShell.h"
|
|
|
|
#include "nsIView.h"
|
|
|
|
#include "nsIViewManager.h"
|
|
|
|
#include "nsString.h"
|
|
|
|
#include "nsDOMEventsIIDs.h"
|
|
|
|
#include "nsIEventStateManager.h"
|
|
|
|
#include "nsDOMEvent.h"
|
|
|
|
#include "nsIPrivateDOMEvent.h"
|
|
|
|
#include "nsDOMCID.h"
|
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsIDOMScriptObjectFactory.h"
|
|
|
|
#include "nsIDOMCSSStyleDeclaration.h"
|
|
|
|
#include "nsDOMCSSDeclaration.h"
|
1998-12-11 02:35:06 +00:00
|
|
|
#include "nsINameSpaceManager.h"
|
1999-01-18 03:43:43 +00:00
|
|
|
#include "nsContentList.h"
|
1998-11-11 22:06:16 +00:00
|
|
|
#include "prprf.h"
|
|
|
|
#include "prmem.h"
|
1999-09-08 23:18:27 +00:00
|
|
|
#include "nsDOMError.h"
|
1998-11-11 22:06:16 +00:00
|
|
|
|
1999-01-25 22:17:15 +00:00
|
|
|
#include "nsLayoutAtoms.h"
|
1998-11-11 22:06:16 +00:00
|
|
|
#include "nsHTMLAtoms.h"
|
|
|
|
|
|
|
|
NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID);
|
|
|
|
NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
|
1999-01-25 22:17:15 +00:00
|
|
|
NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
|
1998-11-11 22:06:16 +00:00
|
|
|
NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID);
|
1999-03-28 22:22:54 +00:00
|
|
|
NS_DEFINE_IID(kIDOMEventTargetIID, NS_IDOMEVENTTARGET_IID);
|
1998-11-11 22:06:16 +00:00
|
|
|
NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
|
|
|
|
NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID);
|
|
|
|
NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
|
|
NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID);
|
|
|
|
|
|
|
|
static NS_DEFINE_IID(kIDOMAttrIID, NS_IDOMATTR_IID);
|
|
|
|
static NS_DEFINE_IID(kIDOMNamedNodeMapIID, NS_IDOMNAMEDNODEMAP_IID);
|
|
|
|
static NS_DEFINE_IID(kIPrivateDOMEventIID, NS_IPRIVATEDOMEVENT_IID);
|
|
|
|
static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID);
|
|
|
|
static NS_DEFINE_IID(kIDOMCSSStyleDeclarationIID, NS_IDOMCSSSTYLEDECLARATION_IID);
|
1998-11-30 07:59:11 +00:00
|
|
|
static NS_DEFINE_IID(kIDOMDocumentIID, NS_IDOMDOCUMENT_IID);
|
|
|
|
static NS_DEFINE_IID(kIDOMDocumentFragmentIID, NS_IDOMDOCUMENTFRAGMENT_IID);
|
1998-11-11 22:06:16 +00:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
nsChildContentList::nsChildContentList(nsIContent *aContent)
|
|
|
|
{
|
|
|
|
// This reference is not reference-counted. The content
|
|
|
|
// object tells us when its about to go away.
|
|
|
|
mContent = aContent;
|
|
|
|
}
|
|
|
|
|
1999-02-12 17:45:58 +00:00
|
|
|
nsChildContentList::~nsChildContentList()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
1998-11-11 22:06:16 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsChildContentList::GetLength(PRUint32* aLength)
|
|
|
|
{
|
|
|
|
if (nsnull != mContent) {
|
|
|
|
PRInt32 length;
|
|
|
|
mContent->ChildCount(length);
|
|
|
|
*aLength = (PRUint32)length;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aLength = 0;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsChildContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
|
|
|
|
{
|
|
|
|
nsIContent *content;
|
|
|
|
nsresult res = NS_OK;
|
|
|
|
|
|
|
|
if (nsnull != mContent) {
|
|
|
|
mContent->ChildAt(aIndex, content);
|
|
|
|
if (nsnull != content) {
|
|
|
|
res = content->QueryInterface(kIDOMNodeIID, (void**)aReturn);
|
|
|
|
NS_RELEASE(content);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aReturn = nsnull;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aReturn = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsChildContentList::DropReference()
|
|
|
|
{
|
|
|
|
mContent = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
// XXX Currently, the script object factory is global. The way we
|
|
|
|
// obtain it should, at least, be made thread-safe later. Ideally,
|
|
|
|
// we'd find a better way.
|
|
|
|
nsIDOMScriptObjectFactory* nsGenericElement::gScriptObjectFactory = nsnull;
|
|
|
|
|
|
|
|
static NS_DEFINE_IID(kIDOMScriptObjectFactoryIID, NS_IDOM_SCRIPT_OBJECT_FACTORY_IID);
|
|
|
|
static NS_DEFINE_IID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetScriptObjectFactory(nsIDOMScriptObjectFactory **aResult)
|
|
|
|
{
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
|
|
|
if (nsnull == gScriptObjectFactory) {
|
|
|
|
result = nsServiceManager::GetService(kDOMScriptObjectFactoryCID,
|
|
|
|
kIDOMScriptObjectFactoryIID,
|
|
|
|
(nsISupports **)&gScriptObjectFactory);
|
|
|
|
if (result != NS_OK) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*aResult = gScriptObjectFactory;
|
|
|
|
NS_ADDREF(gScriptObjectFactory);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsGenericElement::nsGenericElement()
|
|
|
|
{
|
|
|
|
mDocument = nsnull;
|
|
|
|
mParent = nsnull;
|
|
|
|
mTag = nsnull;
|
|
|
|
mContent = nsnull;
|
|
|
|
mDOMSlots = nsnull;
|
|
|
|
mListenerManager = nsnull;
|
1999-08-31 10:06:17 +00:00
|
|
|
mContentID = 0;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsGenericElement::~nsGenericElement()
|
|
|
|
{
|
1998-12-30 08:28:16 +00:00
|
|
|
// pop any enclosed ranges out
|
|
|
|
// nsRange::OwnerGone(mContent); not used for now
|
1998-11-11 22:06:16 +00:00
|
|
|
NS_IF_RELEASE(mTag);
|
|
|
|
NS_IF_RELEASE(mListenerManager);
|
|
|
|
if (nsnull != mDOMSlots) {
|
|
|
|
if (nsnull != mDOMSlots->mChildNodes) {
|
|
|
|
mDOMSlots->mChildNodes->DropReference();
|
|
|
|
NS_RELEASE(mDOMSlots->mChildNodes);
|
1998-12-18 02:51:34 +00:00
|
|
|
delete mDOMSlots->mRangeList;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
if (nsnull != mDOMSlots->mStyle) {
|
|
|
|
mDOMSlots->mStyle->DropReference();
|
|
|
|
NS_RELEASE(mDOMSlots->mStyle);
|
|
|
|
}
|
1999-01-12 16:37:24 +00:00
|
|
|
if (nsnull != mDOMSlots->mAttributeMap) {
|
|
|
|
mDOMSlots->mAttributeMap->DropReference();
|
|
|
|
NS_RELEASE(mDOMSlots->mAttributeMap);
|
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
// XXX Should really be arena managed
|
|
|
|
PR_DELETE(mDOMSlots);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsDOMSlots *
|
|
|
|
nsGenericElement::GetDOMSlots()
|
|
|
|
{
|
|
|
|
if (nsnull == mDOMSlots) {
|
|
|
|
mDOMSlots = PR_NEW(nsDOMSlots);
|
|
|
|
mDOMSlots->mScriptObject = nsnull;
|
|
|
|
mDOMSlots->mChildNodes = nsnull;
|
|
|
|
mDOMSlots->mStyle = nsnull;
|
1999-01-12 16:37:24 +00:00
|
|
|
mDOMSlots->mAttributeMap = nsnull;
|
1998-12-18 02:51:34 +00:00
|
|
|
mDOMSlots->mRangeList = nsnull;
|
1999-03-28 22:22:54 +00:00
|
|
|
mDOMSlots->mCapturer = nsnull;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return mDOMSlots;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsGenericElement::Init(nsIContent* aOuterContentObject,
|
|
|
|
nsIAtom* aTag)
|
|
|
|
{
|
|
|
|
NS_ASSERTION((nsnull == mContent) && (nsnull != aOuterContentObject),
|
|
|
|
"null ptr");
|
|
|
|
mContent = aOuterContentObject;
|
|
|
|
mTag = aTag;
|
|
|
|
NS_IF_ADDREF(aTag);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetNodeName(nsString& aNodeName)
|
|
|
|
{
|
|
|
|
return GetTagName(aNodeName);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetNodeValue(nsString& aNodeValue)
|
|
|
|
{
|
|
|
|
aNodeValue.Truncate();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::SetNodeValue(const nsString& aNodeValue)
|
|
|
|
{
|
1999-09-08 23:18:27 +00:00
|
|
|
// The node value can't be modified
|
|
|
|
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetNodeType(PRUint16* aNodeType)
|
|
|
|
{
|
|
|
|
*aNodeType = (PRUint16)nsIDOMNode::ELEMENT_NODE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetParentNode(nsIDOMNode** aParentNode)
|
|
|
|
{
|
1999-04-17 00:56:25 +00:00
|
|
|
nsresult res = NS_OK;
|
|
|
|
|
1998-11-11 22:06:16 +00:00
|
|
|
if (nsnull != mParent) {
|
1999-04-17 00:56:25 +00:00
|
|
|
res = mParent->QueryInterface(kIDOMNodeIID, (void**)aParentNode);
|
1998-11-11 22:06:16 +00:00
|
|
|
NS_ASSERTION(NS_OK == res, "Must be a DOM Node");
|
|
|
|
}
|
1999-01-19 03:54:26 +00:00
|
|
|
else if (nsnull == mDocument) {
|
1999-04-17 00:56:25 +00:00
|
|
|
*aParentNode = nsnull;
|
1999-01-19 03:54:26 +00:00
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
else {
|
1999-01-19 03:54:26 +00:00
|
|
|
// If we don't have a parent, but we're in the document, we must
|
|
|
|
// be the root node of the document. The DOM says that the root
|
|
|
|
// is the document.
|
1999-04-17 00:56:25 +00:00
|
|
|
res = mDocument->QueryInterface(kIDOMNodeIID, (void**)aParentNode);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
1999-04-17 00:56:25 +00:00
|
|
|
|
|
|
|
return res;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-03-31 20:49:25 +00:00
|
|
|
nsGenericElement::GetPreviousSibling(nsIDOMNode** aPrevSibling)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
1999-03-31 20:49:25 +00:00
|
|
|
nsIContent* sibling = nsnull;
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
1998-11-11 22:06:16 +00:00
|
|
|
if (nsnull != mParent) {
|
|
|
|
PRInt32 pos;
|
|
|
|
mParent->IndexOf(mContent, pos);
|
1999-03-31 20:49:25 +00:00
|
|
|
if (pos > -1 ) {
|
|
|
|
mParent->ChildAt(--pos, sibling);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
}
|
1999-03-31 20:49:25 +00:00
|
|
|
else if (nsnull != mDocument) {
|
|
|
|
// Nodes that are just below the document (their parent is the
|
|
|
|
// document) need to go to the document to find their next sibling.
|
|
|
|
PRInt32 pos;
|
|
|
|
mDocument->IndexOf(mContent, pos);
|
|
|
|
if (pos > -1 ) {
|
|
|
|
mDocument->ChildAt(--pos, sibling);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nsnull != sibling) {
|
|
|
|
result = sibling->QueryInterface(kIDOMNodeIID,(void**)aPrevSibling);
|
|
|
|
NS_ASSERTION(NS_OK == result, "Must be a DOM Node");
|
|
|
|
NS_RELEASE(sibling); // balance the AddRef in ChildAt()
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aPrevSibling = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetNextSibling(nsIDOMNode** aNextSibling)
|
|
|
|
{
|
1999-03-31 20:49:25 +00:00
|
|
|
nsIContent* sibling = nsnull;
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
1998-11-11 22:06:16 +00:00
|
|
|
if (nsnull != mParent) {
|
|
|
|
PRInt32 pos;
|
|
|
|
mParent->IndexOf(mContent, pos);
|
|
|
|
if (pos > -1 ) {
|
1999-03-31 20:49:25 +00:00
|
|
|
mParent->ChildAt(++pos, sibling);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
}
|
1999-03-31 20:49:25 +00:00
|
|
|
else if (nsnull != mDocument) {
|
|
|
|
// Nodes that are just below the document (their parent is the
|
|
|
|
// document) need to go to the document to find their next sibling.
|
|
|
|
PRInt32 pos;
|
|
|
|
mDocument->IndexOf(mContent, pos);
|
|
|
|
if (pos > -1 ) {
|
|
|
|
mDocument->ChildAt(++pos, sibling);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nsnull != sibling) {
|
|
|
|
result = sibling->QueryInterface(kIDOMNodeIID,(void**)aNextSibling);
|
|
|
|
NS_ASSERTION(NS_OK == result, "Must be a DOM Node");
|
|
|
|
NS_RELEASE(sibling); // balance the AddRef in ChildAt()
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aNextSibling = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
|
|
|
|
{
|
|
|
|
// XXX Actually the owner document is the document in whose context
|
|
|
|
// the element has been created. We should be able to get at it
|
|
|
|
// whether or not we are attached to the document.
|
|
|
|
if (nsnull != mDocument) {
|
|
|
|
return mDocument->QueryInterface(kIDOMDocumentIID, (void **)aOwnerDocument);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aOwnerDocument = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetAttributes(nsIDOMNamedNodeMap** aAttributes)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aAttributes, "null pointer argument");
|
1999-01-12 16:37:24 +00:00
|
|
|
nsDOMSlots *slots = GetDOMSlots();
|
1998-11-11 22:06:16 +00:00
|
|
|
|
1999-01-12 16:37:24 +00:00
|
|
|
if (nsnull == slots->mAttributeMap) {
|
|
|
|
slots->mAttributeMap = new nsDOMAttributeMap(mContent);
|
|
|
|
if (nsnull == slots->mAttributeMap) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
NS_ADDREF(slots->mAttributeMap);
|
|
|
|
}
|
|
|
|
|
|
|
|
return slots->mAttributeMap->QueryInterface(kIDOMNamedNodeMapIID,
|
|
|
|
(void **)aAttributes);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetTagName(nsString& aTagName)
|
|
|
|
{
|
|
|
|
aTagName.Truncate();
|
|
|
|
if (nsnull != mTag) {
|
1998-12-20 01:21:23 +00:00
|
|
|
// note that we assume no namespace here, subclasses that support
|
|
|
|
// namespaces must override
|
1998-11-11 22:06:16 +00:00
|
|
|
mTag->ToString(aTagName);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-01-12 16:37:24 +00:00
|
|
|
nsGenericElement::GetAttribute(const nsString& aName, nsString& aReturn)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
1999-01-12 16:37:24 +00:00
|
|
|
nsIAtom* nameAtom;
|
|
|
|
PRInt32 nameSpaceID;
|
|
|
|
|
|
|
|
mContent->ParseAttributeString(aName, nameAtom, nameSpaceID);
|
1999-06-10 05:18:46 +00:00
|
|
|
if (kNameSpaceID_Unknown == nameSpaceID) {
|
|
|
|
nameSpaceID = kNameSpaceID_None; // ignore unknown prefix XXX is this correct?
|
|
|
|
}
|
1999-01-12 16:37:24 +00:00
|
|
|
mContent->GetAttribute(nameSpaceID, nameAtom, aReturn);
|
1998-12-20 01:21:23 +00:00
|
|
|
NS_RELEASE(nameAtom);
|
1999-01-12 16:37:24 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-01-12 16:37:24 +00:00
|
|
|
nsGenericElement::SetAttribute(const nsString& aName,
|
|
|
|
const nsString& aValue)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
1999-01-12 16:37:24 +00:00
|
|
|
nsIAtom* nameAtom;
|
|
|
|
PRInt32 nameSpaceID;
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
|
|
|
mContent->ParseAttributeString(aName, nameAtom, nameSpaceID);
|
1999-06-10 05:18:46 +00:00
|
|
|
if (kNameSpaceID_Unknown == nameSpaceID) {
|
|
|
|
nameSpaceID = kNameSpaceID_None; // ignore unknown prefix XXX is this correct?
|
|
|
|
}
|
1999-01-12 16:37:24 +00:00
|
|
|
result = mContent->SetAttribute(nameSpaceID, nameAtom, aValue, PR_TRUE);
|
1998-12-20 01:21:23 +00:00
|
|
|
NS_RELEASE(nameAtom);
|
1999-01-12 16:37:24 +00:00
|
|
|
|
|
|
|
return result;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::RemoveAttribute(const nsString& aName)
|
|
|
|
{
|
1999-01-12 16:37:24 +00:00
|
|
|
nsIAtom* nameAtom;
|
|
|
|
PRInt32 nameSpaceID;
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
|
|
|
mContent->ParseAttributeString(aName, nameAtom, nameSpaceID);
|
1999-06-10 05:18:46 +00:00
|
|
|
if (kNameSpaceID_Unknown == nameSpaceID) {
|
|
|
|
nameSpaceID = kNameSpaceID_None; // ignore unknown prefix XXX is this correct?
|
|
|
|
}
|
1999-01-12 16:37:24 +00:00
|
|
|
result = mContent->UnsetAttribute(nameSpaceID, nameAtom, PR_TRUE);
|
1998-12-20 01:21:23 +00:00
|
|
|
NS_RELEASE(nameAtom);
|
1999-01-12 16:37:24 +00:00
|
|
|
|
|
|
|
return result;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetAttributeNode(const nsString& aName,
|
1998-12-20 01:21:23 +00:00
|
|
|
nsIDOMAttr** aReturn)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
1999-01-12 16:37:24 +00:00
|
|
|
if (nsnull == aReturn) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
1999-01-12 16:37:24 +00:00
|
|
|
nsIDOMNamedNodeMap* map;
|
|
|
|
nsresult result = GetAttributes(&map);
|
|
|
|
|
|
|
|
*aReturn = nsnull;
|
|
|
|
if (NS_OK == result) {
|
|
|
|
nsIDOMNode* node;
|
|
|
|
result = map->GetNamedItem(aName, &node);
|
|
|
|
if ((NS_OK == result) && (nsnull != node)) {
|
|
|
|
result = node->QueryInterface(kIDOMAttrIID, (void **)aReturn);
|
|
|
|
NS_IF_RELEASE(node);
|
|
|
|
}
|
|
|
|
NS_RELEASE(map);
|
1998-12-20 01:21:23 +00:00
|
|
|
}
|
1999-01-12 16:37:24 +00:00
|
|
|
|
|
|
|
return result;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::SetAttributeNode(nsIDOMAttr* aAttribute,
|
1999-01-12 16:37:24 +00:00
|
|
|
nsIDOMAttr** aReturn)
|
|
|
|
{
|
|
|
|
if ((nsnull == aReturn) || (nsnull == aAttribute)) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
nsIDOMNamedNodeMap* map;
|
|
|
|
nsresult result = GetAttributes(&map);
|
|
|
|
|
|
|
|
*aReturn = nsnull;
|
|
|
|
if (NS_OK == result) {
|
|
|
|
nsIDOMNode *node, *returnNode;
|
|
|
|
result = aAttribute->QueryInterface(kIDOMNodeIID, (void **)&node);
|
|
|
|
if (NS_OK == result) {
|
|
|
|
result = map->SetNamedItem(node, &returnNode);
|
|
|
|
if ((NS_OK == result) && (nsnull != returnNode)) {
|
|
|
|
result = returnNode->QueryInterface(kIDOMAttrIID, (void **)aReturn);
|
|
|
|
NS_IF_RELEASE(returnNode);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
1999-01-12 16:37:24 +00:00
|
|
|
NS_RELEASE(node);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
1999-01-12 16:37:24 +00:00
|
|
|
NS_RELEASE(map);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
1999-01-12 16:37:24 +00:00
|
|
|
|
|
|
|
return result;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::RemoveAttributeNode(nsIDOMAttr* aAttribute,
|
1999-01-12 16:37:24 +00:00
|
|
|
nsIDOMAttr** aReturn)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
1999-01-12 16:37:24 +00:00
|
|
|
if ((nsnull == aReturn) || (nsnull == aAttribute)) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
nsIDOMNamedNodeMap* map;
|
|
|
|
nsresult result = GetAttributes(&map);
|
1998-11-11 22:06:16 +00:00
|
|
|
|
1999-01-12 16:37:24 +00:00
|
|
|
*aReturn = nsnull;
|
|
|
|
if (NS_OK == result) {
|
1998-11-11 22:06:16 +00:00
|
|
|
nsAutoString name;
|
1999-01-12 16:37:24 +00:00
|
|
|
|
|
|
|
result = aAttribute->GetName(name);
|
|
|
|
if (NS_OK == result) {
|
|
|
|
nsIDOMNode* node;
|
|
|
|
result = map->RemoveNamedItem(name, &node);
|
|
|
|
if ((NS_OK == result) && (nsnull != node)) {
|
|
|
|
result = node->QueryInterface(kIDOMAttrIID, (void **)aReturn);
|
|
|
|
NS_RELEASE(node);
|
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
1999-01-12 16:37:24 +00:00
|
|
|
NS_RELEASE(map);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
1999-01-12 16:37:24 +00:00
|
|
|
return result;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetElementsByTagName(const nsString& aTagname,
|
1999-01-15 19:18:30 +00:00
|
|
|
nsIDOMNodeList** aReturn)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
1999-01-18 03:43:43 +00:00
|
|
|
nsIAtom* nameAtom;
|
|
|
|
PRInt32 nameSpaceId;
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
|
|
|
result = mContent->ParseAttributeString(aTagname, nameAtom,
|
|
|
|
nameSpaceId);
|
|
|
|
if (NS_OK != result) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsContentList* list = new nsContentList(mDocument,
|
|
|
|
nameAtom,
|
|
|
|
nameSpaceId,
|
|
|
|
mContent);
|
|
|
|
NS_IF_RELEASE(nameAtom);
|
|
|
|
if (nsnull == list) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
return list->QueryInterface(kIDOMNodeListIID, (void **)aReturn);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
1999-01-25 22:17:15 +00:00
|
|
|
nsresult
|
|
|
|
nsGenericElement::JoinTextNodes(nsIContent* aFirst,
|
|
|
|
nsIContent* aSecond)
|
|
|
|
{
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
nsIDOMText *firstText, *secondText;
|
|
|
|
|
|
|
|
result = aFirst->QueryInterface(kIDOMTextIID, (void**)&firstText);
|
|
|
|
if (NS_OK == result) {
|
|
|
|
result = aSecond->QueryInterface(kIDOMTextIID, (void**)&secondText);
|
|
|
|
|
|
|
|
if (NS_OK == result) {
|
|
|
|
nsAutoString str;
|
|
|
|
|
|
|
|
result = secondText->GetData(str);
|
|
|
|
if (NS_OK == result) {
|
|
|
|
result = firstText->AppendData(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_RELEASE(secondText);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_RELEASE(firstText);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1998-11-11 22:06:16 +00:00
|
|
|
nsresult
|
|
|
|
nsGenericElement::Normalize()
|
|
|
|
{
|
1999-01-25 22:17:15 +00:00
|
|
|
nsresult result = NS_OK;
|
|
|
|
PRInt32 index, count;
|
|
|
|
|
|
|
|
mContent->ChildCount(count);
|
|
|
|
for (index = 0; (index < count) && (NS_OK == result); index++) {
|
|
|
|
nsIContent* child;
|
|
|
|
nsIAtom* name;
|
|
|
|
|
|
|
|
result = mContent->ChildAt(index, child);
|
|
|
|
if (NS_OK == result) {
|
|
|
|
child->GetTag(name);
|
|
|
|
|
|
|
|
// If this is a text node and there's a sibling following it
|
|
|
|
if ((name == nsLayoutAtoms::textTagName) && (index < count-1)) {
|
|
|
|
nsIContent* sibling;
|
|
|
|
|
|
|
|
// Get the sibling. If it's also a text node, then
|
|
|
|
// remove it from the tree and join the two text
|
|
|
|
// nodes.
|
|
|
|
result = mContent->ChildAt(index+1, sibling);
|
|
|
|
if (NS_OK == result) {
|
|
|
|
nsIAtom* siblingName;
|
|
|
|
|
|
|
|
sibling->GetTag(siblingName);
|
|
|
|
if (siblingName == nsLayoutAtoms::textTagName) {
|
|
|
|
result = mContent->RemoveChildAt(index+1, PR_TRUE);
|
|
|
|
if (NS_OK == result) {
|
|
|
|
result = JoinTextNodes(child, sibling);
|
|
|
|
count--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IF_RELEASE(siblingName);
|
|
|
|
NS_RELEASE(sibling);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
nsIDOMElement* element;
|
|
|
|
nsresult qiresult;
|
|
|
|
|
|
|
|
qiresult = child->QueryInterface(kIDOMElementIID, (void**)&element);
|
|
|
|
if (NS_OK == qiresult) {
|
|
|
|
result = element->Normalize();
|
|
|
|
NS_RELEASE(element);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IF_RELEASE(name);
|
|
|
|
NS_RELEASE(child);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetDocument(nsIDocument*& aResult) const
|
|
|
|
{
|
|
|
|
NS_IF_ADDREF(mDocument);
|
|
|
|
aResult = mDocument;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
nsGenericElement::SetDocumentInChildrenOf(nsIContent* aContent,
|
1998-11-30 07:59:11 +00:00
|
|
|
nsIDocument* aDocument)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
|
|
|
PRInt32 i, n;
|
|
|
|
aContent->ChildCount(n);
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
nsIContent* child;
|
|
|
|
aContent->ChildAt(i, child);
|
|
|
|
if (nsnull != child) {
|
|
|
|
child->SetDocument(aDocument, PR_TRUE);
|
|
|
|
NS_RELEASE(child);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::SetDocument(nsIDocument* aDocument, PRBool aDeep)
|
|
|
|
{
|
|
|
|
// If we were part of a document, make sure we get rid of the
|
|
|
|
// script context reference to our script object so that our
|
|
|
|
// script object can be freed (or collected).
|
|
|
|
if ((nsnull != mDocument) && (nsnull != mDOMSlots) &&
|
|
|
|
(nsnull != mDOMSlots->mScriptObject)) {
|
|
|
|
nsIScriptContextOwner *owner = mDocument->GetScriptContextOwner();
|
|
|
|
if (nsnull != owner) {
|
|
|
|
nsIScriptContext *context;
|
|
|
|
if (NS_OK == owner->GetScriptContext(&context)) {
|
|
|
|
context->RemoveReference((void *)&mDOMSlots->mScriptObject,
|
|
|
|
mDOMSlots->mScriptObject);
|
|
|
|
NS_RELEASE(context);
|
|
|
|
}
|
|
|
|
NS_RELEASE(owner);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mDocument = aDocument;
|
|
|
|
|
|
|
|
// If we already have a script object and now we're being added
|
|
|
|
// to a document, make sure that the script context adds a
|
|
|
|
// reference to our script object. This will ensure that it
|
|
|
|
// won't be freed (or collected) out from under us.
|
|
|
|
if ((nsnull != mDocument) && (nsnull != mDOMSlots) &&
|
|
|
|
(nsnull != mDOMSlots->mScriptObject)) {
|
|
|
|
nsIScriptContextOwner *owner = mDocument->GetScriptContextOwner();
|
|
|
|
if (nsnull != owner) {
|
|
|
|
nsIScriptContext *context;
|
|
|
|
if (NS_OK == owner->GetScriptContext(&context)) {
|
|
|
|
nsAutoString tag;
|
|
|
|
char tagBuf[50];
|
|
|
|
|
|
|
|
mTag->ToString(tag);
|
|
|
|
tag.ToCString(tagBuf, sizeof(tagBuf));
|
|
|
|
context->AddNamedReference((void *)&mDOMSlots->mScriptObject,
|
|
|
|
mDOMSlots->mScriptObject,
|
|
|
|
tagBuf);
|
|
|
|
NS_RELEASE(context);
|
|
|
|
}
|
|
|
|
NS_RELEASE(owner);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PR_TRUE == aDeep) {
|
|
|
|
SetDocumentInChildrenOf(mContent, aDocument);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetParent(nsIContent*& aResult) const
|
|
|
|
{
|
|
|
|
NS_IF_ADDREF(mParent);
|
|
|
|
aResult = mParent;
|
1999-09-15 20:30:36 +00:00
|
|
|
return NS_OK;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::SetParent(nsIContent* aParent)
|
|
|
|
{
|
|
|
|
mParent = aParent;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-12-11 02:35:06 +00:00
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetNameSpaceID(PRInt32& aResult) const
|
|
|
|
{
|
|
|
|
aResult = kNameSpaceID_None;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-11-11 22:06:16 +00:00
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetTag(nsIAtom*& aResult) const
|
|
|
|
{
|
|
|
|
NS_IF_ADDREF(mTag);
|
|
|
|
aResult = mTag;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::HandleDOMEvent(nsIPresContext& aPresContext,
|
1999-09-15 20:30:36 +00:00
|
|
|
nsEvent* aEvent,
|
|
|
|
nsIDOMEvent** aDOMEvent,
|
|
|
|
PRUint32 aFlags,
|
|
|
|
nsEventStatus& aEventStatus)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
|
|
|
nsresult ret = NS_OK;
|
|
|
|
|
|
|
|
nsIDOMEvent* domEvent = nsnull;
|
1999-03-28 22:22:54 +00:00
|
|
|
if (NS_EVENT_FLAG_INIT == aFlags) {
|
1998-11-11 22:06:16 +00:00
|
|
|
aDOMEvent = &domEvent;
|
1999-07-19 19:54:34 +00:00
|
|
|
aEvent->flags = NS_EVENT_FLAG_NONE;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
1999-03-28 22:22:54 +00:00
|
|
|
//Capturing stage evaluation
|
|
|
|
//Always pass capturing up the tree before local evaulation
|
|
|
|
if (NS_EVENT_FLAG_BUBBLE != aFlags) {
|
1999-09-23 02:31:37 +00:00
|
|
|
// XXX: Bring on the more optimized version of capturing at some point
|
|
|
|
//if (nsnull != mDOMSlots && nsnull != mDOMSlots->mCapturer) {
|
|
|
|
//mDOMSlots->mCapturer->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_CAPTURE, aEventStatus);
|
|
|
|
//} else {
|
1999-09-23 01:55:41 +00:00
|
|
|
// Node capturing stage
|
|
|
|
if (mParent) {
|
|
|
|
// Pass off to our parent.
|
|
|
|
mParent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_CAPTURE, aEventStatus);
|
1999-09-23 02:31:37 +00:00
|
|
|
} else {
|
|
|
|
//Initiate capturing phase. Special case first call to document
|
|
|
|
if (nsnull != mDocument) {
|
|
|
|
mDocument->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_CAPTURE, aEventStatus);
|
|
|
|
}
|
1999-09-23 01:55:41 +00:00
|
|
|
}
|
1999-09-23 02:31:37 +00:00
|
|
|
//}
|
1999-03-28 22:22:54 +00:00
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
|
|
|
|
//Local handling stage
|
1999-07-19 19:54:34 +00:00
|
|
|
if (mListenerManager && !(aEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH)) {
|
|
|
|
aEvent->flags = aFlags;
|
1999-03-28 22:22:54 +00:00
|
|
|
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//Bubbling stage
|
1999-07-19 19:54:34 +00:00
|
|
|
if ((NS_EVENT_FLAG_CAPTURE != aFlags) &&
|
|
|
|
(mParent != nsnull) && (mDocument != nsnull)) {
|
1998-11-11 22:06:16 +00:00
|
|
|
ret = mParent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
|
1999-03-28 22:22:54 +00:00
|
|
|
NS_EVENT_FLAG_BUBBLE, aEventStatus);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
1999-03-28 22:22:54 +00:00
|
|
|
if (NS_EVENT_FLAG_INIT == aFlags) {
|
1998-11-11 22:06:16 +00:00
|
|
|
// We're leaving the DOM event loop so if we created a DOM event,
|
|
|
|
// release here.
|
|
|
|
if (nsnull != *aDOMEvent) {
|
|
|
|
nsrefcnt rc;
|
|
|
|
NS_RELEASE2(*aDOMEvent, rc);
|
|
|
|
if (0 != rc) {
|
|
|
|
// Okay, so someone in the DOM loop (a listener, JS object)
|
|
|
|
// still has a ref to the DOM Event but the internal data
|
|
|
|
// hasn't been malloc'd. Force a copy of the data here so the
|
|
|
|
// DOM Event is still valid.
|
|
|
|
nsIPrivateDOMEvent *privateEvent;
|
|
|
|
if (NS_OK == (*aDOMEvent)->QueryInterface(kIPrivateDOMEventIID, (void**)&privateEvent)) {
|
|
|
|
privateEvent->DuplicatePrivateData();
|
|
|
|
NS_RELEASE(privateEvent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
aDOMEvent = nsnull;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
1998-12-17 07:22:28 +00:00
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::RangeAdd(nsIDOMRange& aRange)
|
|
|
|
{
|
1998-12-18 02:51:34 +00:00
|
|
|
if (nsnull == mDOMSlots) GetDOMSlots();
|
1998-12-17 07:22:28 +00:00
|
|
|
// lazy allocation of range list
|
1998-12-18 02:51:34 +00:00
|
|
|
if (nsnull == mDOMSlots->mRangeList) {
|
|
|
|
mDOMSlots->mRangeList = new nsVoidArray();
|
1998-12-17 07:22:28 +00:00
|
|
|
}
|
1998-12-18 02:51:34 +00:00
|
|
|
if (nsnull == mDOMSlots->mRangeList) {
|
1998-12-17 07:22:28 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
1999-08-04 18:36:19 +00:00
|
|
|
|
|
|
|
// Make sure we don't add a range that is already
|
|
|
|
// in the list!
|
|
|
|
PRInt32 i = mDOMSlots->mRangeList->IndexOf(&aRange);
|
|
|
|
if (i >= 0) {
|
|
|
|
// Range is already in the list, so there
|
|
|
|
// is nothing to do!
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-12-17 07:22:28 +00:00
|
|
|
// dont need to addref - this call is made by the range object itself
|
1998-12-18 02:51:34 +00:00
|
|
|
PRBool rv = mDOMSlots->mRangeList->AppendElement(&aRange);
|
1998-12-17 07:22:28 +00:00
|
|
|
if (rv) return NS_OK;
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::RangeRemove(nsIDOMRange& aRange)
|
|
|
|
{
|
1998-12-18 02:51:34 +00:00
|
|
|
if (mDOMSlots && mDOMSlots->mRangeList) {
|
1998-12-17 07:22:28 +00:00
|
|
|
// dont need to release - this call is made by the range object itself
|
1998-12-18 02:51:34 +00:00
|
|
|
PRBool rv = mDOMSlots->mRangeList->RemoveElement(&aRange);
|
|
|
|
if (rv) {
|
|
|
|
if (mDOMSlots->mRangeList->Count() == 0) {
|
|
|
|
delete mDOMSlots->mRangeList;
|
1999-01-04 16:48:33 +00:00
|
|
|
mDOMSlots->mRangeList = nsnull;
|
1998-12-18 02:51:34 +00:00
|
|
|
if ( (mDOMSlots->mScriptObject == nsnull) &&
|
|
|
|
(mDOMSlots->mChildNodes == nsnull) &&
|
|
|
|
(mDOMSlots->mStyle == nsnull) ) {
|
|
|
|
PR_DELETE(mDOMSlots);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1998-12-17 07:22:28 +00:00
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
|
1998-12-18 02:51:34 +00:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetRangeList(nsVoidArray*& aResult) const
|
|
|
|
{
|
|
|
|
if (mDOMSlots && mDOMSlots->mRangeList) {
|
|
|
|
aResult = mDOMSlots->mRangeList;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
aResult = nsnull;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-10-05 23:47:46 +00:00
|
|
|
nsresult
|
|
|
|
nsGenericElement::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult,
|
|
|
|
size_t aInstanceSize) const
|
|
|
|
{
|
|
|
|
if (!aResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
|
|
*aResult = (PRUint32) aInstanceSize;
|
|
|
|
#else
|
|
|
|
*aResult = 0;
|
|
|
|
#endif
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-11-11 22:06:16 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
nsresult
|
1999-10-26 04:44:41 +00:00
|
|
|
nsGenericElement::RenderFrame(nsIPresContext* aPresContext)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
|
|
|
nsPoint offset;
|
|
|
|
nsRect bounds;
|
|
|
|
|
|
|
|
// Trigger damage repairs for each frame that maps the given content
|
|
|
|
PRInt32 i, n;
|
|
|
|
n = mDocument->GetNumberOfShells();
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
nsIPresShell* shell;
|
|
|
|
shell = mDocument->GetShellAt(i);
|
|
|
|
nsIFrame* frame;
|
1999-02-12 17:45:58 +00:00
|
|
|
shell->GetPrimaryFrameFor(mContent, &frame);
|
1998-11-11 22:06:16 +00:00
|
|
|
while (nsnull != frame) {
|
|
|
|
nsIViewManager* vm;
|
|
|
|
nsIView* view;
|
|
|
|
|
|
|
|
// Determine damaged area and tell view manager to redraw it
|
|
|
|
frame->GetRect(bounds);
|
|
|
|
bounds.x = bounds.y = 0;
|
|
|
|
|
|
|
|
// XXX We should tell the frame the damage area and let it invalidate
|
|
|
|
// itself. Add some API calls to nsIFrame to allow a caller to invalidate
|
|
|
|
// parts of the frame...
|
1999-10-26 04:44:41 +00:00
|
|
|
frame->GetOffsetFromView(aPresContext, offset, &view);
|
1998-11-11 22:06:16 +00:00
|
|
|
view->GetViewManager(vm);
|
|
|
|
bounds.x += offset.x;
|
|
|
|
bounds.y += offset.y;
|
|
|
|
|
|
|
|
vm->UpdateView(view, bounds, NS_VMREFRESH_IMMEDIATE);
|
|
|
|
NS_RELEASE(vm);
|
|
|
|
|
|
|
|
// If frame has a next-in-flow, repaint it too
|
1999-02-24 04:48:08 +00:00
|
|
|
frame->GetNextInFlow(&frame);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
NS_RELEASE(shell);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
// nsIScriptObjectOwner implementation
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetScriptObject(nsIScriptContext* aContext,
|
|
|
|
void** aScriptObject)
|
|
|
|
{
|
|
|
|
nsresult res = NS_OK;
|
|
|
|
nsDOMSlots *slots = GetDOMSlots();
|
|
|
|
|
|
|
|
if (nsnull == slots->mScriptObject) {
|
|
|
|
nsIDOMScriptObjectFactory *factory;
|
|
|
|
|
|
|
|
res = GetScriptObjectFactory(&factory);
|
|
|
|
if (NS_OK != res) {
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoString tag;
|
|
|
|
mTag->ToString(tag);
|
|
|
|
res = factory->NewScriptElement(tag, aContext, mContent,
|
|
|
|
mParent, (void**)&slots->mScriptObject);
|
|
|
|
NS_RELEASE(factory);
|
|
|
|
|
|
|
|
char tagBuf[50];
|
|
|
|
tag.ToCString(tagBuf, sizeof(tagBuf));
|
|
|
|
if (nsnull != mDocument) {
|
|
|
|
aContext->AddNamedReference((void *)&slots->mScriptObject,
|
|
|
|
slots->mScriptObject,
|
|
|
|
tagBuf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*aScriptObject = slots->mScriptObject;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::SetScriptObject(void *aScriptObject)
|
|
|
|
{
|
|
|
|
nsDOMSlots *slots = GetDOMSlots();
|
|
|
|
|
|
|
|
slots->mScriptObject = aScriptObject;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
// nsIDOMEventReceiver implementation
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetListenerManager(nsIEventListenerManager** aResult)
|
|
|
|
{
|
|
|
|
if (nsnull != mListenerManager) {
|
|
|
|
NS_ADDREF(mListenerManager);
|
|
|
|
*aResult = mListenerManager;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
nsresult rv = NS_NewEventListenerManager(aResult);
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
mListenerManager = *aResult;
|
|
|
|
NS_ADDREF(mListenerManager);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::GetNewListenerManager(nsIEventListenerManager** aResult)
|
|
|
|
{
|
|
|
|
return NS_NewEventListenerManager(aResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-03-28 22:22:54 +00:00
|
|
|
nsGenericElement::AddEventListenerByIID(nsIDOMEventListener* aListener,
|
1998-11-11 22:06:16 +00:00
|
|
|
const nsIID& aIID)
|
|
|
|
{
|
|
|
|
nsIEventListenerManager *manager;
|
|
|
|
|
|
|
|
if (NS_OK == GetListenerManager(&manager)) {
|
1999-03-28 22:22:54 +00:00
|
|
|
manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
1998-11-11 22:06:16 +00:00
|
|
|
NS_RELEASE(manager);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-03-28 22:22:54 +00:00
|
|
|
nsGenericElement::RemoveEventListenerByIID(nsIDOMEventListener* aListener,
|
1998-11-11 22:06:16 +00:00
|
|
|
const nsIID& aIID)
|
|
|
|
{
|
|
|
|
if (nsnull != mListenerManager) {
|
1999-03-28 22:22:54 +00:00
|
|
|
mListenerManager->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
|
1999-07-19 19:54:34 +00:00
|
|
|
PRBool aUseCapture)
|
1999-03-28 22:22:54 +00:00
|
|
|
{
|
|
|
|
nsIEventListenerManager *manager;
|
|
|
|
|
|
|
|
if (NS_OK == GetListenerManager(&manager)) {
|
1999-07-19 19:54:34 +00:00
|
|
|
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
1999-03-28 22:22:54 +00:00
|
|
|
|
|
|
|
manager->AddEventListenerByType(aListener, aType, flags);
|
|
|
|
NS_RELEASE(manager);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::RemoveEventListener(const nsString& aType, nsIDOMEventListener* aListener,
|
1999-07-19 19:54:34 +00:00
|
|
|
PRBool aUseCapture)
|
1999-03-28 22:22:54 +00:00
|
|
|
{
|
|
|
|
if (nsnull != mListenerManager) {
|
1999-07-19 19:54:34 +00:00
|
|
|
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
1999-03-28 22:22:54 +00:00
|
|
|
|
|
|
|
mListenerManager->RemoveEventListenerByType(aListener, aType, flags);
|
1998-11-11 22:06:16 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
// nsIJSScriptObject implementation
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsGenericElement::AddProperty(JSContext *aContext, jsval aID, jsval *aVp)
|
|
|
|
{
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsGenericElement::DeleteProperty(JSContext *aContext, jsval aID, jsval *aVp)
|
|
|
|
{
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsGenericElement::GetProperty(JSContext *aContext, jsval aID, jsval *aVp)
|
|
|
|
{
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsGenericElement::SetProperty(JSContext *aContext, jsval aID, jsval *aVp)
|
|
|
|
{
|
|
|
|
nsIScriptObjectOwner *owner;
|
|
|
|
|
|
|
|
if (NS_OK != mContent->QueryInterface(kIScriptObjectOwnerIID, (void **)&owner)) {
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (JS_TypeOfValue(aContext, *aVp) == JSTYPE_FUNCTION && JSVAL_IS_STRING(aID)) {
|
|
|
|
nsAutoString propName, prefix;
|
|
|
|
propName.SetString(JS_GetStringChars(JS_ValueToString(aContext, aID)));
|
1999-04-22 05:39:24 +00:00
|
|
|
prefix.SetString(propName.GetUnicode(), 2);
|
1998-11-11 22:06:16 +00:00
|
|
|
if (prefix == "on") {
|
|
|
|
nsIEventListenerManager *manager = nsnull;
|
|
|
|
|
|
|
|
if (propName == "onmousedown" || propName == "onmouseup" || propName == "onclick" ||
|
|
|
|
propName == "onmouseover" || propName == "onmouseout") {
|
|
|
|
if (NS_OK == GetListenerManager(&manager)) {
|
|
|
|
nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext);
|
|
|
|
if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMMouseListenerIID)) {
|
|
|
|
NS_RELEASE(manager);
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (propName == "onkeydown" || propName == "onkeyup" || propName == "onkeypress") {
|
|
|
|
if (NS_OK == GetListenerManager(&manager)) {
|
|
|
|
nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext);
|
|
|
|
if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMKeyListenerIID)) {
|
|
|
|
NS_RELEASE(manager);
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (propName == "onmousemove") {
|
|
|
|
if (NS_OK == GetListenerManager(&manager)) {
|
|
|
|
nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext);
|
|
|
|
if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMMouseMotionListenerIID)) {
|
|
|
|
NS_RELEASE(manager);
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (propName == "onfocus" || propName == "onblur") {
|
|
|
|
if (NS_OK == GetListenerManager(&manager)) {
|
|
|
|
nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext);
|
|
|
|
if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMFocusListenerIID)) {
|
|
|
|
NS_RELEASE(manager);
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-08-07 23:18:35 +00:00
|
|
|
else if (propName == "onsubmit" || propName == "onreset" || propName == "onchange" ||
|
|
|
|
propName == "onselect") {
|
1998-11-11 22:06:16 +00:00
|
|
|
if (NS_OK == GetListenerManager(&manager)) {
|
|
|
|
nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext);
|
|
|
|
if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMFormListenerIID)) {
|
|
|
|
NS_RELEASE(manager);
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (propName == "onload" || propName == "onunload" || propName == "onabort" ||
|
|
|
|
propName == "onerror") {
|
|
|
|
if (NS_OK == GetListenerManager(&manager)) {
|
|
|
|
nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext);
|
|
|
|
if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMLoadListenerIID)) {
|
|
|
|
NS_RELEASE(manager);
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (propName == "onpaint") {
|
|
|
|
if (NS_OK == GetListenerManager(&manager)) {
|
|
|
|
nsIScriptContext *mScriptCX = (nsIScriptContext *)
|
|
|
|
JS_GetContextPrivate(aContext);
|
|
|
|
if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner,
|
|
|
|
kIDOMPaintListenerIID)) {
|
|
|
|
NS_RELEASE(manager);
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(manager);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IF_RELEASE(owner);
|
|
|
|
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsGenericElement::EnumerateProperty(JSContext *aContext)
|
|
|
|
{
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsGenericElement::Resolve(JSContext *aContext, jsval aID)
|
|
|
|
{
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsGenericElement::Convert(JSContext *aContext, jsval aID)
|
|
|
|
{
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsGenericElement::Finalize(JSContext *aContext)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
// nsISupports implementation
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsGenericElement::QueryInterface(REFNSIID aIID,void** aInstancePtr)
|
|
|
|
{
|
|
|
|
return mContent->QueryInterface(aIID, aInstancePtr);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP_(nsrefcnt)
|
|
|
|
nsGenericElement::AddRef()
|
|
|
|
{
|
|
|
|
return NS_ADDREF(mContent);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP_(nsrefcnt)
|
|
|
|
nsGenericElement::Release()
|
|
|
|
{
|
1999-09-17 05:15:00 +00:00
|
|
|
nsrefcnt rc=0;
|
|
|
|
NS_ASSERTION(mContent, "nsGenericElement: Nothing to release!");
|
|
|
|
if (mContent)
|
|
|
|
NS_RELEASE2(mContent, rc);
|
1998-12-08 16:08:44 +00:00
|
|
|
return rc;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
void
|
|
|
|
nsGenericElement::TriggerLink(nsIPresContext& aPresContext,
|
1998-11-14 00:21:19 +00:00
|
|
|
nsLinkVerb aVerb,
|
1999-06-23 03:29:44 +00:00
|
|
|
nsIURI* aBaseURL,
|
1998-11-14 00:21:19 +00:00
|
|
|
const nsString& aURLSpec,
|
|
|
|
const nsString& aTargetSpec,
|
|
|
|
PRBool aClick)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
|
|
|
nsILinkHandler* handler;
|
|
|
|
nsresult rv = aPresContext.GetLinkHandler(&handler);
|
|
|
|
if (NS_SUCCEEDED(rv) && (nsnull != handler)) {
|
|
|
|
// Resolve url to an absolute url
|
|
|
|
nsAutoString absURLSpec;
|
1999-01-15 01:56:18 +00:00
|
|
|
if (nsnull != aBaseURL) {
|
1999-06-18 17:34:08 +00:00
|
|
|
#ifndef NECKO
|
1999-07-07 08:19:38 +00:00
|
|
|
nsString empty;
|
1999-01-15 01:56:18 +00:00
|
|
|
NS_MakeAbsoluteURL(aBaseURL, empty, aURLSpec, absURLSpec);
|
1999-06-18 17:34:08 +00:00
|
|
|
#else
|
1999-07-07 08:19:38 +00:00
|
|
|
rv = NS_MakeAbsoluteURI(aURLSpec, aBaseURL, absURLSpec);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "XXX make this function return an nsresult, like it should!");
|
1999-06-18 17:34:08 +00:00
|
|
|
#endif // NECKO
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
absURLSpec = aURLSpec;
|
|
|
|
}
|
|
|
|
|
1999-07-04 23:48:06 +00:00
|
|
|
// HACK HACK HACK. If the link clicked is a mailto: url just
|
|
|
|
// pass the aURLSpec. This is because, netlib doesn't recognize
|
|
|
|
// mailto: protocol. Note: This s'd go away after NECKO lands
|
|
|
|
|
|
|
|
PRInt32 offset = -1;
|
1999-07-22 22:34:28 +00:00
|
|
|
offset = aURLSpec.Find("mailto", PR_TRUE);
|
1999-07-04 23:48:06 +00:00
|
|
|
if (offset >= 0)
|
|
|
|
absURLSpec = aURLSpec;
|
|
|
|
|
1998-11-11 22:06:16 +00:00
|
|
|
// Now pass on absolute url to the click handler
|
|
|
|
if (aClick) {
|
1999-04-21 23:12:55 +00:00
|
|
|
handler->OnLinkClick(mContent, aVerb, absURLSpec.GetUnicode(), aTargetSpec.GetUnicode());
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
else {
|
1999-04-21 23:12:55 +00:00
|
|
|
handler->OnOverLink(mContent, absURLSpec.GetUnicode(), aTargetSpec.GetUnicode());
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
NS_RELEASE(handler);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericElement::AddScriptEventListener(nsIAtom* aAttribute,
|
1999-04-23 19:57:26 +00:00
|
|
|
const nsString& aValue,
|
|
|
|
REFNSIID aIID)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
|
|
|
nsresult ret = NS_OK;
|
|
|
|
nsIScriptContext* context;
|
|
|
|
nsIScriptContextOwner* owner;
|
|
|
|
|
|
|
|
if (nsnull != mDocument) {
|
|
|
|
owner = mDocument->GetScriptContextOwner();
|
1999-04-23 19:57:26 +00:00
|
|
|
if (owner) {
|
|
|
|
if (NS_OK == owner->GetScriptContext(&context)) {
|
|
|
|
if (nsHTMLAtoms::body == mTag || nsHTMLAtoms::frameset == mTag) {
|
|
|
|
nsIDOMEventReceiver *receiver;
|
|
|
|
nsIScriptGlobalObject *global = context->GetGlobalObject();
|
|
|
|
|
|
|
|
if (nsnull != global && NS_OK == global->QueryInterface(kIDOMEventReceiverIID, (void**)&receiver)) {
|
|
|
|
nsIEventListenerManager *manager;
|
|
|
|
if (NS_OK == receiver->GetListenerManager(&manager)) {
|
|
|
|
nsIScriptObjectOwner *mObjectOwner;
|
|
|
|
if (NS_OK == global->QueryInterface(kIScriptObjectOwnerIID, (void**)&mObjectOwner)) {
|
|
|
|
ret = manager->AddScriptEventListener(context, mObjectOwner, aAttribute, aValue, aIID);
|
|
|
|
NS_RELEASE(mObjectOwner);
|
|
|
|
}
|
|
|
|
NS_RELEASE(manager);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
1999-04-23 19:57:26 +00:00
|
|
|
NS_RELEASE(receiver);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
1999-04-23 19:57:26 +00:00
|
|
|
NS_IF_RELEASE(global);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
1999-04-23 19:57:26 +00:00
|
|
|
else {
|
|
|
|
nsIEventListenerManager *manager;
|
|
|
|
if (NS_OK == GetListenerManager(&manager)) {
|
1999-07-16 17:40:39 +00:00
|
|
|
nsIScriptObjectOwner* cowner;
|
1999-04-23 19:57:26 +00:00
|
|
|
if (NS_OK == mContent->QueryInterface(kIScriptObjectOwnerIID,
|
1999-07-16 17:40:39 +00:00
|
|
|
(void**) &cowner)) {
|
|
|
|
ret = manager->AddScriptEventListener(context, cowner,
|
1999-04-23 19:57:26 +00:00
|
|
|
aAttribute, aValue, aIID);
|
1999-07-16 17:40:39 +00:00
|
|
|
NS_RELEASE(cowner);
|
1999-04-23 19:57:26 +00:00
|
|
|
}
|
|
|
|
NS_RELEASE(manager);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
}
|
1999-04-23 19:57:26 +00:00
|
|
|
NS_RELEASE(context);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
1999-04-23 19:57:26 +00:00
|
|
|
NS_RELEASE(owner);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
1999-07-18 00:15:22 +00:00
|
|
|
static char kNameSpaceSeparator = ':';
|
1999-01-12 16:37:24 +00:00
|
|
|
|
|
|
|
nsIAtom*
|
|
|
|
nsGenericElement::CutNameSpacePrefix(nsString& aString)
|
|
|
|
{
|
|
|
|
nsAutoString prefix;
|
1999-07-18 00:15:22 +00:00
|
|
|
PRInt32 nsoffset = aString.FindChar(kNameSpaceSeparator);
|
1999-01-12 16:37:24 +00:00
|
|
|
if (-1 != nsoffset) {
|
|
|
|
aString.Left(prefix, nsoffset);
|
|
|
|
aString.Cut(0, nsoffset+1);
|
|
|
|
}
|
|
|
|
if (0 < prefix.Length()) {
|
|
|
|
return NS_NewAtom(prefix);
|
|
|
|
}
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
1998-11-11 22:06:16 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
1998-12-20 01:21:23 +00:00
|
|
|
struct nsGenericAttribute
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
1998-12-20 01:21:23 +00:00
|
|
|
nsGenericAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, const nsString& aValue)
|
|
|
|
: mNameSpaceID(aNameSpaceID),
|
|
|
|
mName(aName),
|
|
|
|
mValue(aValue)
|
|
|
|
{
|
|
|
|
NS_IF_ADDREF(mName);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
1998-12-20 01:21:23 +00:00
|
|
|
|
|
|
|
~nsGenericAttribute(void)
|
|
|
|
{
|
|
|
|
NS_IF_RELEASE(mName);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
1999-10-05 23:47:46 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
nsresult SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const {
|
|
|
|
if (!aResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
PRUint32 sum = sizeof(*this) - sizeof(mValue);
|
|
|
|
PRUint32 ssize;
|
|
|
|
mValue.SizeOf(aSizer, &ssize);
|
|
|
|
sum += ssize;
|
|
|
|
*aResult = sum;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
1998-12-20 01:21:23 +00:00
|
|
|
PRInt32 mNameSpaceID;
|
|
|
|
nsIAtom* mName;
|
|
|
|
nsString mValue;
|
|
|
|
};
|
1998-11-11 22:06:16 +00:00
|
|
|
|
|
|
|
nsGenericContainerElement::nsGenericContainerElement()
|
|
|
|
{
|
|
|
|
mAttributes = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsGenericContainerElement::~nsGenericContainerElement()
|
|
|
|
{
|
1998-12-20 01:21:23 +00:00
|
|
|
PRInt32 count = mChildren.Count();
|
|
|
|
PRInt32 index;
|
|
|
|
for (index = 0; index < count; index++) {
|
|
|
|
nsIContent* kid = (nsIContent *)mChildren.ElementAt(index);
|
1999-10-05 03:20:57 +00:00
|
|
|
kid->SetParent(nsnull);
|
1998-11-11 22:06:16 +00:00
|
|
|
NS_RELEASE(kid);
|
|
|
|
}
|
|
|
|
if (nsnull != mAttributes) {
|
1998-12-20 01:21:23 +00:00
|
|
|
count = mAttributes->Count();
|
|
|
|
for (index = 0; index < count; index++) {
|
|
|
|
nsGenericAttribute* attr = (nsGenericAttribute*)mAttributes->ElementAt(index);
|
|
|
|
delete attr;
|
|
|
|
}
|
|
|
|
delete mAttributes;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::CopyInnerTo(nsIContent* aSrcContent,
|
1999-01-14 23:14:02 +00:00
|
|
|
nsGenericContainerElement* aDst,
|
|
|
|
PRBool aDeep)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
1999-01-14 23:14:02 +00:00
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
|
|
|
if (nsnull != mAttributes) {
|
|
|
|
nsGenericAttribute* attr;
|
|
|
|
PRInt32 index;
|
|
|
|
PRInt32 count = mAttributes->Count();
|
|
|
|
for (index = 0; index < count; index++) {
|
|
|
|
attr = (nsGenericAttribute*)mAttributes->ElementAt(index);
|
|
|
|
// XXX Not very efficient, since SetAttribute does a linear search
|
|
|
|
// through its attributes before setting each attribute.
|
|
|
|
result = aDst->SetAttribute(attr->mNameSpaceID, attr->mName,
|
|
|
|
attr->mValue, PR_FALSE);
|
|
|
|
if (NS_OK != result) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aDeep) {
|
|
|
|
PRInt32 index;
|
|
|
|
PRInt32 count = mChildren.Count();
|
|
|
|
for (index = 0; index < count; index++) {
|
|
|
|
nsIContent* child = (nsIContent*)mChildren.ElementAt(index);
|
|
|
|
if (nsnull != child) {
|
|
|
|
nsIDOMNode* node;
|
|
|
|
result = child->QueryInterface(kIDOMNodeIID, (void**)&node);
|
|
|
|
if (NS_OK == result) {
|
|
|
|
nsIDOMNode* newNode;
|
|
|
|
|
|
|
|
result = node->CloneNode(aDeep, &newNode);
|
|
|
|
if (NS_OK == result) {
|
|
|
|
nsIContent* newContent;
|
|
|
|
|
|
|
|
result = newNode->QueryInterface(kIContentIID, (void**)&newContent);
|
|
|
|
if (NS_OK == result) {
|
|
|
|
result = aDst->AppendChildTo(newContent, PR_FALSE);
|
|
|
|
NS_RELEASE(newContent);
|
|
|
|
}
|
|
|
|
NS_RELEASE(newNode);
|
|
|
|
}
|
|
|
|
NS_RELEASE(node);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_OK != result) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::GetChildNodes(nsIDOMNodeList** aChildNodes)
|
|
|
|
{
|
|
|
|
nsDOMSlots *slots = GetDOMSlots();
|
|
|
|
|
|
|
|
if (nsnull == slots->mChildNodes) {
|
|
|
|
slots->mChildNodes = new nsChildContentList(mContent);
|
1998-12-17 07:22:28 +00:00
|
|
|
if (nsnull == slots->mChildNodes) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
NS_ADDREF(slots->mChildNodes);
|
|
|
|
}
|
|
|
|
|
|
|
|
return slots->mChildNodes->QueryInterface(kIDOMNodeListIID, (void **)aChildNodes);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::HasChildNodes(PRBool* aReturn)
|
|
|
|
{
|
|
|
|
if (0 != mChildren.Count()) {
|
|
|
|
*aReturn = PR_TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aReturn = PR_FALSE;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::GetFirstChild(nsIDOMNode** aNode)
|
|
|
|
{
|
|
|
|
nsIContent *child = (nsIContent *)mChildren.ElementAt(0);
|
|
|
|
if (nsnull != child) {
|
|
|
|
nsresult res = child->QueryInterface(kIDOMNodeIID, (void**)aNode);
|
|
|
|
NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); // must be a DOM Node
|
|
|
|
return res;
|
|
|
|
}
|
1998-11-30 07:59:11 +00:00
|
|
|
*aNode = nsnull;
|
1998-11-11 22:06:16 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::GetLastChild(nsIDOMNode** aNode)
|
|
|
|
{
|
|
|
|
nsIContent *child = (nsIContent *)mChildren.ElementAt(mChildren.Count()-1);
|
|
|
|
if (nsnull != child) {
|
|
|
|
nsresult res = child->QueryInterface(kIDOMNodeIID, (void**)aNode);
|
|
|
|
NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); // must be a DOM Node
|
|
|
|
return res;
|
|
|
|
}
|
1998-11-30 07:59:11 +00:00
|
|
|
*aNode = nsnull;
|
1998-11-11 22:06:16 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::InsertBefore(nsIDOMNode* aNewChild,
|
1998-11-30 07:59:11 +00:00
|
|
|
nsIDOMNode* aRefChild,
|
|
|
|
nsIDOMNode** aReturn)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
1998-11-30 07:59:11 +00:00
|
|
|
nsresult res;
|
|
|
|
|
|
|
|
*aReturn = nsnull;
|
1998-11-11 22:06:16 +00:00
|
|
|
if (nsnull == aNewChild) {
|
1999-09-08 23:18:27 +00:00
|
|
|
return NS_ERROR_NULL_POINTER;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
1998-11-30 07:59:11 +00:00
|
|
|
// Check if this is a document fragment. If it is, we need
|
|
|
|
// to remove the children of the document fragment and add them
|
|
|
|
// individually (i.e. we don't add the actual document fragment).
|
|
|
|
nsIDOMDocumentFragment* docFrag = nsnull;
|
|
|
|
if (NS_OK == aNewChild->QueryInterface(kIDOMDocumentFragmentIID,
|
|
|
|
(void **)&docFrag)) {
|
|
|
|
|
|
|
|
nsIContent* docFragContent;
|
|
|
|
res = aNewChild->QueryInterface(kIContentIID, (void **)&docFragContent);
|
|
|
|
|
|
|
|
if (NS_OK == res) {
|
1998-11-11 22:06:16 +00:00
|
|
|
nsIContent* refContent = nsnull;
|
1998-11-30 07:59:11 +00:00
|
|
|
nsIContent* childContent = nsnull;
|
|
|
|
PRInt32 refPos = 0;
|
|
|
|
PRInt32 i, count;
|
|
|
|
|
|
|
|
if (nsnull != aRefChild) {
|
|
|
|
res = aRefChild->QueryInterface(kIContentIID, (void **)&refContent);
|
|
|
|
NS_ASSERTION(NS_OK == res, "Ref child must be an nsIContent");
|
|
|
|
IndexOf(refContent, refPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
docFragContent->ChildCount(count);
|
|
|
|
// Iterate through the fragments children, removing each from
|
|
|
|
// the fragment and inserting it into the child list of its
|
|
|
|
// new parent.
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
// Always get and remove the first child, since the child indexes
|
|
|
|
// change as we go along.
|
|
|
|
res = docFragContent->ChildAt(0, childContent);
|
|
|
|
if (NS_OK == res) {
|
|
|
|
res = docFragContent->RemoveChildAt(0, PR_FALSE);
|
|
|
|
if (NS_OK == res) {
|
|
|
|
SetDocumentInChildrenOf(childContent, mDocument);
|
|
|
|
if (nsnull == refContent) {
|
|
|
|
// Append the new child to the end
|
|
|
|
res = AppendChildTo(childContent, PR_TRUE);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Insert the child and increment the insertion position
|
|
|
|
res = InsertChildAt(childContent, refPos++, PR_TRUE);
|
|
|
|
}
|
|
|
|
if (NS_OK != res) {
|
|
|
|
// Stop inserting and indicate failure
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Stop inserting and indicate failure
|
|
|
|
break;
|
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
1998-11-30 07:59:11 +00:00
|
|
|
else {
|
|
|
|
// Stop inserting and indicate failure
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NS_RELEASE(docFragContent);
|
|
|
|
|
|
|
|
// XXX Should really batch notification till the end
|
|
|
|
// rather than doing it for each element added
|
|
|
|
if (NS_OK == res) {
|
|
|
|
*aReturn = aNewChild;
|
|
|
|
NS_ADDREF(aNewChild);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
1998-11-30 07:59:11 +00:00
|
|
|
NS_IF_RELEASE(refContent);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
1999-09-08 23:18:27 +00:00
|
|
|
else {
|
|
|
|
res = NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
|
|
|
}
|
1998-11-30 07:59:11 +00:00
|
|
|
NS_RELEASE(docFrag);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
else {
|
1998-11-30 07:59:11 +00:00
|
|
|
// Get the nsIContent interface for the new content
|
|
|
|
nsIContent* newContent = nsnull;
|
|
|
|
res = aNewChild->QueryInterface(kIContentIID, (void**)&newContent);
|
|
|
|
NS_ASSERTION(NS_OK == res, "New child must be an nsIContent");
|
|
|
|
if (NS_OK == res) {
|
1999-01-19 03:54:26 +00:00
|
|
|
nsIContent* oldParent;
|
|
|
|
res = newContent->GetParent(oldParent);
|
|
|
|
if (NS_OK == res) {
|
|
|
|
// Remove the element from the old parent if one exists
|
|
|
|
if (nsnull != oldParent) {
|
|
|
|
PRInt32 index;
|
|
|
|
oldParent->IndexOf(newContent, index);
|
|
|
|
if (-1 != index) {
|
|
|
|
oldParent->RemoveChildAt(index, PR_TRUE);
|
|
|
|
}
|
|
|
|
NS_RELEASE(oldParent);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nsnull == aRefChild) {
|
|
|
|
// Append the new child to the end
|
|
|
|
SetDocumentInChildrenOf(newContent, mDocument);
|
|
|
|
res = AppendChildTo(newContent, PR_TRUE);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Get the index of where to insert the new child
|
|
|
|
nsIContent* refContent = nsnull;
|
|
|
|
res = aRefChild->QueryInterface(kIContentIID, (void**)&refContent);
|
|
|
|
NS_ASSERTION(NS_OK == res, "Ref child must be an nsIContent");
|
|
|
|
if (NS_OK == res) {
|
|
|
|
PRInt32 pos;
|
|
|
|
IndexOf(refContent, pos);
|
|
|
|
if (pos >= 0) {
|
|
|
|
SetDocumentInChildrenOf(newContent, mDocument);
|
|
|
|
res = InsertChildAt(newContent, pos, PR_TRUE);
|
|
|
|
}
|
1999-09-08 23:18:27 +00:00
|
|
|
else {
|
|
|
|
res = NS_ERROR_DOM_NOT_FOUND_ERR;
|
|
|
|
}
|
1999-01-19 03:54:26 +00:00
|
|
|
NS_RELEASE(refContent);
|
1998-11-30 07:59:11 +00:00
|
|
|
}
|
1999-09-08 23:18:27 +00:00
|
|
|
else {
|
|
|
|
res = NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
|
|
|
}
|
1998-11-30 07:59:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
NS_RELEASE(newContent);
|
|
|
|
|
|
|
|
*aReturn = aNewChild;
|
|
|
|
NS_ADDREF(aNewChild);
|
|
|
|
}
|
1999-09-08 23:18:27 +00:00
|
|
|
else {
|
|
|
|
res = NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::ReplaceChild(nsIDOMNode* aNewChild,
|
1998-11-30 07:59:11 +00:00
|
|
|
nsIDOMNode* aOldChild,
|
|
|
|
nsIDOMNode** aReturn)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
|
|
|
*aReturn = nsnull;
|
1998-11-30 07:59:11 +00:00
|
|
|
if (nsnull == aOldChild) {
|
1999-09-08 23:18:27 +00:00
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
if (nsnull == aNewChild) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1998-11-30 07:59:11 +00:00
|
|
|
}
|
|
|
|
nsIContent* content = nsnull;
|
1998-11-11 22:06:16 +00:00
|
|
|
nsresult res = aOldChild->QueryInterface(kIContentIID, (void**)&content);
|
1999-09-17 20:16:37 +00:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(res), "Must be an nsIContent");
|
|
|
|
if (NS_SUCCEEDED(res)) {
|
1998-11-11 22:06:16 +00:00
|
|
|
PRInt32 pos;
|
|
|
|
IndexOf(content, pos);
|
|
|
|
if (pos >= 0) {
|
|
|
|
nsIContent* newContent = nsnull;
|
1999-09-17 20:16:37 +00:00
|
|
|
res = aNewChild->QueryInterface(kIContentIID, (void**)&newContent);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(res), "Must be an nsIContent");
|
|
|
|
if (NS_SUCCEEDED(res)) {
|
1998-11-30 07:59:11 +00:00
|
|
|
// Check if this is a document fragment. If it is, we need
|
|
|
|
// to remove the children of the document fragment and add them
|
|
|
|
// individually (i.e. we don't add the actual document fragment).
|
|
|
|
nsIDOMDocumentFragment* docFrag = nsnull;
|
|
|
|
if (NS_OK == aNewChild->QueryInterface(kIDOMDocumentFragmentIID,
|
|
|
|
(void **)&docFrag)) {
|
|
|
|
|
|
|
|
nsIContent* docFragContent;
|
|
|
|
res = aNewChild->QueryInterface(kIContentIID, (void **)&docFragContent);
|
1999-09-17 20:16:37 +00:00
|
|
|
if (NS_SUCCEEDED(res)) {
|
1998-11-30 07:59:11 +00:00
|
|
|
PRInt32 count;
|
|
|
|
|
|
|
|
docFragContent->ChildCount(count);
|
|
|
|
// If there are children of the document
|
|
|
|
if (count > 0) {
|
|
|
|
nsIContent* childContent;
|
|
|
|
// Remove the last child of the document fragment
|
|
|
|
// and do a replace with it
|
|
|
|
res = docFragContent->ChildAt(count-1, childContent);
|
1999-09-17 20:16:37 +00:00
|
|
|
if (NS_SUCCEEDED(res)) {
|
1998-11-30 07:59:11 +00:00
|
|
|
res = docFragContent->RemoveChildAt(count-1, PR_FALSE);
|
1999-09-17 20:16:37 +00:00
|
|
|
if (NS_SUCCEEDED(res)) {
|
1998-11-30 07:59:11 +00:00
|
|
|
SetDocumentInChildrenOf(childContent, mDocument);
|
|
|
|
res = ReplaceChildAt(childContent, pos, PR_TRUE);
|
|
|
|
// If there are more children, then insert them before
|
|
|
|
// the newly replaced child
|
|
|
|
if ((NS_OK == res) && (count > 1)) {
|
|
|
|
nsIDOMNode* childNode = nsnull;
|
|
|
|
|
|
|
|
res = childContent->QueryInterface(kIDOMNodeIID,
|
|
|
|
(void **)&childNode);
|
1999-09-17 20:16:37 +00:00
|
|
|
if (NS_SUCCEEDED(res)) {
|
1998-11-30 07:59:11 +00:00
|
|
|
nsIDOMNode* rv;
|
|
|
|
|
|
|
|
res = InsertBefore(aNewChild, childNode, &rv);
|
1999-09-17 20:16:37 +00:00
|
|
|
if (NS_SUCCEEDED(res)) {
|
1998-11-30 07:59:11 +00:00
|
|
|
NS_IF_RELEASE(rv);
|
|
|
|
}
|
|
|
|
NS_RELEASE(childNode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NS_RELEASE(childContent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NS_RELEASE(docFragContent);
|
|
|
|
}
|
1999-09-08 23:18:27 +00:00
|
|
|
else {
|
|
|
|
res = NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
|
|
|
}
|
1998-11-30 07:59:11 +00:00
|
|
|
NS_RELEASE(docFrag);
|
|
|
|
}
|
|
|
|
else {
|
1999-01-19 03:54:26 +00:00
|
|
|
nsIContent* oldParent;
|
|
|
|
res = newContent->GetParent(oldParent);
|
|
|
|
if (NS_OK == res) {
|
|
|
|
// Remove the element from the old parent if one exists
|
|
|
|
if (nsnull != oldParent) {
|
|
|
|
PRInt32 index;
|
|
|
|
oldParent->IndexOf(newContent, index);
|
|
|
|
if (-1 != index) {
|
|
|
|
oldParent->RemoveChildAt(index, PR_TRUE);
|
|
|
|
}
|
|
|
|
NS_RELEASE(oldParent);
|
|
|
|
}
|
|
|
|
|
|
|
|
SetDocumentInChildrenOf(newContent, mDocument);
|
|
|
|
res = ReplaceChildAt(newContent, pos, PR_TRUE);
|
|
|
|
}
|
1998-11-30 07:59:11 +00:00
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
NS_RELEASE(newContent);
|
|
|
|
}
|
1999-09-08 23:18:27 +00:00
|
|
|
else {
|
|
|
|
res = NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
*aReturn = aOldChild;
|
|
|
|
NS_ADDREF(aOldChild);
|
|
|
|
}
|
1999-09-08 23:18:27 +00:00
|
|
|
else {
|
|
|
|
res = NS_ERROR_DOM_NOT_FOUND_ERR;
|
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
NS_RELEASE(content);
|
|
|
|
}
|
1999-09-08 23:18:27 +00:00
|
|
|
else {
|
|
|
|
res = NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
|
|
|
}
|
|
|
|
|
1998-11-11 22:06:16 +00:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::RemoveChild(nsIDOMNode* aOldChild,
|
1998-11-30 07:59:11 +00:00
|
|
|
nsIDOMNode** aReturn)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
|
|
|
nsIContent* content = nsnull;
|
|
|
|
*aReturn = nsnull;
|
1999-09-08 23:18:27 +00:00
|
|
|
|
|
|
|
if (nsnull == aOldChild) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
nsresult res = aOldChild->QueryInterface(kIContentIID, (void**)&content);
|
|
|
|
NS_ASSERTION(NS_OK == res, "Must be an nsIContent");
|
|
|
|
if (NS_OK == res) {
|
|
|
|
PRInt32 pos;
|
|
|
|
IndexOf(content, pos);
|
|
|
|
if (pos >= 0) {
|
|
|
|
res = RemoveChildAt(pos, PR_TRUE);
|
|
|
|
*aReturn = aOldChild;
|
|
|
|
NS_ADDREF(aOldChild);
|
|
|
|
}
|
1999-09-08 23:18:27 +00:00
|
|
|
else {
|
|
|
|
res = NS_ERROR_DOM_NOT_FOUND_ERR;
|
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
NS_RELEASE(content);
|
|
|
|
}
|
1999-09-08 23:18:27 +00:00
|
|
|
else {
|
|
|
|
res = NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
|
|
|
|
{
|
|
|
|
return InsertBefore(aNewChild, nsnull, aReturn);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
1998-12-20 01:21:23 +00:00
|
|
|
nsGenericContainerElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
|
1998-11-30 07:59:11 +00:00
|
|
|
const nsString& aValue,
|
|
|
|
PRBool aNotify)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
1998-12-20 01:21:23 +00:00
|
|
|
NS_ASSERTION(kNameSpaceID_Unknown != aNameSpaceID, "must have name space ID");
|
|
|
|
if (kNameSpaceID_Unknown == aNameSpaceID) {
|
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
|
|
|
}
|
|
|
|
NS_ASSERTION(nsnull != aName, "must have attribute name");
|
|
|
|
if (nsnull == aName) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
|
1998-12-20 01:21:23 +00:00
|
|
|
nsresult rv = NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
if (nsnull == mAttributes) {
|
|
|
|
mAttributes = new nsVoidArray();
|
|
|
|
}
|
|
|
|
if (nsnull != mAttributes) {
|
|
|
|
nsGenericAttribute* attr;
|
|
|
|
PRInt32 index;
|
|
|
|
PRInt32 count = mAttributes->Count();
|
|
|
|
for (index = 0; index < count; index++) {
|
|
|
|
attr = (nsGenericAttribute*)mAttributes->ElementAt(index);
|
|
|
|
if ((aNameSpaceID == attr->mNameSpaceID) && (aName == attr->mName)) {
|
|
|
|
attr->mValue = aValue;
|
|
|
|
rv = NS_OK;
|
|
|
|
break;
|
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
1998-12-20 01:21:23 +00:00
|
|
|
|
|
|
|
if (index >= count) { // didn't find it
|
|
|
|
attr = new nsGenericAttribute(aNameSpaceID, aName, aValue);
|
|
|
|
if (nsnull != attr) {
|
|
|
|
mAttributes->AppendElement(attr);
|
|
|
|
rv = NS_OK;
|
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
}
|
1998-12-20 01:21:23 +00:00
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv) && aNotify && (nsnull != mDocument)) {
|
1999-10-15 23:16:45 +00:00
|
|
|
mDocument->AttributeChanged(mContent, aNameSpaceID, aName, NS_STYLE_HINT_UNKNOWN);
|
1998-12-20 01:21:23 +00:00
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1998-12-20 01:21:23 +00:00
|
|
|
nsGenericContainerElement::GetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
|
1998-11-30 07:59:11 +00:00
|
|
|
nsString& aResult) const
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
1998-12-20 01:21:23 +00:00
|
|
|
NS_ASSERTION(nsnull != aName, "must have attribute name");
|
|
|
|
if (nsnull == aName) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
|
1998-12-20 01:21:23 +00:00
|
|
|
nsresult rv = NS_CONTENT_ATTR_NOT_THERE;
|
1998-11-11 22:06:16 +00:00
|
|
|
|
1998-12-20 01:21:23 +00:00
|
|
|
if (nsnull != mAttributes) {
|
|
|
|
PRInt32 count = mAttributes->Count();
|
|
|
|
PRInt32 index;
|
|
|
|
for (index = 0; index < count; index++) {
|
|
|
|
const nsGenericAttribute* attr = (const nsGenericAttribute*)mAttributes->ElementAt(index);
|
1999-01-30 06:20:39 +00:00
|
|
|
if (((kNameSpaceID_Unknown == aNameSpaceID) || (attr->mNameSpaceID == aNameSpaceID)) &&
|
|
|
|
(attr->mName == aName)) {
|
1998-12-20 01:21:23 +00:00
|
|
|
aResult = attr->mValue;
|
|
|
|
if (0 < aResult.Length()) {
|
|
|
|
rv = NS_CONTENT_ATTR_HAS_VALUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rv = NS_CONTENT_ATTR_NO_VALUE;
|
|
|
|
}
|
|
|
|
break;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1998-12-20 01:21:23 +00:00
|
|
|
|
1999-05-04 20:51:42 +00:00
|
|
|
if (rv == NS_CONTENT_ATTR_NOT_THERE) {
|
|
|
|
// In other cases we already set the out param.
|
|
|
|
// Since we are returning a success code we'd better do
|
|
|
|
// something about the out parameters (someone may have
|
|
|
|
// given us a non-empty string).
|
|
|
|
aResult.Truncate();
|
|
|
|
}
|
|
|
|
|
1998-11-11 22:06:16 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1998-12-20 01:21:23 +00:00
|
|
|
nsGenericContainerElement::UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|
|
|
PRBool aNotify)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
1998-12-20 01:21:23 +00:00
|
|
|
NS_ASSERTION(nsnull != aName, "must have attribute name");
|
|
|
|
if (nsnull == aName) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult rv = NS_OK;
|
1998-11-11 22:06:16 +00:00
|
|
|
|
|
|
|
if (nsnull != mAttributes) {
|
1998-12-20 01:21:23 +00:00
|
|
|
PRInt32 count = mAttributes->Count();
|
|
|
|
PRInt32 index;
|
1999-01-15 01:56:18 +00:00
|
|
|
PRBool found = PR_FALSE;
|
1998-12-20 01:21:23 +00:00
|
|
|
for (index = 0; index < count; index++) {
|
|
|
|
nsGenericAttribute* attr = (nsGenericAttribute*)mAttributes->ElementAt(index);
|
1999-01-30 06:20:39 +00:00
|
|
|
if (((kNameSpaceID_Unknown == aNameSpaceID) || (attr->mNameSpaceID == aNameSpaceID)) &&
|
|
|
|
(attr->mName == aName)) {
|
1998-12-20 01:21:23 +00:00
|
|
|
mAttributes->RemoveElementAt(index);
|
|
|
|
delete attr;
|
1999-01-15 01:56:18 +00:00
|
|
|
found = PR_TRUE;
|
1998-12-20 01:21:23 +00:00
|
|
|
break;
|
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
1999-01-15 01:56:18 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && found && aNotify && (nsnull != mDocument)) {
|
1999-10-15 23:16:45 +00:00
|
|
|
mDocument->AttributeChanged(mContent, aNameSpaceID, aName, NS_STYLE_HINT_UNKNOWN);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1998-12-20 01:21:23 +00:00
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::GetAttributeNameAt(PRInt32 aIndex,
|
|
|
|
PRInt32& aNameSpaceID,
|
|
|
|
nsIAtom*& aName) const
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
|
|
|
if (nsnull != mAttributes) {
|
1998-12-20 01:21:23 +00:00
|
|
|
nsGenericAttribute* attr = (nsGenericAttribute*)mAttributes->ElementAt(aIndex);
|
|
|
|
if (nsnull != attr) {
|
|
|
|
aNameSpaceID = attr->mNameSpaceID;
|
|
|
|
aName = attr->mName;
|
|
|
|
NS_IF_ADDREF(aName);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
1998-12-20 01:21:23 +00:00
|
|
|
aNameSpaceID = kNameSpaceID_None;
|
|
|
|
aName = nsnull;
|
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::GetAttributeCount(PRInt32& aResult) const
|
|
|
|
{
|
|
|
|
if (nsnull != mAttributes) {
|
1998-12-20 01:21:23 +00:00
|
|
|
aResult = mAttributes->Count();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
aResult = 0;
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsGenericContainerElement::ListAttributes(FILE* out) const
|
|
|
|
{
|
1998-12-20 01:21:23 +00:00
|
|
|
PRInt32 index, count;
|
|
|
|
GetAttributeCount(count);
|
|
|
|
|
|
|
|
for (index = 0; index < count; index++) {
|
|
|
|
const nsGenericAttribute* attr = (const nsGenericAttribute*)mAttributes->ElementAt(index);
|
|
|
|
nsAutoString buffer;
|
|
|
|
|
|
|
|
if (kNameSpaceID_None != attr->mNameSpaceID) { // prefix namespace
|
|
|
|
buffer.Append(attr->mNameSpaceID, 10);
|
|
|
|
buffer.Append(':');
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
1998-12-20 01:21:23 +00:00
|
|
|
|
|
|
|
// name
|
|
|
|
nsAutoString name;
|
|
|
|
attr->mName->ToString(name);
|
|
|
|
buffer.Append(name);
|
|
|
|
|
|
|
|
// value
|
|
|
|
buffer.Append("=");
|
|
|
|
buffer.Append(attr->mValue);
|
|
|
|
|
|
|
|
fputs(" ", out);
|
|
|
|
fputs(buffer, out);
|
1998-11-11 22:06:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::List(FILE* out, PRInt32 aIndent) const
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != mDocument, "bad content");
|
|
|
|
|
|
|
|
PRInt32 index;
|
|
|
|
for (index = aIndent; --index >= 0; ) fputs(" ", out);
|
|
|
|
|
|
|
|
nsIAtom* tag;
|
|
|
|
GetTag(tag);
|
|
|
|
if (tag != nsnull) {
|
|
|
|
nsAutoString buf;
|
|
|
|
tag->ToString(buf);
|
|
|
|
fputs(buf, out);
|
|
|
|
NS_RELEASE(tag);
|
|
|
|
}
|
|
|
|
|
|
|
|
ListAttributes(out);
|
|
|
|
|
|
|
|
nsIContent* hc = mContent;
|
|
|
|
nsrefcnt r = NS_ADDREF(hc) - 1;
|
|
|
|
NS_RELEASE(hc);
|
|
|
|
fprintf(out, " refcount=%d<", r);
|
|
|
|
|
|
|
|
PRBool canHaveKids;
|
|
|
|
mContent->CanContainChildren(canHaveKids);
|
|
|
|
if (canHaveKids) {
|
|
|
|
fputs("\n", out);
|
|
|
|
PRInt32 kids;
|
|
|
|
mContent->ChildCount(kids);
|
|
|
|
for (index = 0; index < kids; index++) {
|
|
|
|
nsIContent* kid;
|
|
|
|
mContent->ChildAt(index, kid);
|
|
|
|
kid->List(out, aIndent + 1);
|
|
|
|
NS_RELEASE(kid);
|
|
|
|
}
|
|
|
|
for (index = aIndent; --index >= 0; ) fputs(" ", out);
|
|
|
|
}
|
|
|
|
fputs(">\n", out);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::CanContainChildren(PRBool& aResult) const
|
|
|
|
{
|
|
|
|
aResult = PR_TRUE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::ChildCount(PRInt32& aCount) const
|
|
|
|
{
|
|
|
|
aCount = mChildren.Count();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::ChildAt(PRInt32 aIndex,
|
1998-11-30 07:59:11 +00:00
|
|
|
nsIContent*& aResult) const
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
|
|
|
nsIContent *child = (nsIContent *)mChildren.ElementAt(aIndex);
|
|
|
|
if (nsnull != child) {
|
|
|
|
NS_ADDREF(child);
|
|
|
|
}
|
|
|
|
aResult = child;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::IndexOf(nsIContent* aPossibleChild,
|
1998-11-30 07:59:11 +00:00
|
|
|
PRInt32& aIndex) const
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aPossibleChild, "null ptr");
|
|
|
|
aIndex = mChildren.IndexOf(aPossibleChild);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::InsertChildAt(nsIContent* aKid,
|
1998-11-30 07:59:11 +00:00
|
|
|
PRInt32 aIndex,
|
|
|
|
PRBool aNotify)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aKid, "null ptr");
|
|
|
|
PRBool rv = mChildren.InsertElementAt(aKid, aIndex);/* XXX fix up void array api to use nsresult's*/
|
|
|
|
if (rv) {
|
|
|
|
NS_ADDREF(aKid);
|
|
|
|
aKid->SetParent(mContent);
|
1998-12-30 08:28:16 +00:00
|
|
|
nsRange::OwnerChildInserted(mContent, aIndex);
|
1998-11-11 22:06:16 +00:00
|
|
|
nsIDocument* doc = mDocument;
|
|
|
|
if (nsnull != doc) {
|
|
|
|
aKid->SetDocument(doc, PR_FALSE);
|
|
|
|
if (aNotify) {
|
|
|
|
doc->ContentInserted(mContent, aKid, aIndex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::ReplaceChildAt(nsIContent* aKid,
|
1998-11-30 07:59:11 +00:00
|
|
|
PRInt32 aIndex,
|
|
|
|
PRBool aNotify)
|
1998-11-11 22:06:16 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aKid, "null ptr");
|
|
|
|
nsIContent* oldKid = (nsIContent *)mChildren.ElementAt(aIndex);
|
1999-06-16 21:38:51 +00:00
|
|
|
nsRange::OwnerChildReplaced(mContent, aIndex, oldKid);
|
1998-11-11 22:06:16 +00:00
|
|
|
PRBool rv = mChildren.ReplaceElementAt(aKid, aIndex);
|
|
|
|
if (rv) {
|
|
|
|
NS_ADDREF(aKid);
|
|
|
|
aKid->SetParent(mContent);
|
|
|
|
nsIDocument* doc = mDocument;
|
|
|
|
if (nsnull != doc) {
|
|
|
|
aKid->SetDocument(doc, PR_FALSE);
|
|
|
|
if (aNotify) {
|
|
|
|
doc->ContentReplaced(mContent, oldKid, aKid, aIndex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
oldKid->SetDocument(nsnull, PR_TRUE);
|
|
|
|
oldKid->SetParent(nsnull);
|
|
|
|
NS_RELEASE(oldKid);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::AppendChildTo(nsIContent* aKid, PRBool aNotify)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION((nsnull != aKid) && (aKid != mContent), "null ptr");
|
|
|
|
PRBool rv = mChildren.AppendElement(aKid);
|
|
|
|
if (rv) {
|
|
|
|
NS_ADDREF(aKid);
|
|
|
|
aKid->SetParent(mContent);
|
1998-12-30 08:28:16 +00:00
|
|
|
// ranges don't need adjustment since new child is at end of list
|
1998-11-11 22:06:16 +00:00
|
|
|
nsIDocument* doc = mDocument;
|
|
|
|
if (nsnull != doc) {
|
|
|
|
aKid->SetDocument(doc, PR_FALSE);
|
|
|
|
if (aNotify) {
|
|
|
|
doc->ContentAppended(mContent, mChildren.Count() - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify)
|
|
|
|
{
|
|
|
|
nsIContent* oldKid = (nsIContent *)mChildren.ElementAt(aIndex);
|
|
|
|
if (nsnull != oldKid ) {
|
|
|
|
nsIDocument* doc = mDocument;
|
1998-12-30 08:28:16 +00:00
|
|
|
nsRange::OwnerChildRemoved(mContent, aIndex, oldKid);
|
1999-06-16 21:38:51 +00:00
|
|
|
mChildren.RemoveElementAt(aIndex);
|
1998-11-11 22:06:16 +00:00
|
|
|
if (aNotify) {
|
|
|
|
if (nsnull != doc) {
|
|
|
|
doc->ContentRemoved(mContent, oldKid, aIndex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
oldKid->SetDocument(nsnull, PR_TRUE);
|
|
|
|
oldKid->SetParent(nsnull);
|
|
|
|
NS_RELEASE(oldKid);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// XXX To be implemented
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::BeginConvertToXIF(nsXIFConverter& aConverter) const
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::ConvertContentToXIF(nsXIFConverter& aConverter) const
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::FinishConvertToXIF(nsXIFConverter& aConverter) const
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-10-05 23:47:46 +00:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericContainerElement::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult,
|
|
|
|
size_t aInstanceSize) const
|
|
|
|
{
|
|
|
|
if (!aResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
PRUint32 sum = 0;
|
|
|
|
#ifdef DEBUG
|
|
|
|
sum += aInstanceSize;
|
|
|
|
if (mAttributes) {
|
|
|
|
// Add in array of attributes size
|
|
|
|
PRUint32 asize;
|
|
|
|
mAttributes->SizeOf(aSizer, &asize);
|
|
|
|
sum += asize;
|
|
|
|
|
|
|
|
// Add in each attributes size
|
|
|
|
PRInt32 i, n = mAttributes->Count();
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
const nsGenericAttribute* attr = (const nsGenericAttribute*)
|
|
|
|
mAttributes->ElementAt(i);
|
|
|
|
if (attr) {
|
|
|
|
PRUint32 asum = 0;
|
|
|
|
attr->SizeOf(aSizer, &asum);
|
|
|
|
sum += asum;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
*aResult = sum;
|
|
|
|
return NS_OK;
|
|
|
|
}
|