diff --git a/mozilla/content/html/document/src/nsHTMLContentSink.cpp b/mozilla/content/html/document/src/nsHTMLContentSink.cpp
index 70e27c62912..b10a2da5759 100644
--- a/mozilla/content/html/document/src/nsHTMLContentSink.cpp
+++ b/mozilla/content/html/document/src/nsHTMLContentSink.cpp
@@ -247,6 +247,7 @@ public:
nsresult GrowStack();
nsresult AddText(const nsString& aText);
nsresult FlushText(PRBool* aDidFlush = nsnull);
+ nsresult FlushTags();
void MaybeMarkSinkDirty();
@@ -1150,6 +1151,29 @@ SinkContext::AddText(const nsString& aText)
return NS_OK;
}
+/**
+ * Flush all elements that have been seen so far such that
+ * they are visible in the tree. Specifically, make sure
+ * that they are all added to their respective parents.
+ */
+nsresult
+SinkContext::FlushTags()
+{
+ FlushText();
+
+ PRInt32 stackPos = mStackPos-1;
+ while ((stackPos > 0) && (0 == (mStack[stackPos].mFlags & APPENDED))) {
+ nsIHTMLContent* content = mStack[stackPos].mContent;
+ nsIHTMLContent* parent = mStack[stackPos-1].mContent;
+
+ parent->AppendChildTo(content, PR_FALSE);
+ mStack[stackPos].mFlags |= APPENDED;
+ stackPos--;
+ }
+
+ return NS_OK;
+}
+
/**
* Flush any buffered text out by creating a text content object and
* adding it to the content.
@@ -2280,7 +2304,9 @@ HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
// Otherwise, get the text content of the script tag
script = aNode.GetSkippedContent();
}
-
+
+ mCurrentContext->FlushTags();
+
if (script != "") {
nsIScriptContextOwner *owner;
nsIScriptContext *context;
diff --git a/mozilla/content/html/document/src/nsHTMLDocument.cpp b/mozilla/content/html/document/src/nsHTMLDocument.cpp
index 9b3e6092da2..f0271af483e 100644
--- a/mozilla/content/html/document/src/nsHTMLDocument.cpp
+++ b/mozilla/content/html/document/src/nsHTMLDocument.cpp
@@ -391,6 +391,77 @@ nsHTMLDocument::SetDTDMode(nsDTDMode aMode)
return NS_OK;
}
+NS_IMETHODIMP
+nsHTMLDocument::ContentAppended(nsIContent* aContainer,
+ PRInt32 aNewIndexInContainer)
+{
+ if (nsnull != mNamedItems) {
+ nsIContent* child;
+ nsIAtom *name;
+
+ aContainer->GetTag(name);
+ aContainer->ChildAt(aNewIndexInContainer, child);
+ RegisterNamedItems(aContainer, name == nsHTMLAtoms::form);
+ NS_IF_RELEASE(child);
+ NS_IF_RELEASE(name);
+ }
+
+ return nsDocument::ContentAppended(aContainer, aNewIndexInContainer);
+}
+
+NS_IMETHODIMP
+nsHTMLDocument::ContentInserted(nsIContent* aContainer,
+ nsIContent* aChild,
+ PRInt32 aIndexInContainer)
+{
+ if (nsnull != mNamedItems) {
+ nsIAtom *name;
+
+ aContainer->GetTag(name);
+ RegisterNamedItems(aChild, name == nsHTMLAtoms::form);
+ NS_IF_RELEASE(name);
+ }
+
+ return nsDocument::ContentInserted(aContainer, aChild, aIndexInContainer);
+}
+
+NS_IMETHODIMP
+nsHTMLDocument::ContentReplaced(nsIContent* aContainer,
+ nsIContent* aOldChild,
+ nsIContent* aNewChild,
+ PRInt32 aIndexInContainer)
+{
+ if (nsnull != mNamedItems) {
+ nsIAtom *name;
+
+ aContainer->GetTag(name);
+ UnregisterNamedItems(aOldChild, name == nsHTMLAtoms::form);
+ RegisterNamedItems(aNewChild, name == nsHTMLAtoms::form);
+
+ NS_IF_RELEASE(name);
+ }
+
+ return nsDocument::ContentReplaced(aContainer, aOldChild,
+ aNewChild, aIndexInContainer);
+}
+
+NS_IMETHODIMP
+nsHTMLDocument::ContentRemoved(nsIContent* aContainer,
+ nsIContent* aChild,
+ PRInt32 aIndexInContainer)
+{
+ if (nsnull != mNamedItems) {
+ nsIAtom *name;
+
+ aContainer->GetTag(name);
+ UnregisterNamedItems(aChild, name == nsHTMLAtoms::form);
+
+ NS_IF_RELEASE(name);
+ }
+
+ return nsDocument::ContentRemoved(aContainer, aChild, aIndexInContainer);
+}
+
//
// nsIDOMDocument interface implementation
//
@@ -934,28 +1005,68 @@ nsHTMLDocument::DeleteNamedItems()
}
}
-void
-nsHTMLDocument::RegisterNamedItems(nsIContent *aContent, PRBool aInForm)
+static PRBool
+IsNamedItem(nsIContent* aContent, nsIAtom *aTag,
+ PRBool aInForm, nsString& aName)
{
static nsAutoString name("NAME");
- nsAutoString value;
- nsIAtom *tag;
- aContent->GetTag(tag);
- PRBool inForm;
// Only the content types reflected in Level 0 with a NAME
// attribute are registered. Images and forms always get
// reflected up to the document. Applets and embeds only go
// to the closest container (which could be a form).
- if ((tag == nsHTMLAtoms::img) || (tag == nsHTMLAtoms::form) ||
- (!aInForm && ((tag == nsHTMLAtoms::applet) ||
- (tag == nsHTMLAtoms::embed)))) {
- if (NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttribute(name, value)) {
- char *nameStr = value.ToNewCString();
- PL_HashTableAdd(mNamedItems, nameStr, aContent);
+ if ((aTag == nsHTMLAtoms::img) || (aTag == nsHTMLAtoms::form) ||
+ (!aInForm && ((aTag == nsHTMLAtoms::applet) ||
+ (aTag == nsHTMLAtoms::embed)))) {
+ if (NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttribute(name, aName)) {
+ return PR_TRUE;
}
}
+ return PR_FALSE;
+}
+
+void
+nsHTMLDocument::UnregisterNamedItems(nsIContent *aContent, PRBool aInForm)
+{
+ nsAutoString value;
+ nsIAtom *tag;
+ aContent->GetTag(tag);
+ PRBool inForm;
+
+ if (IsNamedItem(aContent, tag, aInForm, value)) {
+ char *nameStr = value.ToNewCString();
+ // XXX What about the string held in the hash table entry
+ PL_HashTableRemove(mNamedItems, nameStr);
+ delete [] nameStr;
+ }
+
+ inForm = aInForm || (tag == nsHTMLAtoms::form);
+ NS_IF_RELEASE(tag);
+
+ PRInt32 i, count;
+ aContent->ChildCount(count);
+ for (i = 0; i < count; i++) {
+ nsIContent *child;
+ aContent->ChildAt(i, child);
+ UnregisterNamedItems(child, inForm);
+ NS_RELEASE(child);
+ }
+}
+
+void
+nsHTMLDocument::RegisterNamedItems(nsIContent *aContent, PRBool aInForm)
+{
+ nsAutoString value;
+ nsIAtom *tag;
+ aContent->GetTag(tag);
+ PRBool inForm;
+
+ if (IsNamedItem(aContent, tag, aInForm, value)) {
+ char *nameStr = value.ToNewCString();
+ PL_HashTableAdd(mNamedItems, nameStr, aContent);
+ }
+
inForm = aInForm || (tag == nsHTMLAtoms::form);
NS_IF_RELEASE(tag);
@@ -969,22 +1080,68 @@ nsHTMLDocument::RegisterNamedItems(nsIContent *aContent, PRBool aInForm)
}
}
+nsIContent*
+nsHTMLDocument::FindNamedItem(nsIContent *aContent,
+ const nsString& aName,
+ PRBool aInForm)
+{
+ nsAutoString value;
+ nsIAtom *tag;
+ aContent->GetTag(tag);
+ PRBool inForm;
+
+ if (IsNamedItem(aContent, tag, aInForm, value)) {
+ if (aName.Equals(value)) {
+ NS_IF_RELEASE(tag);
+ return aContent;
+ }
+ }
+
+ inForm = aInForm || (tag == nsHTMLAtoms::form);
+ NS_IF_RELEASE(tag);
+
+ PRInt32 i, count;
+ nsIContent *result = nsnull;
+ aContent->ChildCount(count);
+ for (i = 0; (i < count) && (nsnull == result); i++) {
+ nsIContent *child;
+ aContent->ChildAt(i, child);
+ result = FindNamedItem(child, aName, inForm);
+ NS_RELEASE(child);
+ }
+
+ return result;
+}
+
NS_IMETHODIMP
nsHTMLDocument::NamedItem(const nsString& aName, nsIDOMElement** aReturn)
{
- static nsAutoString name("NAME");
nsresult result = NS_OK;
- nsIContent *content;
+ nsIContent *content = nsnull;
- if (nsnull == mNamedItems) {
- mNamedItems = PL_NewHashTable(10, PL_HashString, PL_CompareStrings,
- PL_CompareValues, nsnull, nsnull);
- RegisterNamedItems(mRootContent, PR_FALSE);
+ // XXX If we have a parser, it means that we're still loading the
+ // document. Since there's still content coming in (and not all
+ // may yet have been explicitly added to the document), we do
+ // a depth-first search rather than build up a table.
+ // Obviously, this may be inefficient for large documents.
+ if (nsnull != mParser) {
+ content = FindNamedItem(mRootContent, aName, PR_FALSE);
+ }
+ else {
+ // If the document has completed loading, we build a table and
+ // cache the named items. The table will be updated as content
+ // is added and removed.
+ if (nsnull == mNamedItems) {
+ mNamedItems = PL_NewHashTable(10, PL_HashString, PL_CompareStrings,
+ PL_CompareValues, nsnull, nsnull);
+ RegisterNamedItems(mRootContent, PR_FALSE);
+ }
+
+ char *str = aName.ToNewCString();
+ content = (nsIContent *)PL_HashTableLookup(mNamedItems, str);
+ delete [] str;
}
- char *str = aName.ToNewCString();
-
- content = (nsIContent *)PL_HashTableLookup(mNamedItems, str);
if (nsnull != content) {
result = content->QueryInterface(kIDOMElementIID, (void **)aReturn);
}
@@ -992,7 +1149,6 @@ nsHTMLDocument::NamedItem(const nsString& aName, nsIDOMElement** aReturn)
*aReturn = nsnull;
}
- delete [] str;
return result;
}
diff --git a/mozilla/content/html/document/src/nsHTMLDocument.h b/mozilla/content/html/document/src/nsHTMLDocument.h
index c7867aaa4fc..e8ad3545664 100644
--- a/mozilla/content/html/document/src/nsHTMLDocument.h
+++ b/mozilla/content/html/document/src/nsHTMLDocument.h
@@ -60,6 +60,19 @@ public:
NS_IMETHOD GetDTDMode(nsDTDMode& aMode);
NS_IMETHOD SetDTDMode(nsDTDMode aMode);
+ NS_IMETHOD ContentAppended(nsIContent* aContainer,
+ PRInt32 aNewIndexInContainer);
+ NS_IMETHOD ContentInserted(nsIContent* aContainer,
+ nsIContent* aChild,
+ PRInt32 aIndexInContainer);
+ NS_IMETHOD ContentReplaced(nsIContent* aContainer,
+ nsIContent* aOldChild,
+ nsIContent* aNewChild,
+ PRInt32 aIndexInContainer);
+ NS_IMETHOD ContentRemoved(nsIContent* aContainer,
+ nsIContent* aChild,
+ PRInt32 aIndexInContainer);
+
// nsIDOMDocument interface
NS_IMETHOD GetDoctype(nsIDOMDocumentType** aDocumentType);
NS_IMETHOD GetImplementation(nsIDOMDOMImplementation** aImplementation)
@@ -138,6 +151,10 @@ protected:
protected:
static PRIntn RemoveStrings(PLHashEntry *he, PRIntn i, void *arg);
void RegisterNamedItems(nsIContent *aContent, PRBool aInForm);
+ void UnregisterNamedItems(nsIContent *aContent, PRBool aInForm);
+ nsIContent* FindNamedItem(nsIContent *aContent, const nsString& aName,
+ PRBool aInForm);
+
void DeleteNamedItems();
nsIContent *MatchName(nsIContent *aContent, const nsString& aName);
diff --git a/mozilla/layout/base/src/Makefile.in b/mozilla/layout/base/src/Makefile.in
index 3d37e9cc85d..d1c149eb6e6 100644
--- a/mozilla/layout/base/src/Makefile.in
+++ b/mozilla/layout/base/src/Makefile.in
@@ -29,6 +29,7 @@ DEFINES += -D_IMPL_NS_LAYOUT
CPPSRCS = \
nsContentList.cpp \
nsDocument.cpp \
+ nsDocumentFragment.cpp \
nsFrameImageLoader.cpp \
nsGalleyContext.cpp \
nsPresContext.cpp \
@@ -53,7 +54,7 @@ EXPORTS = \
nsXIFConverter.h \
$(NULL)
-INCLUDES += -I../../html/base/src
+INCLUDES += -I../../html/base/src -I../../html/content/src
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
diff --git a/mozilla/layout/base/src/makefile.win b/mozilla/layout/base/src/makefile.win
index 48d6750b84c..8bb196cb7f2 100644
--- a/mozilla/layout/base/src/makefile.win
+++ b/mozilla/layout/base/src/makefile.win
@@ -23,6 +23,7 @@ DEFINES=-D_IMPL_NS_LAYOUT -DWIN32_LEAN_AND_MEAN
CPPSRCS = \
nsContentList.cpp \
nsDocument.cpp \
+ nsDocumentFragment.cpp \
nsFrameImageLoader.cpp \
nsGalleyContext.cpp \
nsPresContext.cpp \
@@ -45,6 +46,7 @@ EXPORTS=nsSelectionRange.h nsSelectionPoint.h
CPP_OBJS= \
.\$(OBJDIR)\nsContentList.obj \
.\$(OBJDIR)\nsDocument.obj \
+ .\$(OBJDIR)\nsDocumentFragment.obj \
.\$(OBJDIR)\nsFrameImageLoader.obj \
.\$(OBJDIR)\nsGalleyContext.obj \
.\$(OBJDIR)\nsPresContext.obj \
@@ -62,7 +64,7 @@ CPP_OBJS= \
LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor \
-I$(PUBLIC)\dom -I$(PUBLIC)\js -I$(PUBLIC)\netlib \
- -I$(PUBLIC)\pref -I..\..\html\base\src
+ -I$(PUBLIC)\pref -I..\..\html\base\src -I..\..\html\content\src
LCFLAGS = \
$(LCFLAGS) \
diff --git a/mozilla/layout/html/content/src/nsGenericElement.h b/mozilla/layout/html/content/src/nsGenericElement.h
index f92b0fe2d4e..ce5358fba23 100644
--- a/mozilla/layout/html/content/src/nsGenericElement.h
+++ b/mozilla/layout/html/content/src/nsGenericElement.h
@@ -96,7 +96,7 @@ private:
// Another helper class that implements the nsIDOMNamedNodeMap interface.
class nsDOMAttributeMap : public nsIDOMNamedNodeMap,
- public nsIScriptObjectOwner
+ public nsIScriptObjectOwner
{
public:
nsDOMAttributeMap(nsIContent* aContent);
diff --git a/mozilla/layout/html/document/src/nsHTMLContentSink.cpp b/mozilla/layout/html/document/src/nsHTMLContentSink.cpp
index 70e27c62912..b10a2da5759 100644
--- a/mozilla/layout/html/document/src/nsHTMLContentSink.cpp
+++ b/mozilla/layout/html/document/src/nsHTMLContentSink.cpp
@@ -247,6 +247,7 @@ public:
nsresult GrowStack();
nsresult AddText(const nsString& aText);
nsresult FlushText(PRBool* aDidFlush = nsnull);
+ nsresult FlushTags();
void MaybeMarkSinkDirty();
@@ -1150,6 +1151,29 @@ SinkContext::AddText(const nsString& aText)
return NS_OK;
}
+/**
+ * Flush all elements that have been seen so far such that
+ * they are visible in the tree. Specifically, make sure
+ * that they are all added to their respective parents.
+ */
+nsresult
+SinkContext::FlushTags()
+{
+ FlushText();
+
+ PRInt32 stackPos = mStackPos-1;
+ while ((stackPos > 0) && (0 == (mStack[stackPos].mFlags & APPENDED))) {
+ nsIHTMLContent* content = mStack[stackPos].mContent;
+ nsIHTMLContent* parent = mStack[stackPos-1].mContent;
+
+ parent->AppendChildTo(content, PR_FALSE);
+ mStack[stackPos].mFlags |= APPENDED;
+ stackPos--;
+ }
+
+ return NS_OK;
+}
+
/**
* Flush any buffered text out by creating a text content object and
* adding it to the content.
@@ -2280,7 +2304,9 @@ HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
// Otherwise, get the text content of the script tag
script = aNode.GetSkippedContent();
}
-
+
+ mCurrentContext->FlushTags();
+
if (script != "") {
nsIScriptContextOwner *owner;
nsIScriptContext *context;
diff --git a/mozilla/layout/html/document/src/nsHTMLDocument.cpp b/mozilla/layout/html/document/src/nsHTMLDocument.cpp
index 9b3e6092da2..f0271af483e 100644
--- a/mozilla/layout/html/document/src/nsHTMLDocument.cpp
+++ b/mozilla/layout/html/document/src/nsHTMLDocument.cpp
@@ -391,6 +391,77 @@ nsHTMLDocument::SetDTDMode(nsDTDMode aMode)
return NS_OK;
}
+NS_IMETHODIMP
+nsHTMLDocument::ContentAppended(nsIContent* aContainer,
+ PRInt32 aNewIndexInContainer)
+{
+ if (nsnull != mNamedItems) {
+ nsIContent* child;
+ nsIAtom *name;
+
+ aContainer->GetTag(name);
+ aContainer->ChildAt(aNewIndexInContainer, child);
+ RegisterNamedItems(aContainer, name == nsHTMLAtoms::form);
+ NS_IF_RELEASE(child);
+ NS_IF_RELEASE(name);
+ }
+
+ return nsDocument::ContentAppended(aContainer, aNewIndexInContainer);
+}
+
+NS_IMETHODIMP
+nsHTMLDocument::ContentInserted(nsIContent* aContainer,
+ nsIContent* aChild,
+ PRInt32 aIndexInContainer)
+{
+ if (nsnull != mNamedItems) {
+ nsIAtom *name;
+
+ aContainer->GetTag(name);
+ RegisterNamedItems(aChild, name == nsHTMLAtoms::form);
+ NS_IF_RELEASE(name);
+ }
+
+ return nsDocument::ContentInserted(aContainer, aChild, aIndexInContainer);
+}
+
+NS_IMETHODIMP
+nsHTMLDocument::ContentReplaced(nsIContent* aContainer,
+ nsIContent* aOldChild,
+ nsIContent* aNewChild,
+ PRInt32 aIndexInContainer)
+{
+ if (nsnull != mNamedItems) {
+ nsIAtom *name;
+
+ aContainer->GetTag(name);
+ UnregisterNamedItems(aOldChild, name == nsHTMLAtoms::form);
+ RegisterNamedItems(aNewChild, name == nsHTMLAtoms::form);
+
+ NS_IF_RELEASE(name);
+ }
+
+ return nsDocument::ContentReplaced(aContainer, aOldChild,
+ aNewChild, aIndexInContainer);
+}
+
+NS_IMETHODIMP
+nsHTMLDocument::ContentRemoved(nsIContent* aContainer,
+ nsIContent* aChild,
+ PRInt32 aIndexInContainer)
+{
+ if (nsnull != mNamedItems) {
+ nsIAtom *name;
+
+ aContainer->GetTag(name);
+ UnregisterNamedItems(aChild, name == nsHTMLAtoms::form);
+
+ NS_IF_RELEASE(name);
+ }
+
+ return nsDocument::ContentRemoved(aContainer, aChild, aIndexInContainer);
+}
+
//
// nsIDOMDocument interface implementation
//
@@ -934,28 +1005,68 @@ nsHTMLDocument::DeleteNamedItems()
}
}
-void
-nsHTMLDocument::RegisterNamedItems(nsIContent *aContent, PRBool aInForm)
+static PRBool
+IsNamedItem(nsIContent* aContent, nsIAtom *aTag,
+ PRBool aInForm, nsString& aName)
{
static nsAutoString name("NAME");
- nsAutoString value;
- nsIAtom *tag;
- aContent->GetTag(tag);
- PRBool inForm;
// Only the content types reflected in Level 0 with a NAME
// attribute are registered. Images and forms always get
// reflected up to the document. Applets and embeds only go
// to the closest container (which could be a form).
- if ((tag == nsHTMLAtoms::img) || (tag == nsHTMLAtoms::form) ||
- (!aInForm && ((tag == nsHTMLAtoms::applet) ||
- (tag == nsHTMLAtoms::embed)))) {
- if (NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttribute(name, value)) {
- char *nameStr = value.ToNewCString();
- PL_HashTableAdd(mNamedItems, nameStr, aContent);
+ if ((aTag == nsHTMLAtoms::img) || (aTag == nsHTMLAtoms::form) ||
+ (!aInForm && ((aTag == nsHTMLAtoms::applet) ||
+ (aTag == nsHTMLAtoms::embed)))) {
+ if (NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttribute(name, aName)) {
+ return PR_TRUE;
}
}
+ return PR_FALSE;
+}
+
+void
+nsHTMLDocument::UnregisterNamedItems(nsIContent *aContent, PRBool aInForm)
+{
+ nsAutoString value;
+ nsIAtom *tag;
+ aContent->GetTag(tag);
+ PRBool inForm;
+
+ if (IsNamedItem(aContent, tag, aInForm, value)) {
+ char *nameStr = value.ToNewCString();
+ // XXX What about the string held in the hash table entry
+ PL_HashTableRemove(mNamedItems, nameStr);
+ delete [] nameStr;
+ }
+
+ inForm = aInForm || (tag == nsHTMLAtoms::form);
+ NS_IF_RELEASE(tag);
+
+ PRInt32 i, count;
+ aContent->ChildCount(count);
+ for (i = 0; i < count; i++) {
+ nsIContent *child;
+ aContent->ChildAt(i, child);
+ UnregisterNamedItems(child, inForm);
+ NS_RELEASE(child);
+ }
+}
+
+void
+nsHTMLDocument::RegisterNamedItems(nsIContent *aContent, PRBool aInForm)
+{
+ nsAutoString value;
+ nsIAtom *tag;
+ aContent->GetTag(tag);
+ PRBool inForm;
+
+ if (IsNamedItem(aContent, tag, aInForm, value)) {
+ char *nameStr = value.ToNewCString();
+ PL_HashTableAdd(mNamedItems, nameStr, aContent);
+ }
+
inForm = aInForm || (tag == nsHTMLAtoms::form);
NS_IF_RELEASE(tag);
@@ -969,22 +1080,68 @@ nsHTMLDocument::RegisterNamedItems(nsIContent *aContent, PRBool aInForm)
}
}
+nsIContent*
+nsHTMLDocument::FindNamedItem(nsIContent *aContent,
+ const nsString& aName,
+ PRBool aInForm)
+{
+ nsAutoString value;
+ nsIAtom *tag;
+ aContent->GetTag(tag);
+ PRBool inForm;
+
+ if (IsNamedItem(aContent, tag, aInForm, value)) {
+ if (aName.Equals(value)) {
+ NS_IF_RELEASE(tag);
+ return aContent;
+ }
+ }
+
+ inForm = aInForm || (tag == nsHTMLAtoms::form);
+ NS_IF_RELEASE(tag);
+
+ PRInt32 i, count;
+ nsIContent *result = nsnull;
+ aContent->ChildCount(count);
+ for (i = 0; (i < count) && (nsnull == result); i++) {
+ nsIContent *child;
+ aContent->ChildAt(i, child);
+ result = FindNamedItem(child, aName, inForm);
+ NS_RELEASE(child);
+ }
+
+ return result;
+}
+
NS_IMETHODIMP
nsHTMLDocument::NamedItem(const nsString& aName, nsIDOMElement** aReturn)
{
- static nsAutoString name("NAME");
nsresult result = NS_OK;
- nsIContent *content;
+ nsIContent *content = nsnull;
- if (nsnull == mNamedItems) {
- mNamedItems = PL_NewHashTable(10, PL_HashString, PL_CompareStrings,
- PL_CompareValues, nsnull, nsnull);
- RegisterNamedItems(mRootContent, PR_FALSE);
+ // XXX If we have a parser, it means that we're still loading the
+ // document. Since there's still content coming in (and not all
+ // may yet have been explicitly added to the document), we do
+ // a depth-first search rather than build up a table.
+ // Obviously, this may be inefficient for large documents.
+ if (nsnull != mParser) {
+ content = FindNamedItem(mRootContent, aName, PR_FALSE);
+ }
+ else {
+ // If the document has completed loading, we build a table and
+ // cache the named items. The table will be updated as content
+ // is added and removed.
+ if (nsnull == mNamedItems) {
+ mNamedItems = PL_NewHashTable(10, PL_HashString, PL_CompareStrings,
+ PL_CompareValues, nsnull, nsnull);
+ RegisterNamedItems(mRootContent, PR_FALSE);
+ }
+
+ char *str = aName.ToNewCString();
+ content = (nsIContent *)PL_HashTableLookup(mNamedItems, str);
+ delete [] str;
}
- char *str = aName.ToNewCString();
-
- content = (nsIContent *)PL_HashTableLookup(mNamedItems, str);
if (nsnull != content) {
result = content->QueryInterface(kIDOMElementIID, (void **)aReturn);
}
@@ -992,7 +1149,6 @@ nsHTMLDocument::NamedItem(const nsString& aName, nsIDOMElement** aReturn)
*aReturn = nsnull;
}
- delete [] str;
return result;
}
diff --git a/mozilla/layout/html/document/src/nsHTMLDocument.h b/mozilla/layout/html/document/src/nsHTMLDocument.h
index c7867aaa4fc..e8ad3545664 100644
--- a/mozilla/layout/html/document/src/nsHTMLDocument.h
+++ b/mozilla/layout/html/document/src/nsHTMLDocument.h
@@ -60,6 +60,19 @@ public:
NS_IMETHOD GetDTDMode(nsDTDMode& aMode);
NS_IMETHOD SetDTDMode(nsDTDMode aMode);
+ NS_IMETHOD ContentAppended(nsIContent* aContainer,
+ PRInt32 aNewIndexInContainer);
+ NS_IMETHOD ContentInserted(nsIContent* aContainer,
+ nsIContent* aChild,
+ PRInt32 aIndexInContainer);
+ NS_IMETHOD ContentReplaced(nsIContent* aContainer,
+ nsIContent* aOldChild,
+ nsIContent* aNewChild,
+ PRInt32 aIndexInContainer);
+ NS_IMETHOD ContentRemoved(nsIContent* aContainer,
+ nsIContent* aChild,
+ PRInt32 aIndexInContainer);
+
// nsIDOMDocument interface
NS_IMETHOD GetDoctype(nsIDOMDocumentType** aDocumentType);
NS_IMETHOD GetImplementation(nsIDOMDOMImplementation** aImplementation)
@@ -138,6 +151,10 @@ protected:
protected:
static PRIntn RemoveStrings(PLHashEntry *he, PRIntn i, void *arg);
void RegisterNamedItems(nsIContent *aContent, PRBool aInForm);
+ void UnregisterNamedItems(nsIContent *aContent, PRBool aInForm);
+ nsIContent* FindNamedItem(nsIContent *aContent, const nsString& aName,
+ PRBool aInForm);
+
void DeleteNamedItems();
nsIContent *MatchName(nsIContent *aContent, const nsString& aName);