|
|
|
|
@@ -154,8 +154,9 @@ static NS_DEFINE_CID(kCookieServiceCID, NS_COOKIESERVICE_CID);
|
|
|
|
|
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
|
|
|
|
static NS_DEFINE_CID(kCharsetAliasCID, NS_CHARSETALIAS_CID);
|
|
|
|
|
|
|
|
|
|
static PRBool
|
|
|
|
|
IsNamedItem(nsIContent* aContent, nsIAtom *aTag, nsAString& aName);
|
|
|
|
|
// Returns the name atom of aContent, if the content is a named item
|
|
|
|
|
// and has a name atom.
|
|
|
|
|
static nsIAtom* IsNamedItem(nsIContent* aContent);
|
|
|
|
|
|
|
|
|
|
static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
|
|
|
|
|
|
|
|
|
|
@@ -206,8 +207,8 @@ NS_NewHTMLDocument(nsIDocument** aInstancePtrResult)
|
|
|
|
|
class IdAndNameMapEntry : public PLDHashEntryHdr
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
IdAndNameMapEntry(const nsAString& aString) :
|
|
|
|
|
mKey(aString), mNameContentList(nsnull), mIdContentList()
|
|
|
|
|
IdAndNameMapEntry(nsIAtom* aKey) :
|
|
|
|
|
mKey(aKey), mNameContentList(nsnull), mIdContentList()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -238,7 +239,7 @@ public:
|
|
|
|
|
mIdContentList.AppendElement(ID_NOT_IN_DOCUMENT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsString mKey;
|
|
|
|
|
nsCOMPtr<nsIAtom> mKey;
|
|
|
|
|
nsBaseContentList *mNameContentList;
|
|
|
|
|
private:
|
|
|
|
|
nsSmallVoidArray mIdContentList;
|
|
|
|
|
@@ -275,15 +276,14 @@ IdAndNameHashGetKey(PLDHashTable *table, PLDHashEntryHdr *entry)
|
|
|
|
|
{
|
|
|
|
|
IdAndNameMapEntry *e = NS_STATIC_CAST(IdAndNameMapEntry *, entry);
|
|
|
|
|
|
|
|
|
|
return NS_STATIC_CAST(const nsAString *, &e->mKey);
|
|
|
|
|
return NS_STATIC_CAST(const nsIAtom *, e->mKey);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PR_STATIC_CALLBACK(PLDHashNumber)
|
|
|
|
|
IdAndNameHashHashKey(PLDHashTable *table, const void *key)
|
|
|
|
|
{
|
|
|
|
|
const nsAString *str = NS_STATIC_CAST(const nsAString *, key);
|
|
|
|
|
|
|
|
|
|
return HashString(*str);
|
|
|
|
|
// Our key is an nsIAtom*, so just shift it and use that as the hash.
|
|
|
|
|
return NS_PTR_TO_INT32(key) >> 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PR_STATIC_CALLBACK(PRBool)
|
|
|
|
|
@@ -292,9 +292,9 @@ IdAndNameHashMatchEntry(PLDHashTable *table, const PLDHashEntryHdr *entry,
|
|
|
|
|
{
|
|
|
|
|
const IdAndNameMapEntry *e =
|
|
|
|
|
NS_STATIC_CAST(const IdAndNameMapEntry *, entry);
|
|
|
|
|
const nsAString *str = NS_STATIC_CAST(const nsAString *, key);
|
|
|
|
|
const nsIAtom *atom = NS_STATIC_CAST(const nsIAtom *, key);
|
|
|
|
|
|
|
|
|
|
return str->Equals(e->mKey);
|
|
|
|
|
return atom == e->mKey;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PR_STATIC_CALLBACK(void)
|
|
|
|
|
@@ -310,10 +310,11 @@ PR_STATIC_CALLBACK(PRBool)
|
|
|
|
|
IdAndNameHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
|
|
|
|
|
const void *key)
|
|
|
|
|
{
|
|
|
|
|
const nsAString *keyStr = NS_STATIC_CAST(const nsAString *, key);
|
|
|
|
|
nsIAtom *atom = NS_CONST_CAST(nsIAtom *,
|
|
|
|
|
NS_STATIC_CAST(const nsIAtom*, key));
|
|
|
|
|
|
|
|
|
|
// Inititlize the entry with placement new
|
|
|
|
|
new (entry) IdAndNameMapEntry(*keyStr);
|
|
|
|
|
new (entry) IdAndNameMapEntry(atom);
|
|
|
|
|
return PR_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1182,10 +1183,9 @@ nsHTMLDocument::AttributeWillChange(nsIContent* aContent, PRInt32 aNameSpaceID,
|
|
|
|
|
|
|
|
|
|
if (!IsXHTML() && aAttribute == nsHTMLAtoms::name &&
|
|
|
|
|
aNameSpaceID == kNameSpaceID_None) {
|
|
|
|
|
nsAutoString value;
|
|
|
|
|
|
|
|
|
|
if (IsNamedItem(aContent, aContent->Tag(), value)) {
|
|
|
|
|
nsresult rv = RemoveFromNameTable(value, aContent);
|
|
|
|
|
nsIAtom* name = IsNamedItem(aContent);
|
|
|
|
|
if (name) {
|
|
|
|
|
nsresult rv = RemoveFromNameTable(name, aContent);
|
|
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
|
return;
|
|
|
|
|
@@ -1212,10 +1212,10 @@ nsHTMLDocument::AttributeChanged(nsIContent* aContent, PRInt32 aNameSpaceID,
|
|
|
|
|
|
|
|
|
|
if (!IsXHTML() && aAttribute == nsHTMLAtoms::name &&
|
|
|
|
|
aNameSpaceID == kNameSpaceID_None) {
|
|
|
|
|
nsAutoString value;
|
|
|
|
|
|
|
|
|
|
if (IsNamedItem(aContent, aContent->Tag(), value)) {
|
|
|
|
|
nsresult rv = UpdateNameTableEntry(value, aContent);
|
|
|
|
|
nsIAtom* name = IsNamedItem(aContent);
|
|
|
|
|
if (name) {
|
|
|
|
|
nsresult rv = UpdateNameTableEntry(name, aContent);
|
|
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
|
return;
|
|
|
|
|
@@ -1223,14 +1223,9 @@ nsHTMLDocument::AttributeChanged(nsIContent* aContent, PRInt32 aNameSpaceID,
|
|
|
|
|
}
|
|
|
|
|
} else if (aAttribute == aContent->GetIDAttributeName() &&
|
|
|
|
|
aNameSpaceID == kNameSpaceID_None) {
|
|
|
|
|
nsAutoString value;
|
|
|
|
|
|
|
|
|
|
aContent->GetAttr(aNameSpaceID,
|
|
|
|
|
aContent->GetIDAttributeName(),
|
|
|
|
|
value);
|
|
|
|
|
|
|
|
|
|
if (!value.IsEmpty()) {
|
|
|
|
|
nsresult rv = AddToIdTable(value, aContent);
|
|
|
|
|
nsIAtom* id = aContent->GetID();
|
|
|
|
|
if (id) {
|
|
|
|
|
nsresult rv = UpdateIdTableEntry(id, aContent);
|
|
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
|
return;
|
|
|
|
|
@@ -2368,13 +2363,16 @@ nsHTMLDocument::GetElementById(const nsAString& aElementId,
|
|
|
|
|
NS_ENSURE_ARG_POINTER(aReturn);
|
|
|
|
|
*aReturn = nsnull;
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsIAtom> idAtom(do_GetAtom(aElementId));
|
|
|
|
|
NS_ENSURE_TRUE(idAtom, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
|
|
|
|
|
// We don't have to flush before we do the initial hashtable lookup, since if
|
|
|
|
|
// the id is already in the hashtable it couldn't have been removed without
|
|
|
|
|
// us being notified (all removals notify immediately, as far as I can tell).
|
|
|
|
|
// So do the lookup first.
|
|
|
|
|
IdAndNameMapEntry *entry =
|
|
|
|
|
NS_STATIC_CAST(IdAndNameMapEntry *,
|
|
|
|
|
PL_DHashTableOperate(&mIdAndNameHashTable, &aElementId,
|
|
|
|
|
PL_DHashTableOperate(&mIdAndNameHashTable, idAtom,
|
|
|
|
|
PL_DHASH_ADD));
|
|
|
|
|
NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
|
|
|
|
|
@@ -2398,7 +2396,7 @@ nsHTMLDocument::GetElementById(const nsAString& aElementId,
|
|
|
|
|
// the flush actually deleted entries).
|
|
|
|
|
entry =
|
|
|
|
|
NS_STATIC_CAST(IdAndNameMapEntry *,
|
|
|
|
|
PL_DHashTableOperate(&mIdAndNameHashTable, &aElementId,
|
|
|
|
|
PL_DHashTableOperate(&mIdAndNameHashTable, idAtom,
|
|
|
|
|
PL_DHASH_ADD));
|
|
|
|
|
NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
}
|
|
|
|
|
@@ -2434,7 +2432,7 @@ nsHTMLDocument::GetElementById(const nsAString& aElementId,
|
|
|
|
|
"getElementById(\"\") called, fix caller?");
|
|
|
|
|
|
|
|
|
|
if (mRootContent && !aElementId.IsEmpty()) {
|
|
|
|
|
e = nsContentUtils::MatchElementId(mRootContent, aElementId);
|
|
|
|
|
e = nsContentUtils::MatchElementId(mRootContent, idAtom);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2444,7 +2442,7 @@ nsHTMLDocument::GetElementById(const nsAString& aElementId,
|
|
|
|
|
// we'd have done just that already
|
|
|
|
|
if (IdTableIsLive() && mRootContent && !aElementId.IsEmpty()) {
|
|
|
|
|
nsIContent* eDebug =
|
|
|
|
|
nsContentUtils::MatchElementId(mRootContent, aElementId);
|
|
|
|
|
nsContentUtils::MatchElementId(mRootContent, idAtom);
|
|
|
|
|
NS_ASSERTION(!eDebug,
|
|
|
|
|
"We got null for |e| but MatchElementId found something?");
|
|
|
|
|
}
|
|
|
|
|
@@ -2944,11 +2942,14 @@ nsHTMLDocument::InvalidateHashTables()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static nsresult
|
|
|
|
|
ReserveNameInHash(const nsAString& aName, PLDHashTable *aHash)
|
|
|
|
|
ReserveNameInHash(const char* aName, PLDHashTable *aHash)
|
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsIAtom> atom(do_GetAtom(aName));
|
|
|
|
|
NS_ENSURE_TRUE(atom, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
|
|
|
|
|
IdAndNameMapEntry *entry =
|
|
|
|
|
NS_STATIC_CAST(IdAndNameMapEntry *,
|
|
|
|
|
PL_DHashTableOperate(aHash, &aName, PL_DHASH_ADD));
|
|
|
|
|
PL_DHashTableOperate(aHash, atom, PL_DHASH_ADD));
|
|
|
|
|
|
|
|
|
|
NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
|
|
|
|
|
@@ -2966,65 +2967,70 @@ nsHTMLDocument::PrePopulateHashTables()
|
|
|
|
|
{
|
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
|
|
rv = ReserveNameInHash(NS_LITERAL_STRING("write"), &mIdAndNameHashTable);
|
|
|
|
|
rv = ReserveNameInHash("write", &mIdAndNameHashTable);
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
|
|
rv = ReserveNameInHash(NS_LITERAL_STRING("writeln"), &mIdAndNameHashTable);
|
|
|
|
|
rv = ReserveNameInHash("writeln", &mIdAndNameHashTable);
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
|
|
rv = ReserveNameInHash(NS_LITERAL_STRING("open"), &mIdAndNameHashTable);
|
|
|
|
|
rv = ReserveNameInHash("open", &mIdAndNameHashTable);
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
|
|
rv = ReserveNameInHash(NS_LITERAL_STRING("close"), &mIdAndNameHashTable);
|
|
|
|
|
rv = ReserveNameInHash("close", &mIdAndNameHashTable);
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
|
|
rv = ReserveNameInHash(NS_LITERAL_STRING("forms"), &mIdAndNameHashTable);
|
|
|
|
|
rv = ReserveNameInHash("forms", &mIdAndNameHashTable);
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
|
|
rv = ReserveNameInHash(NS_LITERAL_STRING("elements"), &mIdAndNameHashTable);
|
|
|
|
|
rv = ReserveNameInHash("elements", &mIdAndNameHashTable);
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
|
|
rv = ReserveNameInHash(NS_LITERAL_STRING("characterSet"),
|
|
|
|
|
&mIdAndNameHashTable);
|
|
|
|
|
rv = ReserveNameInHash("characterSet", &mIdAndNameHashTable);
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
|
|
rv = ReserveNameInHash(NS_LITERAL_STRING("nodeType"), &mIdAndNameHashTable);
|
|
|
|
|
rv = ReserveNameInHash("nodeType", &mIdAndNameHashTable);
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
|
|
rv = ReserveNameInHash(NS_LITERAL_STRING("parentNode"),
|
|
|
|
|
&mIdAndNameHashTable);
|
|
|
|
|
rv = ReserveNameInHash("parentNode", &mIdAndNameHashTable);
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
|
|
rv = ReserveNameInHash(NS_LITERAL_STRING("cookie"), &mIdAndNameHashTable);
|
|
|
|
|
rv = ReserveNameInHash("cookie", &mIdAndNameHashTable);
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static PRBool
|
|
|
|
|
IsNamedItem(nsIContent* aContent, nsIAtom *aTag, nsAString& aName)
|
|
|
|
|
static nsIAtom*
|
|
|
|
|
IsNamedItem(nsIContent* aContent)
|
|
|
|
|
{
|
|
|
|
|
// Only the content types reflected in Level 0 with a NAME
|
|
|
|
|
// attribute are registered. Images, layers and forms always get
|
|
|
|
|
// reflected up to the document. Applets and embeds only go
|
|
|
|
|
// to the closest container (which could be a form).
|
|
|
|
|
if (aTag == nsHTMLAtoms::img ||
|
|
|
|
|
aTag == nsHTMLAtoms::form ||
|
|
|
|
|
aTag == nsHTMLAtoms::applet ||
|
|
|
|
|
aTag == nsHTMLAtoms::embed ||
|
|
|
|
|
aTag == nsHTMLAtoms::object) {
|
|
|
|
|
aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, aName);
|
|
|
|
|
|
|
|
|
|
if (!aName.IsEmpty()) {
|
|
|
|
|
return PR_TRUE;
|
|
|
|
|
}
|
|
|
|
|
nsGenericHTMLElement* elm = nsGenericHTMLElement::FromContent(aContent);
|
|
|
|
|
if (!elm) {
|
|
|
|
|
return nsnull;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return PR_FALSE;
|
|
|
|
|
nsIAtom* tag = elm->Tag();
|
|
|
|
|
if (tag != nsHTMLAtoms::img &&
|
|
|
|
|
tag != nsHTMLAtoms::form &&
|
|
|
|
|
tag != nsHTMLAtoms::applet &&
|
|
|
|
|
tag != nsHTMLAtoms::embed &&
|
|
|
|
|
tag != nsHTMLAtoms::object) {
|
|
|
|
|
return nsnull;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const nsAttrValue* val = elm->GetParsedAttr(nsHTMLAtoms::name);
|
|
|
|
|
if (val && val->Type() == nsAttrValue::eAtom) {
|
|
|
|
|
return val->GetAtomValue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nsnull;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
nsHTMLDocument::UpdateNameTableEntry(const nsAString& aName,
|
|
|
|
|
nsHTMLDocument::UpdateNameTableEntry(nsIAtom* aName,
|
|
|
|
|
nsIContent *aContent)
|
|
|
|
|
{
|
|
|
|
|
NS_ASSERTION(!IsXHTML(),
|
|
|
|
|
@@ -3032,7 +3038,7 @@ nsHTMLDocument::UpdateNameTableEntry(const nsAString& aName,
|
|
|
|
|
|
|
|
|
|
IdAndNameMapEntry *entry =
|
|
|
|
|
NS_STATIC_CAST(IdAndNameMapEntry *,
|
|
|
|
|
PL_DHashTableOperate(&mIdAndNameHashTable, &aName,
|
|
|
|
|
PL_DHashTableOperate(&mIdAndNameHashTable, aName,
|
|
|
|
|
PL_DHASH_LOOKUP));
|
|
|
|
|
|
|
|
|
|
if (PL_DHASH_ENTRY_IS_FREE(entry)) {
|
|
|
|
|
@@ -3057,29 +3063,13 @@ nsHTMLDocument::UpdateNameTableEntry(const nsAString& aName,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
nsHTMLDocument::AddToIdTable(const nsAString& aId, nsIContent *aContent)
|
|
|
|
|
{
|
|
|
|
|
IdAndNameMapEntry *entry =
|
|
|
|
|
NS_STATIC_CAST(IdAndNameMapEntry *,
|
|
|
|
|
PL_DHashTableOperate(&mIdAndNameHashTable, &aId,
|
|
|
|
|
PL_DHASH_ADD));
|
|
|
|
|
NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
|
|
|
|
|
if (NS_LIKELY(entry->AddIdContent(aContent))) {
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
nsHTMLDocument::UpdateIdTableEntry(const nsAString& aId, nsIContent *aContent)
|
|
|
|
|
nsHTMLDocument::UpdateIdTableEntry(nsIAtom* aId, nsIContent *aContent)
|
|
|
|
|
{
|
|
|
|
|
PRBool liveTable = IdTableIsLive();
|
|
|
|
|
PLDHashOperator op = liveTable ? PL_DHASH_ADD : PL_DHASH_LOOKUP;
|
|
|
|
|
IdAndNameMapEntry *entry =
|
|
|
|
|
NS_STATIC_CAST(IdAndNameMapEntry *,
|
|
|
|
|
PL_DHashTableOperate(&mIdAndNameHashTable, &aId,
|
|
|
|
|
PL_DHashTableOperate(&mIdAndNameHashTable, aId,
|
|
|
|
|
op));
|
|
|
|
|
|
|
|
|
|
NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
@@ -3094,15 +3084,14 @@ nsHTMLDocument::UpdateIdTableEntry(const nsAString& aId, nsIContent *aContent)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
nsHTMLDocument::RemoveFromNameTable(const nsAString& aName,
|
|
|
|
|
nsIContent *aContent)
|
|
|
|
|
nsHTMLDocument::RemoveFromNameTable(nsIAtom* aName, nsIContent *aContent)
|
|
|
|
|
{
|
|
|
|
|
NS_ASSERTION(!IsXHTML(),
|
|
|
|
|
"nsHTMLDocument::RemoveFromNameTable Don't call me on an XHTML document!!!");
|
|
|
|
|
|
|
|
|
|
IdAndNameMapEntry *entry =
|
|
|
|
|
NS_STATIC_CAST(IdAndNameMapEntry *,
|
|
|
|
|
PL_DHashTableOperate(&mIdAndNameHashTable, &aName,
|
|
|
|
|
PL_DHashTableOperate(&mIdAndNameHashTable, aName,
|
|
|
|
|
PL_DHASH_LOOKUP));
|
|
|
|
|
|
|
|
|
|
if (PL_DHASH_ENTRY_IS_BUSY(entry) && entry->mNameContentList &&
|
|
|
|
|
@@ -3116,24 +3105,15 @@ nsHTMLDocument::RemoveFromNameTable(const nsAString& aName,
|
|
|
|
|
nsresult
|
|
|
|
|
nsHTMLDocument::RemoveFromIdTable(nsIContent *aContent)
|
|
|
|
|
{
|
|
|
|
|
nsIAtom* idAttr = aContent->GetIDAttributeName();
|
|
|
|
|
|
|
|
|
|
if (!idAttr || !aContent->HasAttr(kNameSpaceID_None, idAttr)) {
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
nsIAtom* id = aContent->GetID();
|
|
|
|
|
|
|
|
|
|
nsAutoString value;
|
|
|
|
|
aContent->GetAttr(kNameSpaceID_None, idAttr, value);
|
|
|
|
|
|
|
|
|
|
if (value.IsEmpty()) {
|
|
|
|
|
if (!id) {
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IdAndNameMapEntry *entry =
|
|
|
|
|
NS_STATIC_CAST(IdAndNameMapEntry *,
|
|
|
|
|
PL_DHashTableOperate(&mIdAndNameHashTable,
|
|
|
|
|
NS_STATIC_CAST(const nsAString *,
|
|
|
|
|
&value),
|
|
|
|
|
PL_DHashTableOperate(&mIdAndNameHashTable, id,
|
|
|
|
|
PL_DHASH_LOOKUP));
|
|
|
|
|
|
|
|
|
|
if (PL_DHASH_ENTRY_IS_FREE(entry)) {
|
|
|
|
|
@@ -3155,14 +3135,16 @@ nsHTMLDocument::UnregisterNamedItems(nsIContent *aContent)
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsAutoString value;
|
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
|
|
if (!IsXHTML() && IsNamedItem(aContent, aContent->Tag(), value)) {
|
|
|
|
|
rv = RemoveFromNameTable(value, aContent);
|
|
|
|
|
if (!IsXHTML()) {
|
|
|
|
|
nsIAtom* name = IsNamedItem(aContent);
|
|
|
|
|
if (name) {
|
|
|
|
|
rv = RemoveFromNameTable(name, aContent);
|
|
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
|
return rv;
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -3189,21 +3171,19 @@ nsHTMLDocument::RegisterNamedItems(nsIContent *aContent)
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsAutoString value;
|
|
|
|
|
|
|
|
|
|
if (!IsXHTML() && IsNamedItem(aContent, aContent->Tag(), value)) {
|
|
|
|
|
UpdateNameTableEntry(value, aContent);
|
|
|
|
|
if (!IsXHTML()) {
|
|
|
|
|
nsIAtom* name = IsNamedItem(aContent);
|
|
|
|
|
if (name) {
|
|
|
|
|
UpdateNameTableEntry(name, aContent);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsIAtom* idAttr = aContent->GetIDAttributeName();
|
|
|
|
|
if (idAttr) {
|
|
|
|
|
aContent->GetAttr(kNameSpaceID_None, idAttr, value);
|
|
|
|
|
if (!value.IsEmpty()) {
|
|
|
|
|
nsresult rv = UpdateIdTableEntry(value, aContent);
|
|
|
|
|
nsIAtom* id = aContent->GetID();
|
|
|
|
|
if (id) {
|
|
|
|
|
nsresult rv = UpdateIdTableEntry(id, aContent);
|
|
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -3217,7 +3197,7 @@ nsHTMLDocument::RegisterNamedItems(nsIContent *aContent)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
FindNamedItems(const nsAString& aName, nsIContent *aContent,
|
|
|
|
|
FindNamedItems(nsIAtom* aName, nsIContent *aContent,
|
|
|
|
|
IdAndNameMapEntry& aEntry, PRBool aIsXHTML)
|
|
|
|
|
{
|
|
|
|
|
NS_ASSERTION(aEntry.mNameContentList,
|
|
|
|
|
@@ -3232,19 +3212,14 @@ FindNamedItems(const nsAString& aName, nsIContent *aContent,
|
|
|
|
|
|
|
|
|
|
nsAutoString value;
|
|
|
|
|
|
|
|
|
|
if (!aIsXHTML && IsNamedItem(aContent, aContent->Tag(), value) &&
|
|
|
|
|
value.Equals(aName)) {
|
|
|
|
|
if (!aIsXHTML && aName == IsNamedItem(aContent)) {
|
|
|
|
|
aEntry.mNameContentList->AppendElement(aContent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!aEntry.GetIdContent()) {
|
|
|
|
|
// Maybe this node has the right id?
|
|
|
|
|
nsIAtom* idAttr = aContent->GetIDAttributeName();
|
|
|
|
|
if (idAttr &&
|
|
|
|
|
aContent->AttrValueIs(kNameSpaceID_None, idAttr,
|
|
|
|
|
aName, eCaseMatters)) {
|
|
|
|
|
aEntry.AddIdContent(aContent);
|
|
|
|
|
}
|
|
|
|
|
if (!aEntry.GetIdContent() &&
|
|
|
|
|
// Maybe this node has the right id?
|
|
|
|
|
aName == aContent->GetID()) {
|
|
|
|
|
aEntry.AddIdContent(aContent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PRUint32 i, count = aContent->GetChildCount();
|
|
|
|
|
@@ -3267,12 +3242,14 @@ nsHTMLDocument::ResolveName(const nsAString& aName,
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsIAtom> name(do_GetAtom(aName));
|
|
|
|
|
|
|
|
|
|
// We have built a table and cache the named items. The table will
|
|
|
|
|
// be updated as content is added and removed.
|
|
|
|
|
|
|
|
|
|
IdAndNameMapEntry *entry =
|
|
|
|
|
NS_STATIC_CAST(IdAndNameMapEntry *,
|
|
|
|
|
PL_DHashTableOperate(&mIdAndNameHashTable, &aName,
|
|
|
|
|
PL_DHashTableOperate(&mIdAndNameHashTable, name,
|
|
|
|
|
PL_DHASH_ADD));
|
|
|
|
|
NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
|
|
|
|
|
@@ -3301,7 +3278,7 @@ nsHTMLDocument::ResolveName(const nsAString& aName,
|
|
|
|
|
// the flush actually deleted entries).
|
|
|
|
|
entry =
|
|
|
|
|
NS_STATIC_CAST(IdAndNameMapEntry *,
|
|
|
|
|
PL_DHashTableOperate(&mIdAndNameHashTable, &aName,
|
|
|
|
|
PL_DHashTableOperate(&mIdAndNameHashTable, name,
|
|
|
|
|
PL_DHASH_ADD));
|
|
|
|
|
NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
}
|
|
|
|
|
@@ -3326,7 +3303,7 @@ nsHTMLDocument::ResolveName(const nsAString& aName,
|
|
|
|
|
if (mRootContent && !aName.IsEmpty()) {
|
|
|
|
|
// We'll never get here if !IsXHTML(), so we can just pass
|
|
|
|
|
// PR_FALSE to FindNamedItems().
|
|
|
|
|
FindNamedItems(aName, mRootContent, *entry, PR_FALSE);
|
|
|
|
|
FindNamedItems(name, mRootContent, *entry, PR_FALSE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|