Added nsDocumentFragment to build. Fixed bug 1256 - the content sink is flushed as soon as it encounters a script tag.
git-svn-id: svn://10.0.0.236/trunk@15407 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user