2001-09-25 01:32:19 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
2004-04-17 21:52:36 +00:00
|
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
2000-05-09 21:42:57 +00:00
|
|
|
*
|
2004-04-17 21:52:36 +00:00
|
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
|
|
* the License. You may obtain a copy of the License at
|
|
|
|
* http://www.mozilla.org/MPL/
|
2000-05-09 21:42:57 +00:00
|
|
|
*
|
2001-09-25 01:32:19 +00:00
|
|
|
* 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.
|
2000-05-09 21:42:57 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Mozilla Communicator client code.
|
|
|
|
*
|
2004-04-17 21:52:36 +00:00
|
|
|
* The Initial Developer of the Original Code is
|
2001-09-25 01:32:19 +00:00
|
|
|
* Netscape Communications Corporation.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
2000-05-09 21:42:57 +00:00
|
|
|
*
|
2001-09-25 01:32:19 +00:00
|
|
|
* Contributor(s):
|
2004-04-17 21:52:36 +00:00
|
|
|
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
|
|
|
* Alec Flett <alecf@netscape.com>
|
2001-09-25 01:32:19 +00:00
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
2004-04-17 21:52:36 +00:00
|
|
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
|
|
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
2001-09-25 01:32:19 +00:00
|
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
2004-04-17 21:52:36 +00:00
|
|
|
* use your version of this file under the terms of the MPL, indicate your
|
2001-09-25 01:32:19 +00:00
|
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
|
|
* the provisions above, a recipient may use your version of this file under
|
2004-04-17 21:52:36 +00:00
|
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
2001-09-25 01:32:19 +00:00
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
2000-05-09 21:42:57 +00:00
|
|
|
|
|
|
|
#include "nsCOMPtr.h"
|
|
|
|
#include "nsIXBLService.h"
|
|
|
|
#include "nsIInputStream.h"
|
2002-12-02 22:30:26 +00:00
|
|
|
#include "nsDoubleHashtable.h"
|
2003-11-17 21:03:32 +00:00
|
|
|
#include "nsInterfaceHashtable.h"
|
2000-05-09 21:42:57 +00:00
|
|
|
#include "nsIURI.h"
|
|
|
|
#include "nsIURL.h"
|
2003-11-17 21:03:32 +00:00
|
|
|
#include "nsURIHashKey.h"
|
2000-05-09 21:42:57 +00:00
|
|
|
#include "nsIChannel.h"
|
|
|
|
#include "nsXPIDLString.h"
|
|
|
|
#include "nsIParser.h"
|
|
|
|
#include "nsParserCIID.h"
|
|
|
|
#include "nsNetUtil.h"
|
|
|
|
#include "plstr.h"
|
|
|
|
#include "nsIContent.h"
|
|
|
|
#include "nsIDOMElement.h"
|
|
|
|
#include "nsIDocument.h"
|
2004-09-01 16:50:12 +00:00
|
|
|
#include "nsContentUtils.h"
|
2000-10-09 03:08:41 +00:00
|
|
|
#include "nsIPresShell.h"
|
2000-05-09 21:42:57 +00:00
|
|
|
#include "nsIXMLContentSink.h"
|
2001-02-19 12:55:42 +00:00
|
|
|
#include "nsContentCID.h"
|
2000-05-09 21:42:57 +00:00
|
|
|
#include "nsXMLDocument.h"
|
|
|
|
#include "nsHTMLAtoms.h"
|
|
|
|
#include "nsSupportsArray.h"
|
|
|
|
#include "nsITextContent.h"
|
2000-08-06 05:03:36 +00:00
|
|
|
#include "nsIStreamListener.h"
|
2000-08-12 06:28:02 +00:00
|
|
|
#include "nsIStyleRuleSupplier.h"
|
2004-01-28 21:04:33 +00:00
|
|
|
#include "nsStubDocumentObserver.h"
|
2000-05-09 21:42:57 +00:00
|
|
|
|
|
|
|
#include "nsIXBLBinding.h"
|
2000-08-12 06:28:02 +00:00
|
|
|
#include "nsIXBLDocumentInfo.h"
|
2003-04-15 20:35:07 +00:00
|
|
|
#include "nsXBLInsertionPoint.h"
|
2000-08-12 06:28:02 +00:00
|
|
|
|
|
|
|
#include "nsIStyleSheet.h"
|
2004-04-12 21:56:09 +00:00
|
|
|
#include "nsHTMLStyleSheet.h"
|
2000-08-12 06:28:02 +00:00
|
|
|
#include "nsIHTMLCSSStyleSheet.h"
|
|
|
|
|
|
|
|
#include "nsIStyleRuleProcessor.h"
|
2000-09-27 20:23:49 +00:00
|
|
|
#include "nsIWeakReference.h"
|
2000-05-09 21:42:57 +00:00
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
#include "jsapi.h"
|
2000-12-07 10:11:21 +00:00
|
|
|
#include "nsIXPConnect.h"
|
2001-09-05 07:36:55 +00:00
|
|
|
#include "nsDOMCID.h"
|
|
|
|
#include "nsIDOMScriptObjectFactory.h"
|
|
|
|
#include "nsIPrincipal.h"
|
|
|
|
#include "nsIScriptGlobalObject.h"
|
|
|
|
#include "nsIScriptObjectPrincipal.h"
|
|
|
|
#include "nsIConsoleService.h"
|
|
|
|
#include "nsIScriptError.h"
|
|
|
|
|
2001-07-16 02:40:48 +00:00
|
|
|
#include "nsIScriptContext.h"
|
2000-12-07 10:11:21 +00:00
|
|
|
|
2001-02-02 00:54:47 +00:00
|
|
|
// ==================================================================
|
|
|
|
// = nsAnonymousContentList
|
|
|
|
// ==================================================================
|
|
|
|
|
2003-04-15 20:35:07 +00:00
|
|
|
class nsAnonymousContentList : public nsGenericDOMNodeList
|
2001-02-07 07:45:36 +00:00
|
|
|
{
|
|
|
|
public:
|
2003-04-15 20:35:07 +00:00
|
|
|
nsAnonymousContentList(nsVoidArray* aElements);
|
2001-02-02 00:54:47 +00:00
|
|
|
virtual ~nsAnonymousContentList();
|
|
|
|
|
|
|
|
// nsIDOMNodeList interface
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
NS_DECL_NSIDOMNODELIST
|
2001-02-07 07:45:36 +00:00
|
|
|
|
2003-04-15 20:35:07 +00:00
|
|
|
PRInt32 GetInsertionPointCount() { return mElements->Count(); }
|
|
|
|
|
|
|
|
nsXBLInsertionPoint* GetInsertionPointAt(PRInt32 i) { return NS_STATIC_CAST(nsXBLInsertionPoint*, mElements->ElementAt(i)); }
|
|
|
|
|
2001-02-02 00:54:47 +00:00
|
|
|
private:
|
2003-04-15 20:35:07 +00:00
|
|
|
nsVoidArray* mElements;
|
2001-02-02 00:54:47 +00:00
|
|
|
};
|
|
|
|
|
2002-12-11 14:24:49 +00:00
|
|
|
MOZ_DECL_CTOR_COUNTER(nsAnonymousContentList)
|
2001-02-02 00:54:47 +00:00
|
|
|
|
2003-04-15 20:35:07 +00:00
|
|
|
nsAnonymousContentList::nsAnonymousContentList(nsVoidArray* aElements)
|
|
|
|
: mElements(aElements)
|
2001-02-02 00:54:47 +00:00
|
|
|
{
|
|
|
|
MOZ_COUNT_CTOR(nsAnonymousContentList);
|
|
|
|
|
|
|
|
// We don't reference count our Anonymous reference (to avoid circular
|
|
|
|
// references). We'll be told when the Anonymous goes away.
|
|
|
|
}
|
2003-04-15 20:35:07 +00:00
|
|
|
|
|
|
|
static PRBool PR_CALLBACK DeleteInsertionPoint(void* aElement, void* aData)
|
|
|
|
{
|
|
|
|
delete NS_STATIC_CAST(nsXBLInsertionPoint*, aElement);
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
2001-02-02 00:54:47 +00:00
|
|
|
nsAnonymousContentList::~nsAnonymousContentList()
|
|
|
|
{
|
|
|
|
MOZ_COUNT_DTOR(nsAnonymousContentList);
|
2003-04-15 20:35:07 +00:00
|
|
|
mElements->EnumerateForwards(DeleteInsertionPoint, nsnull);
|
|
|
|
delete mElements;
|
2001-02-02 00:54:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsAnonymousContentList::GetLength(PRUint32* aLength)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aLength != nsnull, "null ptr");
|
|
|
|
if (! aLength)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
2003-04-15 20:35:07 +00:00
|
|
|
PRInt32 cnt = mElements->Count();
|
2001-02-02 00:54:47 +00:00
|
|
|
|
|
|
|
*aLength = 0;
|
2003-04-15 20:35:07 +00:00
|
|
|
for (PRInt32 i = 0; i < cnt; i++)
|
|
|
|
*aLength += NS_STATIC_CAST(nsXBLInsertionPoint*, mElements->ElementAt(i))->ChildCount();
|
2001-02-02 00:54:47 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsAnonymousContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
|
|
|
|
{
|
2003-04-15 20:35:07 +00:00
|
|
|
PRInt32 cnt = mElements->Count();
|
2001-02-02 00:54:47 +00:00
|
|
|
PRUint32 pointCount = 0;
|
2003-04-15 20:35:07 +00:00
|
|
|
|
|
|
|
for (PRInt32 i = 0; i < cnt; i++) {
|
2001-02-02 00:54:47 +00:00
|
|
|
aIndex -= pointCount;
|
|
|
|
|
2003-04-15 20:35:07 +00:00
|
|
|
nsXBLInsertionPoint* point = NS_STATIC_CAST(nsXBLInsertionPoint*, mElements->ElementAt(i));
|
|
|
|
pointCount = point->ChildCount();
|
2001-02-02 00:54:47 +00:00
|
|
|
|
|
|
|
if (aIndex < pointCount) {
|
2003-04-15 20:35:07 +00:00
|
|
|
nsCOMPtr<nsIContent> result = point->ChildAt(aIndex);
|
|
|
|
if (result)
|
2002-12-11 14:24:49 +00:00
|
|
|
return CallQueryInterface(result, aReturn);
|
2003-04-15 20:35:07 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2001-02-02 00:54:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2000-08-12 06:28:02 +00:00
|
|
|
|
2002-12-02 22:30:26 +00:00
|
|
|
//
|
|
|
|
// Generic pldhash table stuff for mapping one nsISupports to another
|
|
|
|
//
|
|
|
|
// These values are never null - a null value implies that this
|
|
|
|
// whole key should be removed (See SetOrRemoveObject)
|
|
|
|
class ObjectEntry : public PLDHashEntryHdr
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
// note that these are allocated within the PLDHashTable, but we
|
|
|
|
// want to keep track of them anyway
|
|
|
|
ObjectEntry() { MOZ_COUNT_CTOR(ObjectEntry); }
|
|
|
|
~ObjectEntry() { MOZ_COUNT_DTOR(ObjectEntry); }
|
|
|
|
|
|
|
|
nsISupports* GetValue() { return mValue; }
|
|
|
|
nsISupports* GetKey() { return mKey; }
|
|
|
|
void SetValue(nsISupports* aValue) { mValue = aValue; }
|
|
|
|
void SetKey(nsISupports* aKey) { mKey = aKey; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
nsCOMPtr<nsISupports> mKey;
|
|
|
|
nsCOMPtr<nsISupports> mValue;
|
|
|
|
};
|
|
|
|
|
|
|
|
PR_STATIC_CALLBACK(void)
|
|
|
|
ClearObjectEntry(PLDHashTable* table, PLDHashEntryHdr *entry)
|
|
|
|
{
|
|
|
|
ObjectEntry* objEntry = NS_STATIC_CAST(ObjectEntry*, entry);
|
|
|
|
objEntry->~ObjectEntry();
|
|
|
|
}
|
|
|
|
|
2003-08-05 20:09:21 +00:00
|
|
|
PR_STATIC_CALLBACK(PRBool)
|
2002-12-02 22:30:26 +00:00
|
|
|
InitObjectEntry(PLDHashTable* table, PLDHashEntryHdr* entry, const void* key)
|
|
|
|
{
|
|
|
|
new (entry) ObjectEntry;
|
2003-08-05 20:09:21 +00:00
|
|
|
return PR_TRUE;
|
2002-12-02 22:30:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static PLDHashTableOps ObjectTableOps = {
|
|
|
|
PL_DHashAllocTable,
|
|
|
|
PL_DHashFreeTable,
|
|
|
|
PL_DHashGetKeyStub,
|
|
|
|
PL_DHashVoidPtrKeyStub,
|
|
|
|
PL_DHashMatchEntryStub,
|
|
|
|
PL_DHashMoveEntryStub,
|
|
|
|
ClearObjectEntry,
|
|
|
|
PL_DHashFinalizeStub,
|
|
|
|
InitObjectEntry
|
|
|
|
};
|
|
|
|
|
|
|
|
// helper routine for adding a new entry
|
|
|
|
static nsresult
|
|
|
|
AddObjectEntry(PLDHashTable& table, nsISupports* aKey, nsISupports* aValue)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aKey, "key must be non-null");
|
|
|
|
if (!aKey) return NS_ERROR_INVALID_ARG;
|
|
|
|
|
|
|
|
ObjectEntry *entry =
|
|
|
|
NS_STATIC_CAST(ObjectEntry*,
|
|
|
|
PL_DHashTableOperate(&table, aKey, PL_DHASH_ADD));
|
|
|
|
|
|
|
|
if (!entry)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
// only add the key if the entry is new
|
|
|
|
if (!entry->GetKey())
|
|
|
|
entry->SetKey(aKey);
|
|
|
|
|
|
|
|
// now attach the new entry - note that entry->mValue could possibly
|
|
|
|
// have a value already, this will release that.
|
|
|
|
entry->SetValue(aValue);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// helper routine for looking up an existing entry. Note that the
|
|
|
|
// return result is NOT addreffed
|
|
|
|
static nsISupports*
|
|
|
|
LookupObject(PLDHashTable& table, nsISupports* aKey)
|
|
|
|
{
|
|
|
|
ObjectEntry *entry =
|
|
|
|
NS_STATIC_CAST(ObjectEntry*,
|
|
|
|
PL_DHashTableOperate(&table, aKey, PL_DHASH_LOOKUP));
|
|
|
|
|
|
|
|
if (PL_DHASH_ENTRY_IS_BUSY(entry))
|
|
|
|
return entry->GetValue();
|
|
|
|
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
RemoveObjectEntry(PLDHashTable& table, nsISupports* aKey)
|
|
|
|
{
|
|
|
|
PL_DHashTableOperate(&table, aKey, PL_DHASH_REMOVE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
|
|
|
SetOrRemoveObject(PLDHashTable& table, nsISupports* aKey, nsISupports* aValue)
|
|
|
|
{
|
2003-07-14 21:26:24 +00:00
|
|
|
if (aValue) {
|
|
|
|
// lazily create the table, but only when adding elements
|
|
|
|
if (!table.ops &&
|
|
|
|
!PL_DHashTableInit(&table, &ObjectTableOps, nsnull,
|
|
|
|
sizeof(ObjectEntry), 16)) {
|
|
|
|
table.ops = nsnull;
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
2002-12-02 22:30:26 +00:00
|
|
|
return AddObjectEntry(table, aKey, aValue);
|
2003-07-14 21:26:24 +00:00
|
|
|
}
|
2002-12-02 22:30:26 +00:00
|
|
|
|
|
|
|
// no value, so remove the key from the table
|
|
|
|
if (table.ops)
|
|
|
|
RemoveObjectEntry(table, aKey);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2001-02-07 07:45:36 +00:00
|
|
|
|
2000-08-12 06:28:02 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2004-01-28 21:04:33 +00:00
|
|
|
class nsBindingManager : public nsIBindingManager,
|
|
|
|
public nsIStyleRuleSupplier,
|
|
|
|
public nsStubDocumentObserver
|
2000-05-09 21:42:57 +00:00
|
|
|
{
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
public:
|
|
|
|
nsBindingManager();
|
|
|
|
virtual ~nsBindingManager();
|
|
|
|
|
|
|
|
NS_IMETHOD GetBinding(nsIContent* aContent, nsIXBLBinding** aResult);
|
|
|
|
NS_IMETHOD SetBinding(nsIContent* aContent, nsIXBLBinding* aBinding);
|
|
|
|
|
2001-02-02 00:54:47 +00:00
|
|
|
NS_IMETHOD GetInsertionParent(nsIContent* aContent, nsIContent** aResult);
|
|
|
|
NS_IMETHOD SetInsertionParent(nsIContent* aContent, nsIContent* aResult);
|
|
|
|
|
2000-12-07 10:11:21 +00:00
|
|
|
NS_IMETHOD GetWrappedJS(nsIContent* aContent, nsIXPConnectWrappedJS** aResult);
|
|
|
|
NS_IMETHOD SetWrappedJS(nsIContent* aContent, nsIXPConnectWrappedJS* aResult);
|
|
|
|
|
2000-09-20 00:14:04 +00:00
|
|
|
NS_IMETHOD ChangeDocumentFor(nsIContent* aContent, nsIDocument* aOldDocument,
|
|
|
|
nsIDocument* aNewDocument);
|
|
|
|
|
2000-05-24 08:19:10 +00:00
|
|
|
NS_IMETHOD ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom** aResult);
|
2000-05-09 21:42:57 +00:00
|
|
|
|
2001-02-02 00:54:47 +00:00
|
|
|
NS_IMETHOD GetContentListFor(nsIContent* aContent, nsIDOMNodeList** aResult);
|
2003-04-15 20:35:07 +00:00
|
|
|
NS_IMETHOD SetContentListFor(nsIContent* aContent, nsVoidArray* aList);
|
2001-08-03 07:34:28 +00:00
|
|
|
NS_IMETHOD HasContentListFor(nsIContent* aContent, PRBool* aResult);
|
2001-02-02 00:54:47 +00:00
|
|
|
|
|
|
|
NS_IMETHOD GetAnonymousNodesFor(nsIContent* aContent, nsIDOMNodeList** aResult);
|
2003-04-15 20:35:07 +00:00
|
|
|
NS_IMETHOD SetAnonymousNodesFor(nsIContent* aContent, nsVoidArray* aList);
|
2001-02-02 00:54:47 +00:00
|
|
|
|
2001-02-20 01:05:34 +00:00
|
|
|
NS_IMETHOD GetXBLChildNodesFor(nsIContent* aContent, nsIDOMNodeList** aResult);
|
|
|
|
|
2001-02-02 00:54:47 +00:00
|
|
|
NS_IMETHOD GetInsertionPoint(nsIContent* aParent, nsIContent* aChild, nsIContent** aResult, PRUint32* aIndex);
|
|
|
|
NS_IMETHOD GetSingleInsertionPoint(nsIContent* aParent, nsIContent** aResult, PRUint32* aIndex,
|
2000-05-22 08:23:09 +00:00
|
|
|
PRBool* aMultipleInsertionPoints);
|
|
|
|
|
2003-10-01 22:53:56 +00:00
|
|
|
NS_IMETHOD AddLayeredBinding(nsIContent* aContent, nsIURI* aURL);
|
|
|
|
NS_IMETHOD RemoveLayeredBinding(nsIContent* aContent, nsIURI* aURL);
|
2003-11-17 21:03:32 +00:00
|
|
|
NS_IMETHOD LoadBindingDocument(nsIDocument* aBoundDoc, nsIURI* aURL,
|
2000-09-05 07:29:01 +00:00
|
|
|
nsIDocument** aResult);
|
2000-06-02 08:13:29 +00:00
|
|
|
|
2000-07-28 00:35:02 +00:00
|
|
|
NS_IMETHOD AddToAttachedQueue(nsIXBLBinding* aBinding);
|
|
|
|
NS_IMETHOD ClearAttachedQueue();
|
|
|
|
NS_IMETHOD ProcessAttachedQueue();
|
|
|
|
|
2000-09-08 06:57:03 +00:00
|
|
|
NS_IMETHOD ExecuteDetachedHandlers();
|
|
|
|
|
2000-08-12 06:28:02 +00:00
|
|
|
NS_IMETHOD PutXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo);
|
2003-11-17 21:03:32 +00:00
|
|
|
NS_IMETHOD GetXBLDocumentInfo(nsIURI* aURI, nsIXBLDocumentInfo** aResult);
|
2001-11-02 01:53:13 +00:00
|
|
|
NS_IMETHOD RemoveXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo);
|
2000-08-05 22:33:29 +00:00
|
|
|
|
2003-11-17 21:03:32 +00:00
|
|
|
NS_IMETHOD PutLoadingDocListener(nsIURI* aURL, nsIStreamListener* aListener);
|
|
|
|
NS_IMETHOD GetLoadingDocListener(nsIURI* aURL, nsIStreamListener** aResult);
|
|
|
|
NS_IMETHOD RemoveLoadingDocListener(nsIURI* aURL);
|
2000-08-06 04:57:55 +00:00
|
|
|
|
2000-08-12 06:28:02 +00:00
|
|
|
NS_IMETHOD InheritsStyle(nsIContent* aContent, PRBool* aResult);
|
2001-12-17 22:51:39 +00:00
|
|
|
NS_IMETHOD FlushSkinBindings();
|
2000-08-14 04:04:18 +00:00
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
NS_IMETHOD GetBindingImplementation(nsIContent* aContent, REFNSIID aIID, void** aResult);
|
2000-12-07 10:11:21 +00:00
|
|
|
|
2001-02-07 07:45:36 +00:00
|
|
|
NS_IMETHOD ShouldBuildChildFrames(nsIContent* aContent, PRBool* aResult);
|
|
|
|
|
2000-08-12 06:28:02 +00:00
|
|
|
// nsIStyleRuleSupplier
|
2004-01-07 22:30:53 +00:00
|
|
|
NS_IMETHOD WalkRules(nsStyleSet* aStyleSet,
|
|
|
|
nsIStyleRuleProcessor::EnumFunc aFunc,
|
2004-09-10 04:57:30 +00:00
|
|
|
RuleProcessorData* aData,
|
|
|
|
PRBool* aCutOffInheritance);
|
2000-08-12 06:28:02 +00:00
|
|
|
|
2001-02-07 07:45:36 +00:00
|
|
|
// nsIDocumentObserver
|
2004-01-28 21:04:33 +00:00
|
|
|
virtual void ContentAppended(nsIDocument* aDocument,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
PRInt32 aNewIndexInContainer);
|
|
|
|
virtual void ContentInserted(nsIDocument* aDocument,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInContainer);
|
|
|
|
virtual void ContentRemoved(nsIDocument* aDocument,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInContainer);
|
2000-12-07 10:11:21 +00:00
|
|
|
|
2000-08-12 06:28:02 +00:00
|
|
|
protected:
|
2003-04-15 20:35:07 +00:00
|
|
|
nsresult GetXBLChildNodesInternal(nsIContent* aContent,
|
|
|
|
nsIDOMNodeList** aResult,
|
|
|
|
PRBool* aIsAnonymousContentList);
|
|
|
|
nsresult GetAnonymousNodesInternal(nsIContent* aContent,
|
|
|
|
nsIDOMNodeList** aResult,
|
|
|
|
PRBool* aIsAnonymousContentList);
|
|
|
|
|
2003-07-28 21:17:26 +00:00
|
|
|
nsIContent* GetEnclosingScope(nsIContent* aContent) {
|
|
|
|
return aContent->GetBindingParent();
|
|
|
|
}
|
2000-08-12 06:28:02 +00:00
|
|
|
|
2001-02-07 07:45:36 +00:00
|
|
|
nsresult GetNestedInsertionPoint(nsIContent* aParent, nsIContent* aChild, nsIContent** aResult);
|
|
|
|
|
2000-05-09 21:42:57 +00:00
|
|
|
// MEMBER VARIABLES
|
|
|
|
protected:
|
2002-12-02 22:30:26 +00:00
|
|
|
// A mapping from nsIContent* to the nsIXBLBinding* that is
|
|
|
|
// installed on that element.
|
|
|
|
PLDHashTable mBindingTable;
|
2001-02-02 00:54:47 +00:00
|
|
|
|
2002-12-02 22:30:26 +00:00
|
|
|
// A mapping from nsIContent* to an nsIDOMNodeList*
|
|
|
|
// (nsAnonymousContentList*). This list contains an accurate
|
|
|
|
// reflection of our *explicit* children (once intermingled with
|
2001-02-02 00:54:47 +00:00
|
|
|
// insertion points) in the altered DOM.
|
2002-12-02 22:30:26 +00:00
|
|
|
PLDHashTable mContentListTable;
|
|
|
|
|
|
|
|
// A mapping from nsIContent* to an nsIDOMNodeList*
|
|
|
|
// (nsAnonymousContentList*). This list contains an accurate
|
|
|
|
// reflection of our *anonymous* children (if and only if they are
|
|
|
|
// intermingled with insertion points) in the altered DOM. This
|
|
|
|
// table is not used if no insertion points were defined directly
|
|
|
|
// underneath a <content> tag in a binding. The NodeList from the
|
|
|
|
// <content> is used instead as a performance optimization.
|
|
|
|
PLDHashTable mAnonymousNodesTable;
|
|
|
|
|
|
|
|
// A mapping from nsIContent* to nsIContent*. The insertion parent
|
|
|
|
// is our one true parent in the transformed DOM. This gives us a
|
|
|
|
// more-or-less O(1) way of obtaining our transformed parent.
|
|
|
|
PLDHashTable mInsertionParentTable;
|
|
|
|
|
|
|
|
// A mapping from nsIContent* to nsIXPWrappedJS* (an XPConnect
|
|
|
|
// wrapper for JS objects). For XBL bindings that implement XPIDL
|
|
|
|
// interfaces, and that get referred to from C++, this table caches
|
|
|
|
// the XPConnect wrapper for the binding. By caching it, I control
|
|
|
|
// its lifetime, and I prevent a re-wrap of the same script object
|
|
|
|
// (in the case where multiple bindings in an XBL inheritance chain
|
|
|
|
// both implement an XPIDL interface).
|
|
|
|
PLDHashTable mWrapperTable;
|
|
|
|
|
|
|
|
// A mapping from a URL (a string) to nsIXBLDocumentInfo*. This table
|
|
|
|
// is the cache of all binding documents that have been loaded by a
|
|
|
|
// given bound document.
|
2003-11-17 21:03:32 +00:00
|
|
|
nsInterfaceHashtable<nsURIHashKey,nsIXBLDocumentInfo> mDocumentTable;
|
2002-12-02 22:30:26 +00:00
|
|
|
|
|
|
|
// A mapping from a URL (a string) to a nsIStreamListener. This
|
|
|
|
// table is the currently loading binding docs. If they're in this
|
|
|
|
// table, they have not yet finished loading.
|
2003-11-17 21:03:32 +00:00
|
|
|
nsInterfaceHashtable<nsURIHashKey,nsIStreamListener> mLoadingDocTable;
|
2002-12-02 22:30:26 +00:00
|
|
|
|
|
|
|
// A queue of binding attached event handlers that are awaiting
|
|
|
|
// execution.
|
2003-09-11 02:17:11 +00:00
|
|
|
nsCOMPtr<nsISupportsArray> mAttachedStack;
|
|
|
|
PRBool mProcessingAttachedStack;
|
2000-05-09 21:42:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Implementation /////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// Static member variable initialization
|
|
|
|
|
|
|
|
// Implement our nsISupports methods
|
2001-02-07 07:45:36 +00:00
|
|
|
NS_IMPL_ISUPPORTS3(nsBindingManager, nsIBindingManager, nsIStyleRuleSupplier, nsIDocumentObserver)
|
2000-05-09 21:42:57 +00:00
|
|
|
|
|
|
|
// Constructors/Destructors
|
|
|
|
nsBindingManager::nsBindingManager(void)
|
2003-09-11 02:17:11 +00:00
|
|
|
: mProcessingAttachedStack(PR_FALSE)
|
2000-05-09 21:42:57 +00:00
|
|
|
{
|
2002-12-02 22:30:26 +00:00
|
|
|
mBindingTable.ops = nsnull;
|
|
|
|
mContentListTable.ops = nsnull;
|
|
|
|
mAnonymousNodesTable.ops = nsnull;
|
|
|
|
mInsertionParentTable.ops = nsnull;
|
|
|
|
mWrapperTable.ops = nsnull;
|
2000-05-09 21:42:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsBindingManager::~nsBindingManager(void)
|
|
|
|
{
|
2002-12-02 22:30:26 +00:00
|
|
|
if (mBindingTable.ops)
|
|
|
|
PL_DHashTableFinish(&mBindingTable);
|
|
|
|
if (mContentListTable.ops)
|
|
|
|
PL_DHashTableFinish(&mContentListTable);
|
|
|
|
if (mAnonymousNodesTable.ops)
|
|
|
|
PL_DHashTableFinish(&mAnonymousNodesTable);
|
|
|
|
if (mInsertionParentTable.ops)
|
|
|
|
PL_DHashTableFinish(&mInsertionParentTable);
|
|
|
|
if (mWrapperTable.ops)
|
|
|
|
PL_DHashTableFinish(&mWrapperTable);
|
2000-05-09 21:42:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsBindingManager::GetBinding(nsIContent* aContent, nsIXBLBinding** aResult)
|
2002-12-02 22:30:26 +00:00
|
|
|
{
|
|
|
|
if (mBindingTable.ops) {
|
|
|
|
*aResult = NS_STATIC_CAST(nsIXBLBinding*,
|
|
|
|
LookupObject(mBindingTable, aContent));
|
|
|
|
NS_IF_ADDREF(*aResult);
|
2000-09-20 00:14:04 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aResult = nsnull;
|
2000-05-09 21:42:57 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2001-02-08 23:24:55 +00:00
|
|
|
nsBindingManager::SetBinding(nsIContent* aContent, nsIXBLBinding* aBinding)
|
2000-05-09 21:42:57 +00:00
|
|
|
{
|
2002-12-02 22:30:26 +00:00
|
|
|
nsresult rv =
|
|
|
|
SetOrRemoveObject(mBindingTable, aContent, aBinding);
|
|
|
|
if (!aBinding) {
|
|
|
|
// The death of the bindings means the death of the JS wrapper,
|
|
|
|
// and the flushing of our explicit and anonymous insertion point
|
|
|
|
// lists.
|
2000-12-07 10:11:21 +00:00
|
|
|
SetWrappedJS(aContent, nsnull);
|
2001-02-08 23:24:55 +00:00
|
|
|
SetContentListFor(aContent, nsnull);
|
|
|
|
SetAnonymousNodesFor(aContent, nsnull);
|
2000-12-07 10:11:21 +00:00
|
|
|
}
|
|
|
|
|
2002-12-02 22:30:26 +00:00
|
|
|
return rv;
|
2000-12-07 10:11:21 +00:00
|
|
|
}
|
|
|
|
|
2001-02-02 00:54:47 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsBindingManager::GetInsertionParent(nsIContent* aContent, nsIContent** aResult)
|
|
|
|
{
|
2002-12-02 22:30:26 +00:00
|
|
|
if (mInsertionParentTable.ops) {
|
|
|
|
*aResult = NS_STATIC_CAST(nsIContent*,
|
|
|
|
LookupObject(mInsertionParentTable, aContent));
|
|
|
|
NS_IF_ADDREF(*aResult);
|
2001-02-02 00:54:47 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aResult = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsBindingManager::SetInsertionParent(nsIContent* aContent, nsIContent* aParent)
|
|
|
|
{
|
2002-12-02 22:30:26 +00:00
|
|
|
return SetOrRemoveObject(mInsertionParentTable, aContent, aParent);
|
2001-02-02 00:54:47 +00:00
|
|
|
}
|
|
|
|
|
2000-12-07 10:11:21 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsBindingManager::GetWrappedJS(nsIContent* aContent, nsIXPConnectWrappedJS** aResult)
|
|
|
|
{
|
2002-12-02 22:30:26 +00:00
|
|
|
if (mWrapperTable.ops) {
|
|
|
|
*aResult = NS_STATIC_CAST(nsIXPConnectWrappedJS*, LookupObject(mWrapperTable, aContent));
|
|
|
|
NS_IF_ADDREF(*aResult);
|
2000-12-07 10:11:21 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aResult = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsBindingManager::SetWrappedJS(nsIContent* aContent, nsIXPConnectWrappedJS* aWrappedJS)
|
|
|
|
{
|
2002-12-02 22:30:26 +00:00
|
|
|
return SetOrRemoveObject(mWrapperTable, aContent, aWrappedJS);
|
2000-05-09 21:42:57 +00:00
|
|
|
}
|
|
|
|
|
2000-09-20 00:14:04 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsBindingManager::ChangeDocumentFor(nsIContent* aContent, nsIDocument* aOldDocument,
|
|
|
|
nsIDocument* aNewDocument)
|
|
|
|
{
|
2000-10-09 03:08:41 +00:00
|
|
|
NS_PRECONDITION(aOldDocument != nsnull, "no old document");
|
|
|
|
if (! aOldDocument)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
2000-09-20 00:14:04 +00:00
|
|
|
nsCOMPtr<nsIXBLBinding> binding;
|
|
|
|
GetBinding(aContent, getter_AddRefs(binding));
|
|
|
|
if (binding) {
|
|
|
|
binding->ChangeDocument(aOldDocument, aNewDocument);
|
|
|
|
SetBinding(aContent, nsnull);
|
2003-10-22 06:09:48 +00:00
|
|
|
if (aNewDocument)
|
|
|
|
aNewDocument->GetBindingManager()->SetBinding(aContent, binding);
|
2000-09-20 00:14:04 +00:00
|
|
|
}
|
|
|
|
|
2001-02-02 00:54:47 +00:00
|
|
|
// Clear out insertion parents and content lists.
|
|
|
|
SetInsertionParent(aContent, nsnull);
|
|
|
|
SetContentListFor(aContent, nsnull);
|
|
|
|
SetAnonymousNodesFor(aContent, nsnull);
|
|
|
|
|
2003-09-27 04:18:26 +00:00
|
|
|
PRUint32 count = aOldDocument->GetNumberOfShells();
|
|
|
|
|
|
|
|
for (PRUint32 i = 0; i < count; ++i) {
|
|
|
|
nsIPresShell *shell = aOldDocument->GetShellAt(i);
|
|
|
|
NS_ASSERTION(shell != nsnull, "Zoiks! nsIDocument::GetShellAt() broke");
|
2000-10-09 03:08:41 +00:00
|
|
|
|
2000-09-20 00:14:04 +00:00
|
|
|
// See if the element has nsIAnonymousContentCreator-created
|
|
|
|
// anonymous content...
|
2000-10-09 03:08:41 +00:00
|
|
|
nsCOMPtr<nsISupportsArray> anonymousElements;
|
|
|
|
shell->GetAnonymousContentFor(aContent, getter_AddRefs(anonymousElements));
|
2000-09-20 00:14:04 +00:00
|
|
|
|
|
|
|
if (anonymousElements) {
|
|
|
|
// ...yep, so be sure to update the doc pointer in those
|
|
|
|
// elements, too.
|
|
|
|
PRUint32 count;
|
|
|
|
anonymousElements->Count(&count);
|
|
|
|
|
|
|
|
while (PRInt32(--count) >= 0) {
|
2004-01-12 23:43:59 +00:00
|
|
|
nsCOMPtr<nsIContent> content( do_QueryElementAt(anonymousElements, count));
|
2000-09-20 00:14:04 +00:00
|
|
|
NS_ASSERTION(content != nsnull, "not an nsIContent");
|
|
|
|
if (! content)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
content->SetDocument(aNewDocument, PR_TRUE, PR_TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-05-09 21:42:57 +00:00
|
|
|
NS_IMETHODIMP
|
2003-11-19 01:20:56 +00:00
|
|
|
nsBindingManager::ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID,
|
|
|
|
nsIAtom** aResult)
|
2000-05-09 21:42:57 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIXBLBinding> binding;
|
|
|
|
GetBinding(aContent, getter_AddRefs(binding));
|
|
|
|
|
|
|
|
if (binding) {
|
2003-11-19 01:20:56 +00:00
|
|
|
binding->GetBaseTag(aNameSpaceID, aResult);
|
|
|
|
|
|
|
|
if (*aResult) {
|
2000-05-09 21:42:57 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-06-13 20:10:01 +00:00
|
|
|
aContent->GetNameSpaceID(aNameSpaceID);
|
2003-11-19 01:20:56 +00:00
|
|
|
NS_ADDREF(*aResult = aContent->Tag());
|
|
|
|
|
|
|
|
return NS_OK;
|
2000-05-09 21:42:57 +00:00
|
|
|
}
|
|
|
|
|
2000-05-22 08:23:09 +00:00
|
|
|
NS_IMETHODIMP
|
2001-02-02 00:54:47 +00:00
|
|
|
nsBindingManager::GetContentListFor(nsIContent* aContent, nsIDOMNodeList** aResult)
|
|
|
|
{
|
|
|
|
// Locate the primary binding and get its node list of anonymous children.
|
|
|
|
*aResult = nsnull;
|
|
|
|
|
2002-12-02 22:30:26 +00:00
|
|
|
if (mContentListTable.ops) {
|
|
|
|
*aResult = NS_STATIC_CAST(nsIDOMNodeList*,
|
|
|
|
LookupObject(mContentListTable, aContent));
|
|
|
|
NS_IF_ADDREF(*aResult);
|
2001-02-02 00:54:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!*aResult) {
|
|
|
|
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aContent));
|
|
|
|
return node->GetChildNodes(aResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2003-04-15 20:35:07 +00:00
|
|
|
nsBindingManager::SetContentListFor(nsIContent* aContent, nsVoidArray* aList)
|
2002-12-02 22:30:26 +00:00
|
|
|
{
|
|
|
|
nsIDOMNodeList* contentList = nsnull;
|
2001-02-02 00:54:47 +00:00
|
|
|
if (aList) {
|
2002-12-02 22:30:26 +00:00
|
|
|
contentList = new nsAnonymousContentList(aList);
|
|
|
|
if (!contentList) return NS_ERROR_OUT_OF_MEMORY;
|
2001-02-02 00:54:47 +00:00
|
|
|
}
|
|
|
|
|
2002-12-02 22:30:26 +00:00
|
|
|
return SetOrRemoveObject(mContentListTable, aContent, contentList);
|
2001-02-02 00:54:47 +00:00
|
|
|
}
|
|
|
|
|
2001-08-03 07:34:28 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsBindingManager::HasContentListFor(nsIContent* aContent, PRBool* aResult)
|
|
|
|
{
|
|
|
|
*aResult = PR_FALSE;
|
2002-12-02 22:30:26 +00:00
|
|
|
if (mContentListTable.ops) {
|
|
|
|
nsISupports* list = LookupObject(mContentListTable, aContent);
|
2001-08-03 07:34:28 +00:00
|
|
|
*aResult = (list != nsnull);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2003-04-15 20:35:07 +00:00
|
|
|
nsresult
|
|
|
|
nsBindingManager::GetAnonymousNodesInternal(nsIContent* aContent,
|
|
|
|
nsIDOMNodeList** aResult,
|
|
|
|
PRBool* aIsAnonymousContentList)
|
2001-02-02 00:54:47 +00:00
|
|
|
{
|
|
|
|
// Locate the primary binding and get its node list of anonymous children.
|
|
|
|
*aResult = nsnull;
|
2002-12-02 22:30:26 +00:00
|
|
|
if (mAnonymousNodesTable.ops) {
|
|
|
|
*aResult = NS_STATIC_CAST(nsIDOMNodeList*,
|
|
|
|
LookupObject(mAnonymousNodesTable, aContent));
|
|
|
|
NS_IF_ADDREF(*aResult);
|
2001-02-02 00:54:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!*aResult) {
|
2003-04-15 20:35:07 +00:00
|
|
|
*aIsAnonymousContentList = PR_FALSE;
|
2001-02-02 00:54:47 +00:00
|
|
|
nsCOMPtr<nsIXBLBinding> binding;
|
|
|
|
GetBinding(aContent, getter_AddRefs(binding));
|
|
|
|
if (binding)
|
|
|
|
return binding->GetAnonymousNodes(aResult);
|
2003-04-15 20:35:07 +00:00
|
|
|
} else
|
|
|
|
*aIsAnonymousContentList = PR_TRUE;
|
2001-02-02 00:54:47 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2003-04-15 20:35:07 +00:00
|
|
|
nsBindingManager::GetAnonymousNodesFor(nsIContent* aContent,
|
|
|
|
nsIDOMNodeList** aResult)
|
|
|
|
{
|
|
|
|
PRBool dummy;
|
|
|
|
return GetAnonymousNodesInternal(aContent, aResult, &dummy);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsBindingManager::SetAnonymousNodesFor(nsIContent* aContent, nsVoidArray* aList)
|
2002-12-02 22:30:26 +00:00
|
|
|
{
|
|
|
|
nsIDOMNodeList* contentList = nsnull;
|
2001-02-02 00:54:47 +00:00
|
|
|
if (aList) {
|
2002-12-02 22:30:26 +00:00
|
|
|
contentList = new nsAnonymousContentList(aList);
|
|
|
|
if (!contentList) return NS_ERROR_OUT_OF_MEMORY;
|
2001-02-02 00:54:47 +00:00
|
|
|
}
|
2002-12-02 22:30:26 +00:00
|
|
|
|
|
|
|
return SetOrRemoveObject(mAnonymousNodesTable, aContent, contentList);
|
2001-02-02 00:54:47 +00:00
|
|
|
}
|
|
|
|
|
2003-04-15 20:35:07 +00:00
|
|
|
nsresult
|
|
|
|
nsBindingManager::GetXBLChildNodesInternal(nsIContent* aContent,
|
|
|
|
nsIDOMNodeList** aResult,
|
|
|
|
PRBool* aIsAnonymousContentList)
|
2001-02-20 01:05:34 +00:00
|
|
|
{
|
2001-02-21 03:18:45 +00:00
|
|
|
*aResult = nsnull;
|
|
|
|
|
2001-02-20 01:05:34 +00:00
|
|
|
PRUint32 length;
|
|
|
|
|
|
|
|
// Retrieve the anonymous content that we should build.
|
2003-04-15 20:35:07 +00:00
|
|
|
GetAnonymousNodesInternal(aContent, aResult, aIsAnonymousContentList);
|
2001-02-20 01:05:34 +00:00
|
|
|
if (*aResult) {
|
|
|
|
(*aResult)->GetLength(&length);
|
|
|
|
if (length == 0)
|
|
|
|
*aResult = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We may have an altered list of children from XBL insertion points.
|
|
|
|
// If we don't have any anonymous kids, we next check to see if we have
|
|
|
|
// insertion points.
|
2001-02-21 03:18:45 +00:00
|
|
|
if (! *aResult) {
|
2002-12-02 22:30:26 +00:00
|
|
|
if (mContentListTable.ops) {
|
|
|
|
*aResult = NS_STATIC_CAST(nsIDOMNodeList*,
|
|
|
|
LookupObject(mContentListTable, aContent));
|
|
|
|
NS_IF_ADDREF(*aResult);
|
2003-04-15 20:35:07 +00:00
|
|
|
*aIsAnonymousContentList = PR_TRUE;
|
2001-02-21 03:18:45 +00:00
|
|
|
}
|
|
|
|
}
|
2003-04-15 20:35:07 +00:00
|
|
|
|
2001-02-20 01:05:34 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2003-04-15 20:35:07 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsBindingManager::GetXBLChildNodesFor(nsIContent* aContent, nsIDOMNodeList** aResult)
|
|
|
|
{
|
|
|
|
PRBool dummy;
|
|
|
|
return GetXBLChildNodesInternal(aContent, aResult, &dummy);
|
|
|
|
}
|
|
|
|
|
2001-02-02 00:54:47 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsBindingManager::GetInsertionPoint(nsIContent* aParent, nsIContent* aChild, nsIContent** aResult, PRUint32* aIndex)
|
2000-05-22 08:23:09 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIXBLBinding> binding;
|
|
|
|
GetBinding(aParent, getter_AddRefs(binding));
|
2001-10-26 00:24:49 +00:00
|
|
|
|
|
|
|
if (!binding) {
|
|
|
|
*aResult = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-05-22 08:23:09 +00:00
|
|
|
|
2001-03-07 01:46:13 +00:00
|
|
|
nsCOMPtr<nsIContent> defContent;
|
2001-10-26 00:24:49 +00:00
|
|
|
return binding->GetInsertionPoint(aChild, aResult, aIndex,
|
|
|
|
getter_AddRefs(defContent));
|
2000-05-22 08:23:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2001-02-02 00:54:47 +00:00
|
|
|
nsBindingManager::GetSingleInsertionPoint(nsIContent* aParent, nsIContent** aResult, PRUint32* aIndex,
|
2000-05-22 08:23:09 +00:00
|
|
|
PRBool* aMultipleInsertionPoints)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIXBLBinding> binding;
|
|
|
|
GetBinding(aParent, getter_AddRefs(binding));
|
|
|
|
|
2001-10-26 00:24:49 +00:00
|
|
|
if (!binding) {
|
|
|
|
*aMultipleInsertionPoints = PR_FALSE;
|
|
|
|
*aResult = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2001-03-07 01:46:13 +00:00
|
|
|
|
2001-10-26 00:24:49 +00:00
|
|
|
nsCOMPtr<nsIContent> defContent;
|
|
|
|
return binding->GetSingleInsertionPoint(aResult, aIndex,
|
|
|
|
aMultipleInsertionPoints,
|
|
|
|
getter_AddRefs(defContent));
|
2000-05-22 08:23:09 +00:00
|
|
|
}
|
|
|
|
|
2000-06-02 08:13:29 +00:00
|
|
|
NS_IMETHODIMP
|
2003-10-01 22:53:56 +00:00
|
|
|
nsBindingManager::AddLayeredBinding(nsIContent* aContent, nsIURI* aURL)
|
2000-06-02 08:13:29 +00:00
|
|
|
{
|
|
|
|
// First we need to load our binding.
|
|
|
|
nsresult rv;
|
2001-07-25 07:54:28 +00:00
|
|
|
nsCOMPtr<nsIXBLService> xblService =
|
|
|
|
do_GetService("@mozilla.org/xbl;1", &rv);
|
2000-06-02 08:13:29 +00:00
|
|
|
if (!xblService)
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
// Load the bindings.
|
2000-07-28 00:35:02 +00:00
|
|
|
nsCOMPtr<nsIXBLBinding> binding;
|
2000-09-08 10:01:18 +00:00
|
|
|
PRBool dummy;
|
|
|
|
xblService->LoadBindings(aContent, aURL, PR_TRUE, getter_AddRefs(binding), &dummy);
|
2000-07-28 00:35:02 +00:00
|
|
|
if (binding) {
|
|
|
|
AddToAttachedQueue(binding);
|
|
|
|
ProcessAttachedQueue();
|
|
|
|
}
|
2000-06-02 08:13:29 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2003-10-01 22:53:56 +00:00
|
|
|
nsBindingManager::RemoveLayeredBinding(nsIContent* aContent, nsIURI* aURL)
|
2000-06-02 08:13:29 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIXBLBinding> binding;
|
2002-10-22 05:28:36 +00:00
|
|
|
GetBinding(aContent, getter_AddRefs(binding));
|
2000-06-02 08:13:29 +00:00
|
|
|
|
2002-10-22 05:28:36 +00:00
|
|
|
if (!binding) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-06-02 08:13:29 +00:00
|
|
|
|
2002-10-22 05:28:36 +00:00
|
|
|
// For now we can only handle removing a binding if it's the only one
|
|
|
|
nsCOMPtr<nsIXBLBinding> nextBinding;
|
|
|
|
binding->GetBaseBinding(getter_AddRefs(nextBinding));
|
|
|
|
NS_ENSURE_FALSE(nextBinding, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
// Make sure that the binding has the URI that is requested to be removed
|
2003-11-17 21:03:32 +00:00
|
|
|
nsIURI* bindingUri = binding->BindingURI();
|
2002-10-22 05:28:36 +00:00
|
|
|
|
|
|
|
PRBool equalUri;
|
2003-11-17 21:03:32 +00:00
|
|
|
nsresult rv = aURL->Equals(bindingUri, &equalUri);
|
2002-10-22 05:28:36 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (!equalUri) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-06-02 08:13:29 +00:00
|
|
|
|
2002-10-22 05:28:36 +00:00
|
|
|
// Make sure it isn't a style binding
|
|
|
|
PRBool style;
|
|
|
|
binding->IsStyleBinding(&style);
|
|
|
|
if (style) {
|
|
|
|
return NS_OK;
|
2000-06-02 08:13:29 +00:00
|
|
|
}
|
2004-09-10 04:57:30 +00:00
|
|
|
|
|
|
|
// Hold strong ref in case removing the binding tries to close the
|
|
|
|
// window or something.
|
2004-10-11 16:14:27 +00:00
|
|
|
// XXXbz should that be ownerdoc? Wouldn't we need a ref to the
|
|
|
|
// currentdoc too? What's the one that should be passed to
|
|
|
|
// ChangeDocument?
|
2004-09-10 04:57:30 +00:00
|
|
|
nsCOMPtr<nsIDocument> doc = aContent->GetOwnerDoc();
|
|
|
|
NS_ASSERTION(doc, "No owner document?");
|
2002-10-22 05:28:36 +00:00
|
|
|
|
|
|
|
// Finally remove the binding...
|
|
|
|
binding->UnhookEventHandlers();
|
|
|
|
binding->ChangeDocument(doc, nsnull);
|
|
|
|
SetBinding(aContent, nsnull);
|
|
|
|
binding->MarkForDeath();
|
|
|
|
|
|
|
|
// ...and recreate it's frames. We need to do this since the frames may have
|
|
|
|
// been removed and style may have changed due to the removal of the
|
|
|
|
// anonymous children.
|
2004-10-11 16:14:27 +00:00
|
|
|
// XXXbz this should be using the current doc (if any), not the owner doc.
|
2003-09-27 04:18:26 +00:00
|
|
|
nsIPresShell *presShell = doc->GetShellAt(0);
|
2002-10-22 05:28:36 +00:00
|
|
|
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
return presShell->RecreateFramesFor(aContent);;
|
2000-06-02 08:13:29 +00:00
|
|
|
}
|
|
|
|
|
2000-08-17 08:11:11 +00:00
|
|
|
NS_IMETHODIMP
|
2003-09-27 04:18:26 +00:00
|
|
|
nsBindingManager::LoadBindingDocument(nsIDocument* aBoundDoc,
|
2003-11-17 21:03:32 +00:00
|
|
|
nsIURI* aURL,
|
2000-09-05 07:29:01 +00:00
|
|
|
nsIDocument** aResult)
|
2000-08-17 08:11:11 +00:00
|
|
|
{
|
2003-11-17 21:03:32 +00:00
|
|
|
NS_PRECONDITION(aURL, "Must have a URI to load!");
|
2000-09-15 06:38:35 +00:00
|
|
|
|
2002-03-06 07:48:55 +00:00
|
|
|
nsCAutoString otherScheme;
|
2003-11-17 21:03:32 +00:00
|
|
|
aURL->GetScheme(otherScheme);
|
|
|
|
|
2002-03-06 07:48:55 +00:00
|
|
|
nsCAutoString scheme;
|
2004-01-09 23:54:21 +00:00
|
|
|
aBoundDoc->GetDocumentURI()->GetScheme(scheme);
|
2000-09-15 06:38:35 +00:00
|
|
|
|
2000-08-17 08:11:11 +00:00
|
|
|
// First we need to load our binding.
|
2000-09-05 07:29:01 +00:00
|
|
|
*aResult = nsnull;
|
2000-08-17 08:11:11 +00:00
|
|
|
nsresult rv;
|
2001-07-25 07:54:28 +00:00
|
|
|
nsCOMPtr<nsIXBLService> xblService =
|
|
|
|
do_GetService("@mozilla.org/xbl;1", &rv);
|
2000-08-17 08:11:11 +00:00
|
|
|
if (!xblService)
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
// Load the binding doc.
|
|
|
|
nsCOMPtr<nsIXBLDocumentInfo> info;
|
2003-11-17 21:03:32 +00:00
|
|
|
xblService->LoadBindingDocumentInfo(nsnull, aBoundDoc, aURL,
|
|
|
|
PR_TRUE, getter_AddRefs(info));
|
2000-08-17 08:11:11 +00:00
|
|
|
if (!info)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2003-11-17 21:03:32 +00:00
|
|
|
// XXXbz Why is this based on a scheme comparison? Shouldn't this
|
|
|
|
// be a real security check???
|
|
|
|
if (!strcmp(scheme.get(), otherScheme.get()))
|
2000-09-15 06:38:35 +00:00
|
|
|
info->GetDocument(aResult); // Addref happens here.
|
|
|
|
|
2000-08-17 08:11:11 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-07-28 00:35:02 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsBindingManager::AddToAttachedQueue(nsIXBLBinding* aBinding)
|
|
|
|
{
|
2003-09-11 02:17:11 +00:00
|
|
|
if (!mAttachedStack)
|
|
|
|
NS_NewISupportsArray(getter_AddRefs(mAttachedStack)); // This call addrefs the array.
|
2000-07-28 00:35:02 +00:00
|
|
|
|
2003-09-11 02:17:11 +00:00
|
|
|
mAttachedStack->AppendElement(aBinding);
|
2000-07-28 00:35:02 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsBindingManager::ClearAttachedQueue()
|
|
|
|
{
|
2003-09-11 02:17:11 +00:00
|
|
|
if (mAttachedStack)
|
|
|
|
mAttachedStack->Clear();
|
2000-07-28 00:35:02 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsBindingManager::ProcessAttachedQueue()
|
|
|
|
{
|
2003-09-11 02:17:11 +00:00
|
|
|
if (!mAttachedStack || mProcessingAttachedStack)
|
2000-07-28 00:35:02 +00:00
|
|
|
return NS_OK;
|
|
|
|
|
2003-09-11 02:17:11 +00:00
|
|
|
mProcessingAttachedStack = PR_TRUE;
|
2003-07-28 10:59:54 +00:00
|
|
|
|
2000-07-28 00:35:02 +00:00
|
|
|
PRUint32 count;
|
2003-09-11 02:17:11 +00:00
|
|
|
while (NS_SUCCEEDED(mAttachedStack->Count(&count)) && count--) {
|
|
|
|
nsCOMPtr<nsIXBLBinding> binding = do_QueryElementAt(mAttachedStack, count);
|
|
|
|
mAttachedStack->RemoveElementAt(count);
|
2000-08-24 09:21:27 +00:00
|
|
|
|
|
|
|
if (binding)
|
|
|
|
binding->ExecuteAttachedHandler();
|
2000-07-28 00:35:02 +00:00
|
|
|
}
|
|
|
|
|
2003-09-11 02:17:11 +00:00
|
|
|
mProcessingAttachedStack = PR_FALSE;
|
2000-07-28 00:35:02 +00:00
|
|
|
ClearAttachedQueue();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-12-02 22:30:26 +00:00
|
|
|
PR_STATIC_CALLBACK(PLDHashOperator)
|
|
|
|
ExecuteDetachedHandler(PLDHashTable* aTable, PLDHashEntryHdr* aHdr, PRUint32 aNumber, void* aClosure)
|
2000-09-08 06:57:03 +00:00
|
|
|
{
|
2002-12-02 22:30:26 +00:00
|
|
|
ObjectEntry* entry = NS_STATIC_CAST(ObjectEntry*, aHdr);
|
|
|
|
nsIXBLBinding* binding = NS_STATIC_CAST(nsIXBLBinding*, entry->GetValue());
|
2000-09-08 06:57:03 +00:00
|
|
|
binding->ExecuteDetachedHandler();
|
2002-12-02 22:30:26 +00:00
|
|
|
return PL_DHASH_NEXT;
|
2000-09-08 06:57:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsBindingManager::ExecuteDetachedHandlers()
|
|
|
|
{
|
|
|
|
// Walk our hashtable of bindings.
|
2002-12-02 22:30:26 +00:00
|
|
|
if (mBindingTable.ops)
|
|
|
|
PL_DHashTableEnumerate(&mBindingTable, ExecuteDetachedHandler, nsnull);
|
2000-09-08 06:57:03 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-08-05 22:33:29 +00:00
|
|
|
NS_IMETHODIMP
|
2000-08-12 06:28:02 +00:00
|
|
|
nsBindingManager::PutXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo)
|
2000-08-05 22:33:29 +00:00
|
|
|
{
|
2003-11-17 21:03:32 +00:00
|
|
|
NS_PRECONDITION(aDocumentInfo, "Must have a non-null documentinfo!");
|
|
|
|
|
|
|
|
NS_ENSURE_TRUE(mDocumentTable.IsInitialized() || mDocumentTable.Init(16),
|
|
|
|
NS_ERROR_OUT_OF_MEMORY);
|
2002-12-02 22:30:26 +00:00
|
|
|
|
2003-11-17 21:03:32 +00:00
|
|
|
NS_ENSURE_TRUE(mDocumentTable.Put(aDocumentInfo->DocumentURI(),
|
|
|
|
aDocumentInfo),
|
|
|
|
NS_ERROR_OUT_OF_MEMORY);
|
2002-12-02 22:30:26 +00:00
|
|
|
|
2000-08-05 22:33:29 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-11-02 01:53:13 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsBindingManager::RemoveXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo)
|
|
|
|
{
|
2003-11-17 21:03:32 +00:00
|
|
|
if (!mDocumentTable.IsInitialized())
|
2001-11-02 01:53:13 +00:00
|
|
|
return NS_OK;
|
|
|
|
|
2003-11-17 21:03:32 +00:00
|
|
|
mDocumentTable.Remove(aDocumentInfo->DocumentURI());
|
2001-11-02 01:53:13 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-08-05 22:33:29 +00:00
|
|
|
NS_IMETHODIMP
|
2003-11-17 21:03:32 +00:00
|
|
|
nsBindingManager::GetXBLDocumentInfo(nsIURI* aURL, nsIXBLDocumentInfo** aResult)
|
2000-08-05 22:33:29 +00:00
|
|
|
{
|
|
|
|
*aResult = nsnull;
|
2003-11-17 21:03:32 +00:00
|
|
|
if (!mDocumentTable.IsInitialized())
|
2000-08-05 22:33:29 +00:00
|
|
|
return NS_OK;
|
|
|
|
|
2003-11-17 21:03:32 +00:00
|
|
|
mDocumentTable.Get(aURL, aResult);
|
2000-08-05 22:33:29 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-08-06 04:57:55 +00:00
|
|
|
NS_IMETHODIMP
|
2003-11-17 21:03:32 +00:00
|
|
|
nsBindingManager::PutLoadingDocListener(nsIURI* aURL, nsIStreamListener* aListener)
|
2000-08-06 04:57:55 +00:00
|
|
|
{
|
2003-11-17 21:03:32 +00:00
|
|
|
NS_PRECONDITION(aListener, "Must have a non-null listener!");
|
|
|
|
|
|
|
|
NS_ENSURE_TRUE(mLoadingDocTable.IsInitialized() || mLoadingDocTable.Init(16),
|
|
|
|
NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
|
|
|
NS_ENSURE_TRUE(mLoadingDocTable.Put(aURL, aListener),
|
|
|
|
NS_ERROR_OUT_OF_MEMORY);
|
2000-08-06 04:57:55 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2003-11-17 21:03:32 +00:00
|
|
|
nsBindingManager::GetLoadingDocListener(nsIURI* aURL, nsIStreamListener** aResult)
|
2000-08-06 04:57:55 +00:00
|
|
|
{
|
|
|
|
*aResult = nsnull;
|
2003-11-17 21:03:32 +00:00
|
|
|
if (!mLoadingDocTable.IsInitialized())
|
2000-08-06 04:57:55 +00:00
|
|
|
return NS_OK;
|
|
|
|
|
2003-11-17 21:03:32 +00:00
|
|
|
mLoadingDocTable.Get(aURL, aResult);
|
2000-08-06 04:57:55 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2003-11-17 21:03:32 +00:00
|
|
|
nsBindingManager::RemoveLoadingDocListener(nsIURI* aURL)
|
2000-08-06 04:57:55 +00:00
|
|
|
{
|
2003-11-17 21:03:32 +00:00
|
|
|
if (!mLoadingDocTable.IsInitialized())
|
2000-08-06 04:57:55 +00:00
|
|
|
return NS_OK;
|
|
|
|
|
2002-12-02 22:30:26 +00:00
|
|
|
mLoadingDocTable.Remove(aURL);
|
2000-08-06 04:57:55 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
2000-08-14 04:04:18 +00:00
|
|
|
}
|
|
|
|
|
2002-12-02 22:30:26 +00:00
|
|
|
PR_STATIC_CALLBACK(PLDHashOperator)
|
|
|
|
MarkForDeath(PLDHashTable* aTable, PLDHashEntryHdr* aHdr, PRUint32 aNumber, void* aClosure)
|
2000-08-14 04:04:18 +00:00
|
|
|
{
|
2002-12-02 22:30:26 +00:00
|
|
|
ObjectEntry* entry = NS_STATIC_CAST(ObjectEntry*, aHdr);
|
|
|
|
nsIXBLBinding* binding = NS_STATIC_CAST(nsIXBLBinding*, entry->GetValue());
|
|
|
|
|
2001-12-17 22:51:39 +00:00
|
|
|
PRBool marked = PR_FALSE;
|
|
|
|
binding->MarkedForDeath(&marked);
|
|
|
|
if (marked)
|
2002-12-02 22:30:26 +00:00
|
|
|
return PL_DHASH_NEXT; // Already marked for death.
|
2001-12-17 22:51:39 +00:00
|
|
|
|
2003-11-17 21:03:32 +00:00
|
|
|
nsCAutoString path;
|
2003-11-17 21:41:13 +00:00
|
|
|
binding->DocURI()->GetPath(path);
|
2003-11-17 21:03:32 +00:00
|
|
|
|
|
|
|
if (!strncmp(path.get(), "/skin", 5))
|
|
|
|
binding->MarkForDeath();
|
|
|
|
|
2002-12-02 22:30:26 +00:00
|
|
|
return PL_DHASH_NEXT;
|
2000-08-14 04:04:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2001-12-17 22:51:39 +00:00
|
|
|
nsBindingManager::FlushSkinBindings()
|
2000-08-14 04:04:18 +00:00
|
|
|
{
|
2002-12-02 22:30:26 +00:00
|
|
|
if (mBindingTable.ops)
|
|
|
|
PL_DHashTableEnumerate(&mBindingTable, MarkForDeath, nsnull);
|
2000-08-14 04:04:18 +00:00
|
|
|
return NS_OK;
|
2000-08-06 04:57:55 +00:00
|
|
|
}
|
2000-08-05 22:33:29 +00:00
|
|
|
|
2001-09-22 00:24:24 +00:00
|
|
|
// Used below to protect from recurring in QI calls through XPConnect.
|
|
|
|
struct AntiRecursionData {
|
|
|
|
nsIContent* element;
|
|
|
|
REFNSIID iid;
|
|
|
|
AntiRecursionData* next;
|
|
|
|
|
|
|
|
AntiRecursionData(nsIContent* aElement,
|
|
|
|
REFNSIID aIID,
|
|
|
|
AntiRecursionData* aNext)
|
|
|
|
: element(aElement), iid(aIID), next(aNext) {}
|
|
|
|
};
|
|
|
|
|
2000-12-07 10:11:21 +00:00
|
|
|
NS_IMETHODIMP
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
nsBindingManager::GetBindingImplementation(nsIContent* aContent, REFNSIID aIID,
|
|
|
|
void** aResult)
|
2000-12-07 10:11:21 +00:00
|
|
|
{
|
|
|
|
*aResult = nsnull;
|
|
|
|
nsCOMPtr<nsIXBLBinding> binding;
|
|
|
|
GetBinding(aContent, getter_AddRefs(binding));
|
|
|
|
if (binding) {
|
|
|
|
PRBool supportsInterface;
|
2003-05-13 23:27:33 +00:00
|
|
|
// The binding should not be asked for nsISupports
|
|
|
|
NS_ASSERTION(!aIID.Equals(NS_GET_IID(nsISupports)), "Asking a binding for nsISupports");
|
2000-12-07 10:11:21 +00:00
|
|
|
binding->ImplementsInterface(aIID, &supportsInterface);
|
|
|
|
if (supportsInterface) {
|
|
|
|
nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS;
|
|
|
|
GetWrappedJS(aContent, getter_AddRefs(wrappedJS));
|
|
|
|
|
2001-09-07 01:26:00 +00:00
|
|
|
if (wrappedJS) {
|
2001-09-22 00:24:24 +00:00
|
|
|
// Protect from recurring in QI calls through XPConnect.
|
|
|
|
// This can happen when a second binding is being resolved.
|
|
|
|
// At that point a wrappedJS exists, but it doesn't yet know about
|
|
|
|
// the iid we are asking for. So, without this protection,
|
|
|
|
// AggregatedQueryInterface would end up recurring back into itself
|
|
|
|
// through this code.
|
|
|
|
//
|
|
|
|
// With this protection, when we detect the recursion we return
|
|
|
|
// NS_NOINTERFACE in the inner call. The outer call will then fall
|
|
|
|
// through (see below) and build a new chained wrappedJS for the iid.
|
|
|
|
//
|
|
|
|
// We're careful to not assume that only one direct nesting can occur
|
|
|
|
// because there is a call into JS in the middle and we can't assume
|
|
|
|
// that this code won't be reached by some more complex nesting path.
|
|
|
|
//
|
|
|
|
// NOTE: We *assume* this is single threaded, so we can use a
|
|
|
|
// static linked list to do the check.
|
|
|
|
|
|
|
|
static AntiRecursionData* list = nsnull;
|
|
|
|
|
|
|
|
for (AntiRecursionData* p = list; p; p = p->next) {
|
|
|
|
if (p->element == aContent && p->iid.Equals(aIID)) {
|
|
|
|
*aResult = nsnull;
|
|
|
|
return NS_NOINTERFACE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
AntiRecursionData item(aContent, aIID, list);
|
|
|
|
list = &item;
|
|
|
|
|
2001-09-07 01:26:00 +00:00
|
|
|
nsresult rv = wrappedJS->AggregatedQueryInterface(aIID, aResult);
|
2001-09-22 00:24:24 +00:00
|
|
|
|
|
|
|
list = item.next;
|
|
|
|
|
2001-09-07 01:26:00 +00:00
|
|
|
if (*aResult)
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
// No result was found, so this must be another XBL interface.
|
|
|
|
// Fall through to create a new wrapper.
|
|
|
|
}
|
2000-12-07 10:11:21 +00:00
|
|
|
|
|
|
|
// We have never made a wrapper for this implementation.
|
|
|
|
// Create an XPC wrapper for the script object and hand it back.
|
|
|
|
|
2003-07-28 21:17:26 +00:00
|
|
|
nsIDocument* doc = aContent->GetDocument();
|
2000-12-07 10:11:21 +00:00
|
|
|
if (!doc)
|
|
|
|
return NS_NOINTERFACE;
|
|
|
|
|
2003-10-22 06:09:48 +00:00
|
|
|
nsIScriptGlobalObject *global = doc->GetScriptGlobalObject();
|
2000-12-07 10:11:21 +00:00
|
|
|
if (!global)
|
|
|
|
return NS_NOINTERFACE;
|
|
|
|
|
2004-02-09 22:48:53 +00:00
|
|
|
nsIScriptContext *context = global->GetContext();
|
2000-12-07 10:11:21 +00:00
|
|
|
if (!context)
|
|
|
|
return NS_NOINTERFACE;
|
|
|
|
|
|
|
|
JSContext* jscontext = (JSContext*)context->GetNativeContext();
|
|
|
|
if (!jscontext)
|
|
|
|
return NS_NOINTERFACE;
|
|
|
|
|
2004-09-01 16:50:12 +00:00
|
|
|
nsIXPConnect *xpConnect = nsContentUtils::XPConnect();
|
2000-12-07 10:11:21 +00:00
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
|
|
|
|
xpConnect->GetWrappedNativeOfNativeObject(jscontext,
|
|
|
|
JS_GetGlobalObject(jscontext),
|
|
|
|
aContent,
|
|
|
|
NS_GET_IID(nsISupports),
|
|
|
|
getter_AddRefs(wrapper));
|
|
|
|
NS_ENSURE_TRUE(wrapper, NS_NOINTERFACE);
|
|
|
|
|
|
|
|
JSObject* jsobj = nsnull;
|
|
|
|
|
|
|
|
wrapper->GetJSObject(&jsobj);
|
|
|
|
NS_ENSURE_TRUE(jsobj, NS_NOINTERFACE);
|
|
|
|
|
|
|
|
nsresult rv = xpConnect->WrapJSAggregatedToNative(aContent, jscontext,
|
|
|
|
jsobj, aIID, aResult);
|
2000-12-07 10:11:21 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
// We successfully created a wrapper. We will own this wrapper for as long as the binding remains
|
|
|
|
// alive. At the time the binding is cleared out of the bindingManager, we will remove the wrapper
|
|
|
|
// from the bindingManager as well.
|
|
|
|
nsISupports* supp = NS_STATIC_CAST(nsISupports*, *aResult);
|
|
|
|
wrappedJS = do_QueryInterface(supp);
|
|
|
|
SetWrappedJS(aContent, wrappedJS);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*aResult = nsnull;
|
|
|
|
return NS_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
2000-08-12 06:28:02 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsBindingManager::InheritsStyle(nsIContent* aContent, PRBool* aResult)
|
|
|
|
{
|
|
|
|
// Get our enclosing parent.
|
|
|
|
*aResult = PR_TRUE;
|
2003-07-28 21:17:26 +00:00
|
|
|
nsCOMPtr<nsIContent> parent = GetEnclosingScope(aContent);
|
2000-08-12 06:28:02 +00:00
|
|
|
if (parent) {
|
|
|
|
// See if the parent is our parent.
|
2003-07-28 21:17:26 +00:00
|
|
|
if (aContent->GetParent() == parent) {
|
2000-08-12 06:28:02 +00:00
|
|
|
// Yes. Check the binding and see if it wants to allow us
|
|
|
|
// to inherit styles.
|
|
|
|
nsCOMPtr<nsIXBLBinding> binding;
|
|
|
|
GetBinding(parent, getter_AddRefs(binding));
|
|
|
|
if (binding)
|
|
|
|
binding->InheritsStyle(aResult);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2004-09-10 04:57:30 +00:00
|
|
|
nsBindingManager::WalkRules(nsStyleSet* aStyleSet,
|
|
|
|
nsIStyleRuleProcessor::EnumFunc aFunc,
|
|
|
|
RuleProcessorData* aData,
|
|
|
|
PRBool* aCutOffInheritance)
|
2000-08-12 06:28:02 +00:00
|
|
|
{
|
2004-09-10 04:57:30 +00:00
|
|
|
*aCutOffInheritance = PR_FALSE;
|
|
|
|
|
|
|
|
if (!aData->mContent)
|
2000-08-12 06:28:02 +00:00
|
|
|
return NS_OK;
|
|
|
|
|
2004-09-10 04:57:30 +00:00
|
|
|
// Walk the binding scope chain, starting with the binding attached to our
|
|
|
|
// content, up till we run out of scopes or we get cut off.
|
|
|
|
nsIContent *content = aData->mContent;
|
|
|
|
|
|
|
|
do {
|
2000-08-12 06:28:02 +00:00
|
|
|
nsCOMPtr<nsIXBLBinding> binding;
|
2004-09-10 04:57:30 +00:00
|
|
|
GetBinding(content, getter_AddRefs(binding));
|
2000-08-12 06:28:02 +00:00
|
|
|
if (binding) {
|
2004-09-10 04:57:30 +00:00
|
|
|
aData->mScopedRoot = content;
|
|
|
|
binding->WalkRules(aFunc, aData);
|
|
|
|
// If we're not looking at our original content, allow the binding to cut
|
|
|
|
// off style inheritance
|
|
|
|
if (content != aData->mContent) {
|
|
|
|
PRBool inheritsStyle = PR_TRUE;
|
|
|
|
binding->InheritsStyle(&inheritsStyle);
|
|
|
|
if (!inheritsStyle) {
|
|
|
|
// Go no further; we're not inheriting style from anything above here
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2000-08-12 06:28:02 +00:00
|
|
|
}
|
|
|
|
|
2004-09-10 04:57:30 +00:00
|
|
|
nsIContent* parent = GetEnclosingScope(content);
|
|
|
|
if (parent == content)
|
|
|
|
break; // The scrollbar case only is deliberately hacked to return itself
|
|
|
|
// (see GetBindingParent in nsXULElement.cpp). Actually, all
|
|
|
|
// native anonymous content is thus hacked. Cut off inheritance
|
|
|
|
// here.
|
2000-08-12 06:28:02 +00:00
|
|
|
|
2004-09-10 04:57:30 +00:00
|
|
|
content = parent;
|
|
|
|
} while (content);
|
2001-11-10 23:51:45 +00:00
|
|
|
|
2004-09-10 04:57:30 +00:00
|
|
|
// If "content" is non-null that means we cut off inheritance at some point
|
|
|
|
// in the loop.
|
|
|
|
*aCutOffInheritance = (content != nsnull);
|
2000-08-12 06:28:02 +00:00
|
|
|
|
2004-09-10 04:57:30 +00:00
|
|
|
// Null out the scoped root that we set repeatedly
|
2001-11-10 23:51:45 +00:00
|
|
|
aData->mScopedRoot = nsnull;
|
2000-08-25 00:19:38 +00:00
|
|
|
|
2000-08-12 06:28:02 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-12-07 10:11:21 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsBindingManager::ShouldBuildChildFrames(nsIContent* aContent, PRBool* aResult)
|
|
|
|
{
|
|
|
|
*aResult = PR_TRUE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIXBLBinding> binding;
|
|
|
|
GetBinding(aContent, getter_AddRefs(binding));
|
|
|
|
|
|
|
|
if (binding)
|
|
|
|
return binding->ShouldBuildChildFrames(aResult);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-08-12 06:28:02 +00:00
|
|
|
|
2001-02-07 07:45:36 +00:00
|
|
|
nsresult
|
|
|
|
nsBindingManager::GetNestedInsertionPoint(nsIContent* aParent, nsIContent* aChild, nsIContent** aResult)
|
|
|
|
{
|
|
|
|
*aResult = nsnull;
|
|
|
|
|
|
|
|
// Check to see if the content is anonymous.
|
2003-07-28 21:17:26 +00:00
|
|
|
if (aChild->GetBindingParent() == aParent)
|
2001-02-07 07:45:36 +00:00
|
|
|
return NS_OK; // It is anonymous. Don't use the insertion point, since that's only
|
|
|
|
// for the explicit kids.
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> insertionElement;
|
|
|
|
PRUint32 index;
|
|
|
|
GetInsertionPoint(aParent, aChild, getter_AddRefs(insertionElement), &index);
|
2001-02-08 23:24:55 +00:00
|
|
|
if (insertionElement != aParent) {
|
2001-02-07 07:45:36 +00:00
|
|
|
// See if we nest even further in.
|
|
|
|
nsCOMPtr<nsIContent> nestedPoint;
|
|
|
|
GetNestedInsertionPoint(insertionElement, aChild, getter_AddRefs(nestedPoint));
|
|
|
|
if (nestedPoint)
|
|
|
|
insertionElement = nestedPoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
*aResult = insertionElement;
|
|
|
|
NS_IF_ADDREF(*aResult);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2004-01-24 00:46:17 +00:00
|
|
|
void
|
2001-02-07 07:45:36 +00:00
|
|
|
nsBindingManager::ContentAppended(nsIDocument* aDocument,
|
2004-01-28 21:04:33 +00:00
|
|
|
nsIContent* aContainer,
|
2001-02-07 07:45:36 +00:00
|
|
|
PRInt32 aNewIndexInContainer)
|
|
|
|
{
|
|
|
|
// XXX This is hacked and not quite correct. See below.
|
2002-12-02 22:30:26 +00:00
|
|
|
if (aNewIndexInContainer == -1 || !mContentListTable.ops)
|
2001-02-07 07:45:36 +00:00
|
|
|
// It's anonymous.
|
2004-01-24 00:46:17 +00:00
|
|
|
return;
|
2001-02-07 07:45:36 +00:00
|
|
|
|
2003-09-27 04:18:26 +00:00
|
|
|
PRInt32 childCount = aContainer->GetChildCount();
|
|
|
|
|
|
|
|
nsIContent *child = aContainer->GetChildAt(aNewIndexInContainer);
|
|
|
|
|
2001-02-07 07:45:36 +00:00
|
|
|
nsCOMPtr<nsIContent> ins;
|
|
|
|
GetNestedInsertionPoint(aContainer, child, getter_AddRefs(ins));
|
|
|
|
|
|
|
|
if (ins) {
|
2001-10-25 07:31:18 +00:00
|
|
|
nsCOMPtr<nsIDOMNodeList> nodeList;
|
2003-04-15 20:35:07 +00:00
|
|
|
PRBool isAnonymousContentList;
|
|
|
|
GetXBLChildNodesInternal(ins, getter_AddRefs(nodeList),
|
|
|
|
&isAnonymousContentList);
|
|
|
|
|
|
|
|
if (nodeList && isAnonymousContentList) {
|
|
|
|
// Find a non-pseudo-insertion point and just jam ourselves in.
|
|
|
|
// This is not 100% correct. Hack city, baby.
|
|
|
|
nsAnonymousContentList* contentList = NS_STATIC_CAST(nsAnonymousContentList*, NS_STATIC_CAST(nsIDOMNodeList*, nodeList.get()));
|
|
|
|
|
|
|
|
PRInt32 count = contentList->GetInsertionPointCount();
|
|
|
|
for (PRInt32 i = 0; i < count; i++) {
|
|
|
|
nsXBLInsertionPoint* point = contentList->GetInsertionPointAt(i);
|
|
|
|
PRInt32 index = point->GetInsertionIndex();
|
|
|
|
if (index != -1) {
|
|
|
|
// We're real. Jam all the kids in.
|
|
|
|
// XXX Check the filters to find the correct points.
|
|
|
|
for (PRInt32 j = aNewIndexInContainer; j < childCount; j++) {
|
2003-09-27 04:18:26 +00:00
|
|
|
child = aContainer->GetChildAt(j);
|
2003-04-15 20:35:07 +00:00
|
|
|
point->AddChild(child);
|
|
|
|
SetInsertionParent(child, ins);
|
2001-02-07 07:45:36 +00:00
|
|
|
}
|
2003-04-15 20:35:07 +00:00
|
|
|
break;
|
2001-02-07 07:45:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-01-24 00:46:17 +00:00
|
|
|
void
|
2001-02-07 07:45:36 +00:00
|
|
|
nsBindingManager::ContentInserted(nsIDocument* aDocument,
|
2003-04-15 20:35:07 +00:00
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInContainer)
|
2001-02-07 07:45:36 +00:00
|
|
|
{
|
|
|
|
// XXX This is hacked just to make menus work again.
|
2002-12-02 22:30:26 +00:00
|
|
|
if (aIndexInContainer == -1 || !mContentListTable.ops)
|
2001-02-07 07:45:36 +00:00
|
|
|
// It's anonymous.
|
2004-01-24 00:46:17 +00:00
|
|
|
return;
|
|
|
|
|
2001-02-07 07:45:36 +00:00
|
|
|
nsCOMPtr<nsIContent> ins;
|
|
|
|
GetNestedInsertionPoint(aContainer, aChild, getter_AddRefs(ins));
|
|
|
|
|
|
|
|
if (ins) {
|
2001-10-25 07:31:18 +00:00
|
|
|
nsCOMPtr<nsIDOMNodeList> nodeList;
|
2003-04-15 20:35:07 +00:00
|
|
|
PRBool isAnonymousContentList;
|
|
|
|
GetXBLChildNodesInternal(ins, getter_AddRefs(nodeList),
|
|
|
|
&isAnonymousContentList);
|
|
|
|
|
|
|
|
if (nodeList && isAnonymousContentList) {
|
|
|
|
// Find a non-pseudo-insertion point and just jam ourselves in.
|
|
|
|
// This is not 100% correct. Hack city, baby.
|
|
|
|
nsAnonymousContentList* contentList = NS_STATIC_CAST(nsAnonymousContentList*, NS_STATIC_CAST(nsIDOMNodeList*, nodeList.get()));
|
|
|
|
|
|
|
|
PRInt32 count = contentList->GetInsertionPointCount();
|
|
|
|
for (PRInt32 i = 0; i < count; i++) {
|
|
|
|
nsXBLInsertionPoint* point = contentList->GetInsertionPointAt(i);
|
|
|
|
if (point->GetInsertionIndex() != -1) {
|
|
|
|
// We're real. Jam the kid in.
|
|
|
|
// XXX Check the filters to find the correct points.
|
2004-03-02 22:28:48 +00:00
|
|
|
|
|
|
|
// Find the right insertion spot. Can't just insert in the insertion
|
|
|
|
// point at aIndexInContainer since the point may contain anonymous
|
|
|
|
// content, not all of aContainer's kids, etc. So find the last
|
|
|
|
// child of aContainer that comes before aIndexInContainer and is in
|
|
|
|
// the insertion point and insert right after it.
|
|
|
|
PRInt32 pointSize = point->ChildCount();
|
|
|
|
PRBool inserted = PR_FALSE;
|
|
|
|
for (PRInt32 parentIndex = aIndexInContainer - 1;
|
|
|
|
parentIndex >= 0 && !inserted; --parentIndex) {
|
|
|
|
nsIContent* currentSibling = aContainer->GetChildAt(parentIndex);
|
|
|
|
for (PRInt32 pointIndex = pointSize - 1; pointIndex >= 0;
|
|
|
|
--pointIndex) {
|
|
|
|
nsCOMPtr<nsIContent> currContent = point->ChildAt(pointIndex);
|
|
|
|
if (currContent == currentSibling) {
|
|
|
|
point->InsertChildAt(pointIndex + 1, aChild);
|
|
|
|
inserted = PR_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!inserted) {
|
|
|
|
// None of our previous siblings are in here... just stick
|
2004-03-10 23:53:09 +00:00
|
|
|
// ourselves in at the beginning of the insertion point.
|
2004-03-02 22:28:48 +00:00
|
|
|
// XXXbz if we ever start doing the filter thing right, this may be
|
|
|
|
// no good, since we may _still_ have anonymous kids in there and
|
|
|
|
// may need to get the ordering with those right.
|
2004-03-10 23:53:09 +00:00
|
|
|
point->InsertChildAt(0, aChild);
|
2004-03-02 22:28:48 +00:00
|
|
|
}
|
2003-04-15 20:35:07 +00:00
|
|
|
SetInsertionParent(aChild, ins);
|
|
|
|
break;
|
2001-02-07 07:45:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-01-24 00:46:17 +00:00
|
|
|
void
|
2001-02-07 07:45:36 +00:00
|
|
|
nsBindingManager::ContentRemoved(nsIDocument* aDocument,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInContainer)
|
|
|
|
{
|
2002-12-02 22:30:26 +00:00
|
|
|
if (aIndexInContainer == -1 || !mContentListTable.ops)
|
2001-02-07 07:45:36 +00:00
|
|
|
// It's anonymous.
|
2004-01-24 00:46:17 +00:00
|
|
|
return;
|
|
|
|
|
2001-02-07 07:45:36 +00:00
|
|
|
nsCOMPtr<nsIContent> point;
|
|
|
|
GetNestedInsertionPoint(aContainer, aChild, getter_AddRefs(point));
|
|
|
|
|
|
|
|
if (point) {
|
2001-10-25 07:31:18 +00:00
|
|
|
nsCOMPtr<nsIDOMNodeList> nodeList;
|
2003-04-15 20:35:07 +00:00
|
|
|
PRBool isAnonymousContentList;
|
|
|
|
GetXBLChildNodesInternal(point, getter_AddRefs(nodeList),
|
|
|
|
&isAnonymousContentList);
|
|
|
|
|
|
|
|
if (nodeList && isAnonymousContentList) {
|
|
|
|
// Find a non-pseudo-insertion point and remove ourselves.
|
|
|
|
nsAnonymousContentList* contentList = NS_STATIC_CAST(nsAnonymousContentList*, NS_STATIC_CAST(nsIDOMNodeList*, nodeList));
|
|
|
|
PRInt32 count = contentList->GetInsertionPointCount();
|
|
|
|
for (PRInt32 i =0; i < count; i++) {
|
|
|
|
nsXBLInsertionPoint* point = contentList->GetInsertionPointAt(i);
|
|
|
|
if (point->GetInsertionIndex() != -1) {
|
|
|
|
point->RemoveChild(aChild);
|
2001-02-07 07:45:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-03-02 22:28:48 +00:00
|
|
|
|
2000-05-09 21:42:57 +00:00
|
|
|
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
NS_NewBindingManager(nsIBindingManager** aResult)
|
|
|
|
{
|
|
|
|
*aResult = new nsBindingManager;
|
|
|
|
if (!*aResult)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
NS_ADDREF(*aResult);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|