зеркало из https://github.com/mozilla/pjs.git
Back last checkin out till I get the windows casting stuff settled out....
This commit is contained in:
Родитель
1db949551e
Коммит
13fd7bf0c1
|
@ -52,8 +52,6 @@
|
|||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "nsIContentList.h"
|
||||
|
||||
#include "pldhash.h"
|
||||
|
||||
nsBaseContentList::nsBaseContentList()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
@ -274,117 +272,15 @@ nsFormContentList::Reset()
|
|||
return nsBaseContentList::Reset();
|
||||
}
|
||||
|
||||
// Hashtable for storing nsContentLists
|
||||
static PLDHashTable gContentListHashTable;
|
||||
|
||||
struct ContentListHashEntry : public PLDHashEntryHdr
|
||||
{
|
||||
nsContentList* mContentList;
|
||||
};
|
||||
|
||||
PR_STATIC_CALLBACK(const void *)
|
||||
ContentListHashtableGetKey(PLDHashTable *table, PLDHashEntryHdr *entry)
|
||||
{
|
||||
ContentListHashEntry *e = NS_STATIC_CAST(ContentListHashEntry *, entry);
|
||||
return NS_STATIC_CAST(nsContentListKey*, e->mContentList);
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(PLDHashNumber)
|
||||
ContentListHashtableHashKey(PLDHashTable *table, const void *key)
|
||||
{
|
||||
const nsContentListKey* list = NS_STATIC_CAST(const nsContentListKey *, key);
|
||||
return list->GetHash();
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(PRBool)
|
||||
ContentListHashtableMatchEntry(PLDHashTable *table,
|
||||
const PLDHashEntryHdr *entry,
|
||||
const void *key)
|
||||
{
|
||||
const ContentListHashEntry *e =
|
||||
NS_STATIC_CAST(const ContentListHashEntry *, entry);
|
||||
const nsContentListKey* list1 = NS_STATIC_CAST(nsContentListKey*, e->mContentList);
|
||||
const nsContentListKey* list2 = NS_STATIC_CAST(const nsContentListKey *, key);
|
||||
|
||||
return list1->Equals(*list2);
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_GetContentList(nsIDocument* aDocument, nsIAtom* aMatchAtom,
|
||||
PRInt32 aMatchNameSpaceId, nsIContent* aRootContent,
|
||||
nsIContentList** aInstancePtrResult)
|
||||
{
|
||||
*aInstancePtrResult = nsnull;
|
||||
nsContentList* list = nsnull;
|
||||
|
||||
static PLDHashTableOps hash_table_ops =
|
||||
{
|
||||
PL_DHashAllocTable,
|
||||
PL_DHashFreeTable,
|
||||
ContentListHashtableGetKey,
|
||||
ContentListHashtableHashKey,
|
||||
ContentListHashtableMatchEntry,
|
||||
PL_DHashMoveEntryStub,
|
||||
PL_DHashClearEntryStub,
|
||||
PL_DHashFinalizeStub
|
||||
};
|
||||
|
||||
// Initialize the hashtable if needed.
|
||||
if (!gContentListHashTable.ops) {
|
||||
PRBool success = PL_DHashTableInit(&gContentListHashTable,
|
||||
&hash_table_ops, nsnull,
|
||||
sizeof(ContentListHashEntry),
|
||||
16);
|
||||
|
||||
if (!success) {
|
||||
gContentListHashTable.ops = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
ContentListHashEntry *entry = nsnull;
|
||||
// First we look in our hashtable. Then we create a content list if needed
|
||||
if (gContentListHashTable.ops) {
|
||||
nsContentListKey hashKey(aDocument, aMatchAtom,
|
||||
aMatchNameSpaceId, aRootContent);
|
||||
|
||||
// A PL_DHASH_ADD is equivalent to a PL_DHASH_LOOKUP for cases
|
||||
// when the entry is already in the hashtable.
|
||||
entry = NS_STATIC_CAST(ContentListHashEntry *,
|
||||
PL_DHashTableOperate(&gContentListHashTable,
|
||||
&hashKey,
|
||||
PL_DHASH_ADD));
|
||||
if (entry)
|
||||
list = entry->mContentList;
|
||||
}
|
||||
|
||||
if (!list) {
|
||||
// We need to create a ContentList and add it to our new entry, if
|
||||
// we have an entry
|
||||
list = new nsContentList(aDocument, aMatchAtom,
|
||||
aMatchNameSpaceId, aRootContent);
|
||||
if (entry) {
|
||||
if (list)
|
||||
entry->mContentList = list;
|
||||
else
|
||||
PL_DHashTableRawRemove(&gContentListHashTable, entry);
|
||||
}
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
*aInstancePtrResult = list;
|
||||
NS_ADDREF(*aInstancePtrResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// nsContentList implementation
|
||||
|
||||
nsContentList::nsContentList(const nsContentList& aContentList)
|
||||
: nsBaseContentList(), nsContentListKey(aContentList)
|
||||
: nsBaseContentList()
|
||||
{
|
||||
mFunc = aContentList.mFunc;
|
||||
mMatchAtom = aContentList.mMatchAtom;
|
||||
mDocument = aContentList.mDocument;
|
||||
|
||||
if (aContentList.mData) {
|
||||
mData = new nsString(*aContentList.mData);
|
||||
|
@ -393,31 +289,39 @@ nsContentList::nsContentList(const nsContentList& aContentList)
|
|||
}
|
||||
|
||||
mMatchAll = aContentList.mMatchAll;
|
||||
mRootContent = aContentList.mRootContent;
|
||||
mElements = aContentList.mElements;
|
||||
}
|
||||
|
||||
nsContentList::nsContentList(nsIDocument *aDocument)
|
||||
: nsBaseContentList(), nsContentListKey(aDocument, nsnull, kNameSpaceID_Unknown, nsnull)
|
||||
: nsBaseContentList()
|
||||
{
|
||||
mFunc = nsnull;
|
||||
mMatchAtom = nsnull;
|
||||
mDocument = aDocument;
|
||||
mData = nsnull;
|
||||
mMatchAll = PR_FALSE;
|
||||
mRootContent = nsnull;
|
||||
}
|
||||
|
||||
nsContentList::nsContentList(nsIDocument *aDocument,
|
||||
nsIAtom* aMatchAtom,
|
||||
PRInt32 aMatchNameSpaceId,
|
||||
nsIContent* aRootContent)
|
||||
: nsBaseContentList(), nsContentListKey(aDocument, aMatchAtom, aMatchNameSpaceId, aRootContent)
|
||||
: nsBaseContentList()
|
||||
{
|
||||
mMatchAtom = aMatchAtom;
|
||||
NS_IF_ADDREF(mMatchAtom);
|
||||
if (nsLayoutAtoms::wildcard == mMatchAtom) {
|
||||
mMatchAll = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
mMatchAll = PR_FALSE;
|
||||
}
|
||||
mMatchNameSpaceId = aMatchNameSpaceId;
|
||||
mFunc = nsnull;
|
||||
mData = nsnull;
|
||||
mRootContent = aRootContent;
|
||||
Init(aDocument);
|
||||
}
|
||||
|
||||
|
@ -425,7 +329,7 @@ nsContentList::nsContentList(nsIDocument *aDocument,
|
|||
nsContentListMatchFunc aFunc,
|
||||
const nsAString& aData,
|
||||
nsIContent* aRootContent)
|
||||
: nsBaseContentList(), nsContentListKey(aDocument, nsnull, kNameSpaceID_Unknown, aRootContent)
|
||||
: nsBaseContentList()
|
||||
{
|
||||
mFunc = aFunc;
|
||||
if (!aData.IsEmpty()) {
|
||||
|
@ -457,11 +361,12 @@ void nsContentList::Init(nsIDocument *aDocument)
|
|||
|
||||
nsContentList::~nsContentList()
|
||||
{
|
||||
RemoveFromHashtable();
|
||||
if (mDocument) {
|
||||
mDocument->RemoveObserver(this);
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(mMatchAtom);
|
||||
|
||||
delete mData;
|
||||
}
|
||||
|
||||
|
@ -662,8 +567,6 @@ NS_IMETHODIMP
|
|||
nsContentList::DocumentWillBeDestroyed(nsIDocument *aDocument)
|
||||
{
|
||||
if (mDocument) {
|
||||
// Our key will change... Best remove ourselves before that happens.
|
||||
RemoveFromHashtable();
|
||||
aDocument->RemoveObserver(this);
|
||||
mDocument = nsnull;
|
||||
}
|
||||
|
@ -750,12 +653,14 @@ nsContentList::MatchSelf(nsIContent *aContent)
|
|||
}
|
||||
|
||||
aContent->ChildCount(count);
|
||||
nsCOMPtr<nsIContent> child;
|
||||
for (i = 0; i < count; i++) {
|
||||
aContent->ChildAt(i, *getter_AddRefs(child));
|
||||
nsIContent *child;
|
||||
aContent->ChildAt(i, child);
|
||||
if (MatchSelf(child)) {
|
||||
NS_RELEASE(child);
|
||||
return PR_TRUE;
|
||||
}
|
||||
NS_RELEASE(child);
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
|
@ -776,10 +681,11 @@ nsContentList::PopulateWith(nsIContent *aContent, PRBool aIncludeRoot)
|
|||
}
|
||||
|
||||
aContent->ChildCount(count);
|
||||
nsCOMPtr<nsIContent> child;
|
||||
for (i = 0; i < count; i++) {
|
||||
aContent->ChildAt(i, *getter_AddRefs(child));
|
||||
nsIContent *child;
|
||||
aContent->ChildAt(i, child);
|
||||
PopulateWith(child, PR_TRUE);
|
||||
NS_RELEASE(child);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -792,10 +698,11 @@ nsContentList::PopulateSelf()
|
|||
PopulateWith(mRootContent, PR_FALSE);
|
||||
}
|
||||
else if (mDocument) {
|
||||
nsCOMPtr<nsIContent> root;
|
||||
mDocument->GetRootContent(getter_AddRefs(root));
|
||||
nsIContent *root = nsnull;
|
||||
mDocument->GetRootContent(&root);
|
||||
if (root) {
|
||||
PopulateWith(root, PR_TRUE);
|
||||
NS_RELEASE(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -862,26 +769,7 @@ void
|
|||
nsContentList::DisconnectFromDocument()
|
||||
{
|
||||
if (mDocument) {
|
||||
// Our key will change... Best remove ourselves before that happens.
|
||||
RemoveFromHashtable();
|
||||
mDocument->RemoveObserver(this);
|
||||
mDocument = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsContentList::RemoveFromHashtable()
|
||||
{
|
||||
if (!gContentListHashTable.ops)
|
||||
return;
|
||||
|
||||
PL_DHashTableOperate(&gContentListHashTable,
|
||||
NS_STATIC_CAST(nsContentListKey*, this),
|
||||
PL_DHASH_REMOVE);
|
||||
|
||||
if (gContentListHashTable.entryCount == 0) {
|
||||
PL_DHashTableFinish(&gContentListHashTable);
|
||||
gContentListHashTable.ops = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -90,54 +90,7 @@ public:
|
|||
NS_IMETHOD Reset();
|
||||
};
|
||||
|
||||
class nsContentListKey
|
||||
{
|
||||
public:
|
||||
nsContentListKey(nsIDocument *aDocument,
|
||||
nsIAtom* aMatchAtom,
|
||||
PRInt32 aMatchNameSpaceId,
|
||||
nsIContent* aRootContent)
|
||||
: mMatchAtom(aMatchAtom),
|
||||
mMatchNameSpaceId(aMatchNameSpaceId),
|
||||
mDocument(aDocument),
|
||||
mRootContent(aRootContent)
|
||||
{
|
||||
}
|
||||
|
||||
nsContentListKey(const nsContentListKey& aContentListKey)
|
||||
: mMatchAtom(aContentListKey.mMatchAtom),
|
||||
mMatchNameSpaceId(aContentListKey.mMatchNameSpaceId),
|
||||
mDocument(aContentListKey.mDocument),
|
||||
mRootContent(aContentListKey.mRootContent)
|
||||
{
|
||||
}
|
||||
|
||||
PRBool Equals(const nsContentListKey& aContentListKey) const
|
||||
{
|
||||
return
|
||||
mMatchAtom == aContentListKey.mMatchAtom &&
|
||||
mMatchNameSpaceId == aContentListKey.mMatchNameSpaceId &&
|
||||
mDocument == aContentListKey.mDocument &&
|
||||
mRootContent == aContentListKey.mRootContent;
|
||||
}
|
||||
inline PRUint32 GetHash(void) const
|
||||
{
|
||||
return
|
||||
NS_PTR_TO_INT32(mMatchAtom.get()) ^
|
||||
(NS_PTR_TO_INT32(mRootContent) << 8) ^
|
||||
(NS_PTR_TO_INT32(mDocument) << 16) ^
|
||||
(mMatchNameSpaceId << 24);
|
||||
}
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIAtom> mMatchAtom;
|
||||
PRInt32 mMatchNameSpaceId;
|
||||
nsIDocument* mDocument; // Weak ref
|
||||
nsIContent* mRootContent; // Weak ref
|
||||
};
|
||||
|
||||
class nsContentList : public nsBaseContentList,
|
||||
protected nsContentListKey,
|
||||
public nsIDOMHTMLCollection,
|
||||
public nsIDocumentObserver,
|
||||
public nsIContentList
|
||||
|
@ -238,16 +191,14 @@ protected:
|
|||
PRBool IsDescendantOfRoot(nsIContent* aContainer);
|
||||
PRBool ContainsRoot(nsIContent* aContent);
|
||||
nsresult CheckDocumentExistence();
|
||||
void RemoveFromHashtable();
|
||||
|
||||
nsIAtom* mMatchAtom;
|
||||
PRInt32 mMatchNameSpaceId;
|
||||
nsContentListMatchFunc mFunc;
|
||||
nsString* mData;
|
||||
nsIDocument* mDocument;
|
||||
nsIContent* mRootContent;
|
||||
PRBool mMatchAll;
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
NS_GetContentList(nsIDocument* aDocument, nsIAtom* aMatchAtom,
|
||||
PRInt32 aMatchNameSpaceId, nsIContent* aRootContent,
|
||||
nsIContentList** aInstancePtrResult);
|
||||
|
||||
#endif // nsContentList_h___
|
||||
|
|
|
@ -2444,12 +2444,10 @@ nsDocument::GetElementsByTagName(const nsAString& aTagname,
|
|||
{
|
||||
nsCOMPtr<nsIAtom> nameAtom(dont_AddRef(NS_NewAtom(aTagname)));
|
||||
|
||||
nsCOMPtr<nsIContentList> list;
|
||||
NS_GetContentList(this, nameAtom, kNameSpaceID_Unknown, nsnull,
|
||||
getter_AddRefs(list));
|
||||
nsContentList* list = new nsContentList(this, nameAtom, kNameSpaceID_Unknown);
|
||||
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return CallQueryInterface(list, aReturn);
|
||||
return list->QueryInterface(NS_GET_IID(nsIDOMNodeList), (void **)aReturn);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -2460,27 +2458,25 @@ nsDocument::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
|
|||
|
||||
PRInt32 nameSpaceId = kNameSpaceID_Unknown;
|
||||
|
||||
nsCOMPtr<nsIContentList> list;
|
||||
nsContentList* list = nsnull;
|
||||
|
||||
if (!aNamespaceURI.Equals(NS_LITERAL_STRING("*"))) {
|
||||
mNameSpaceManager->GetNameSpaceID(aNamespaceURI, nameSpaceId);
|
||||
|
||||
if (nameSpaceId == kNameSpaceID_Unknown) {
|
||||
// Unkonwn namespace means no matches, we create an empty list...
|
||||
NS_GetContentList(this, nsnull, kNameSpaceID_None, nsnull,
|
||||
getter_AddRefs(list));
|
||||
list = new nsContentList(this, nsnull, kNameSpaceID_None);
|
||||
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
if (!list) {
|
||||
nsCOMPtr<nsIAtom> nameAtom(dont_AddRef(NS_NewAtom(aLocalName)));
|
||||
NS_GetContentList(this, nameAtom, nameSpaceId, nsnull,
|
||||
getter_AddRefs(list));
|
||||
list = new nsContentList(this, nameAtom, nameSpaceId);
|
||||
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
return CallQueryInterface(list, aReturn);
|
||||
return list->QueryInterface(NS_GET_IID(nsIDOMNodeList), (void **)aReturn);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -1075,15 +1075,16 @@ nsGenericElement::GetElementsByTagName(const nsAString& aTagname,
|
|||
|
||||
nameAtom = dont_AddRef(NS_NewAtom(aTagname));
|
||||
|
||||
nsCOMPtr<nsIContentList> list;
|
||||
NS_GetContentList(mDocument, nameAtom, kNameSpaceID_Unknown, this,
|
||||
getter_AddRefs(list));
|
||||
nsContentList* list = new nsContentList(mDocument,
|
||||
nameAtom,
|
||||
kNameSpaceID_Unknown,
|
||||
this);
|
||||
|
||||
if (!list) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return CallQueryInterface(list, aReturn);
|
||||
return list->QueryInterface(NS_GET_IID(nsIDOMNodeList), (void **)aReturn);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1223,7 +1224,7 @@ nsGenericElement::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
|
|||
nsCOMPtr<nsIAtom> nameAtom(dont_AddRef(NS_NewAtom(aLocalName)));
|
||||
PRInt32 nameSpaceId = kNameSpaceID_Unknown;
|
||||
|
||||
nsCOMPtr<nsIContentList> list;
|
||||
nsContentList* list = nsnull;
|
||||
|
||||
if (!aNamespaceURI.Equals(NS_LITERAL_STRING("*"))) {
|
||||
nsCOMPtr<nsINodeInfoManager> nimgr;
|
||||
|
@ -1237,20 +1238,18 @@ nsGenericElement::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
|
|||
nsmgr->GetNameSpaceID(aNamespaceURI, nameSpaceId);
|
||||
|
||||
if (nameSpaceId == kNameSpaceID_Unknown) {
|
||||
// Unknown namespace means no matches, we create an empty list...
|
||||
NS_GetContentList(mDocument, nsnull, kNameSpaceID_None, nsnull,
|
||||
getter_AddRefs(list));
|
||||
// Unkonwn namespace means no matches, we create an empty list...
|
||||
list = new nsContentList(mDocument, nsnull, kNameSpaceID_None);
|
||||
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
if (!list) {
|
||||
NS_GetContentList(mDocument, nameAtom, nameSpaceId, this,
|
||||
getter_AddRefs(list));
|
||||
list = new nsContentList(mDocument, nameAtom, nameSpaceId, this);
|
||||
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
return CallQueryInterface(list, aReturn);
|
||||
return list->QueryInterface(NS_GET_IID(nsIDOMNodeList), (void **)aReturn);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
Загрузка…
Ссылка в новой задаче