class OrphansEntry : public PLDHashEntryHdr { public: nsIContent *mKey;
nsDocument::nsDocument() {      mBindingManager = do_CreateInstance("@mozilla.org/xbl/binding-manager;1");  nsCOMPtr<nsIDocumentObserver> observer(do_QueryInterface(mBindingManager)); if (observer) {    mObservers.InsertElementAt(observer, 0); } }  nsDocument::~nsDocument() { mInDestructor = PR_TRUE;         PRInt32 indx; for (indx = mObservers.Count() - 1; indx >= 0; --indx) {  nsIDocumentObserver* observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(indx));  observer->DocumentWillBeDestroyed(this); }  mParentDocument = nsnull;    if (mSubDocuments) { PL_DHashTableDestroy(mSubDocuments);  mSubDocuments = nsnull; }  if (mRootContent) { if (mRootContent->GetDocument()) {    PRInt32 count = mChildren.Count(); for (indx = 0; indx < count; ++indx) { mChildren[indx]->SetDocument(nsnull, PR_TRUE, PR_FALSE); } } }  mRootContent = nsnull; mChildren.Clear();   indx = mStyleSheets.Count(); while (--indx >= 0) { mStyleSheets[indx]->SetOwningDocument(nsnull); } indx = mCatalogSheets.Count(); while (--indx >= 0) { mCatalogSheets[indx]->SetOwningDocument(nsnull); } if (mAttrStyleSheet) mAttrStyleSheet->SetOwningDocument(nsnull); if (mStyleAttrStyleSheet) mStyleAttrStyleSheet->SetOwningDocument(nsnull);  if (mChildNodes) { mChildNodes->DropReference(); }  if (mListenerManager) { mListenerManager->SetListenerTarget(nsnull); }  if (mScriptLoader) { mScriptLoader->DropDocumentReference(); }  if (mCSSLoader) { mCSSLoader->DropDocumentReference(); }   if (mNodeInfoManager) { mNodeInfoManager->DropDocumentReference(); NS_RELEASE(mNodeInfoManager); }  if (mAttrStyleSheet) { mAttrStyleSheet->SetOwningDocument(nsnull); }  if (mStyleAttrStyleSheet) { mStyleAttrStyleSheet->SetOwningDocument(nsnull); }  delete mHeaderData; delete mBoxObjectTable; delete mXPathDocument; }  PRBool gCheckedForXPathDOM = PR_FALSE; PRBool gHaveXPathDOM = PR_FALSE;  NS_INTERFACE_MAP_BEGIN(nsDocument) NS_INTERFACE_MAP_ENTRY(nsIDocument) NS_INTERFACE_MAP_ENTRY(nsIDOMDocument) NS_INTERFACE_MAP_ENTRY(nsIDOMNSDocument) NS_INTERFACE_MAP_ENTRY(nsIDOMDocumentEvent) NS_INTERFACE_MAP_ENTRY(nsIDOM3DocumentEvent) NS_INTERFACE_MAP_ENTRY(nsIDOMDocumentStyle) NS_INTERFACE_MAP_ENTRY(nsIDOMNSDocumentStyle) NS_INTERFACE_MAP_ENTRY(nsIDOMDocumentView) NS_INTERFACE_MAP_ENTRY(nsIDOMDocumentRange) NS_INTERFACE_MAP_ENTRY(nsIDOMDocumentTraversal) NS_INTERFACE_MAP_ENTRY(nsIDOMDocumentXBL) NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal) NS_INTERFACE_MAP_ENTRY(nsIDOMEventReceiver) NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget) NS_INTERFACE_MAP_ENTRY(nsIDOM3EventTarget) NS_INTERFACE_MAP_ENTRY(nsIDOMNode) NS_INTERFACE_MAP_ENTRY(nsIDOM3Node) NS_INTERFACE_MAP_ENTRY(nsIDOM3Document) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_ENTRY(nsIRadioGroupContainer) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocument) if (aIID.Equals(NS_GET_IID(nsIDOMXPathEvaluator)) && (!gCheckedForXPathDOM || gHaveXPathDOM)) { if (!mXPathDocument) { nsCOMPtr<nsIDOMXPathEvaluator> evaluator; nsresult rv; evaluator = do_CreateInstance(NS_XPATH_EVALUATOR_CONTRACTID, &rv); gCheckedForXPathDOM = PR_TRUE; gHaveXPathDOM = (evaluator != nsnull); if (rv == NS_ERROR_FACTORY_NOT_REGISTERED) { return NS_ERROR_NO_INTERFACE; } NS_ENSURE_SUCCESS(rv, rv);  nsCOMPtr<nsIXPathEvaluatorInternal> internal = do_QueryInterface(evaluator); if (internal) { internal->SetDocument(this); }  mXPathDocument = new nsXPathDocumentTearoff(evaluator, this); NS_ENSURE_TRUE(mXPathDocument, NS_ERROR_OUT_OF_MEMORY); } foundInterface = mXPathDocument; } else NS_INTERFACE_MAP_END  NS_IMPL_ADDREF(nsDocument) NS_IMPL_RELEASE(nsDocument)  nsresult nsDocument::Init() { if (mNodeInfoManager) { return NS_ERROR_ALREADY_INITIALIZED; }  mNodeInfoManager = new nsNodeInfoManager(); NS_ENSURE_TRUE(mNodeInfoManager, NS_ERROR_OUT_OF_MEMORY);  NS_ADDREF(mNodeInfoManager);  return mNodeInfoManager->Init(this); }  nsresult nsDocument::AddXMLEventsContent(nsIContent *aXMLEventsElement) { if (!mXMLEventsManager) { mXMLEventsManager = new nsXMLEventsManager(); NS_ENSURE_TRUE(mXMLEventsManager, NS_ERROR_OUT_OF_MEMORY); AddObserver(mXMLEventsManager); } mXMLEventsManager->AddXMLEventsContent(aXMLEventsElement); return NS_OK; }  void nsDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) { nsCOMPtr<nsIURI> uri; if (aChannel) { aChannel->GetOriginalURI(getter_AddRefs(uri)); nsresult rv; PRBool isAbout = PR_FALSE; PRBool isChrome = PR_FALSE; PRBool isRes = PR_FALSE; rv = uri->SchemeIs("chrome", &isChrome); rv |= uri->SchemeIs("resource", &isRes); rv |= uri->SchemeIs("about", &isAbout);  if (NS_SUCCEEDED(rv) && !isChrome && !isRes && !isAbout) { aChannel->GetURI(getter_AddRefs(uri)); } }  ResetToURI(uri, aLoadGroup);  if (aChannel) { nsCOMPtr<nsISupports> owner; aChannel->GetOwner(getter_AddRefs(owner));  mPrincipal = do_QueryInterface(owner); } }  void nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup) { NS_PRECONDITION(aURI, "Null URI passed to ResetToURI"); mDocumentTitle.Truncate();  mPrincipal = nsnull; mSecurityInfo = nsnull;  mDocumentLoadGroup = nsnull;    if (mSubDocuments) { PL_DHashTableDestroy(mSubDocuments);  mSubDocuments = nsnull; }  mRootContent = nsnull; PRInt32 count, i; count = mChildren.Count(); for (i = 0; i < count; i++) { nsCOMPtr<nsIContent> content = mChildren[i];  content->SetDocument(nsnull, PR_TRUE, PR_TRUE); ContentRemoved(nsnull, content, i); } mChildren.Clear();   ResetStylesheetsToURI(aURI);   mListenerManager = nsnull;   mDOMStyleSheets = nsnull;  mDocumentURI = aURI; mDocumentBaseURI = mDocumentURI;  if (aLoadGroup) { mDocumentLoadGroup = do_GetWeakReference(aLoadGroup);    }  mLastModified.Truncate(); mContentType.Truncate(); mContentLanguage.Truncate(); mBaseTarget.Truncate(); mReferrer.Truncate();  mXMLDeclarationBits = 0; }  nsresult nsDocument::ResetStylesheetsToURI(nsIURI* aURI) { NS_PRECONDITION(aURI, "Null URI passed to ResetStylesheetsToURI");  mozAutoDocUpdate(this, UPDATE_STYLE, PR_TRUE);   PRInt32 indx = mStyleSheets.Count(); while (--indx >= 0) { nsIStyleSheet* sheet = mStyleSheets[indx]; sheet->SetOwningDocument(nsnull);  PRBool applicable; sheet->GetApplicable(applicable); if (applicable) { RemoveStyleSheetFromStyleSets(sheet); }   }  indx = mCatalogSheets.Count(); while (--indx >= 0) { nsIStyleSheet* sheet = mCatalogSheets[indx]; sheet->SetOwningDocument(nsnull);  PRBool applicable; sheet->GetApplicable(applicable); if (applicable) { for (PRInt32 i = 0, i_end = mPresShells.Count(); i < i_end; ++i) { NS_STATIC_CAST(nsIPresShell*, mPresShells.ElementAt(i))->StyleSet()-> RemoveStyleSheet(nsStyleSet::eAgentSheet, sheet); } }   }    mStyleSheets.Clear();      nsresult rv; nsStyleSet::sheetType attrSheetType = GetAttrSheetType(); if (mAttrStyleSheet) {  PRInt32 count = mPresShells.Count(); for (indx = 0; indx < count; ++indx) { NS_STATIC_CAST(nsIPresShell*, mPresShells.ElementAt(indx))->StyleSet()-> RemoveStyleSheet(attrSheetType, mAttrStyleSheet); } rv = mAttrStyleSheet->Reset(aURI); } else { rv = NS_NewHTMLStyleSheet(getter_AddRefs(mAttrStyleSheet), aURI, this); } NS_ENSURE_SUCCESS(rv, rv);    mAttrStyleSheet->SetOwningDocument(this);  if (mStyleAttrStyleSheet) {  PRInt32 count = mPresShells.Count(); for (indx = 0; indx < count; ++indx) { NS_STATIC_CAST(nsIPresShell*, mPresShells.ElementAt(indx))->StyleSet()-> RemoveStyleSheet(nsStyleSet::eStyleAttrSheet, mStyleAttrStyleSheet); } rv = mStyleAttrStyleSheet->Reset(aURI); } else { rv = NS_NewHTMLCSSStyleSheet(getter_AddRefs(mStyleAttrStyleSheet), aURI, this); } NS_ENSURE_SUCCESS(rv, rv);    mStyleAttrStyleSheet->SetOwningDocument(this);   PRInt32 count = mPresShells.Count(); for (indx = 0; indx < count; ++indx) { FillStyleSet(NS_STATIC_CAST(nsIPresShell*, mPresShells.ElementAt(indx))->StyleSet()); }  return rv; }  nsStyleSet::sheetType nsDocument::GetAttrSheetType() { return nsStyleSet::ePresHintSheet; }  void nsDocument::FillStyleSet(nsStyleSet* aStyleSet) { NS_PRECONDITION(aStyleSet, "Must have a style set"); NS_PRECONDITION(aStyleSet->SheetCount(nsStyleSet::ePresHintSheet) == 0, "Style set already has a preshint sheet?"); NS_PRECONDITION(aStyleSet->SheetCount(nsStyleSet::eHTMLPresHintSheet) == 0, "Style set already has a HTML preshint sheet?"); NS_PRECONDITION(aStyleSet->SheetCount(nsStyleSet::eDocSheet) == 0, "Style set already has document sheets?"); NS_PRECONDITION(aStyleSet->SheetCount(nsStyleSet::eStyleAttrSheet) == 0, "Style set already has style attr sheets?"); NS_PRECONDITION(mStyleAttrStyleSheet, "No style attr stylesheet?"); NS_PRECONDITION(mAttrStyleSheet, "No attr stylesheet?");  aStyleSet->AppendStyleSheet(GetAttrSheetType(), mAttrStyleSheet);  aStyleSet->AppendStyleSheet(nsStyleSet::eStyleAttrSheet, mStyleAttrStyleSheet);  PRInt32 i; for (i = mStyleSheets.Count() - 1; i >= 0; --i) { nsIStyleSheet* sheet = mStyleSheets[i]; PRBool sheetApplicable; sheet->GetApplicable(sheetApplicable); if (sheetApplicable) { aStyleSet->AddDocStyleSheet(sheet, this); } }  for (i = mCatalogSheets.Count() - 1; i >= 0; --i) { nsIStyleSheet* sheet = mCatalogSheets[i]; PRBool sheetApplicable; sheet->GetApplicable(sheetApplicable); if (sheetApplicable) { aStyleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, sheet); } } }  nsresult nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel, nsILoadGroup* aLoadGroup, nsISupports* aContainer, nsIStreamListener **aDocListener, PRBool aReset, nsIContentSink* aSink) { if (aReset) { Reset(aChannel, aLoadGroup); }  nsCAutoString contentType; if (NS_SUCCEEDED(aChannel->GetContentType(contentType))) {  nsACString::const_iterator start, end, semicolon; contentType.BeginReading(start); contentType.EndReading(end); semicolon = start; FindCharInReadable(';', semicolon, end); mContentType = Substring(start, semicolon); }  RetrieveRelevantHeaders(aChannel);  return NS_OK; }  void nsDocument::StopDocumentLoad() { }  NS_IMETHODIMP nsDocument::GetLastModified(nsAString& aLastModified) { if (!mLastModified.IsEmpty()) { CopyASCIItoUCS2(mLastModified, aLastModified); } else {   CopyASCIItoUCS2(NS_LITERAL_CSTRING("January 1, 1970 GMT"), aLastModified); }  return NS_OK; }  nsIPrincipal* nsDocument::GetPrincipal() { if (!mPrincipal) { nsresult rv; nsCOMPtr<nsIScriptSecurityManager> securityManager = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); if (NS_FAILED(rv)) return nsnull; NS_WARN_IF_FALSE(mDocumentURI, "no URI!"); rv = securityManager->GetCodebasePrincipal(mDocumentURI, getter_AddRefs(mPrincipal));  if (NS_FAILED(rv)) { return nsnull; } }  return mPrincipal; }  void nsDocument::SetPrincipal(nsIPrincipal *aNewPrincipal) { mPrincipal = aNewPrincipal; }  NS_IMETHODIMP nsDocument::GetContentType(nsAString& aContentType) { CopyUTF8toUTF16(mContentType, aContentType);  return NS_OK; }  void nsDocument::SetContentType(const nsAString& aContentType) { NS_ASSERTION(mContentType.IsEmpty() || mContentType.Equals(NS_ConvertUCS2toUTF8(aContentType)), "Do you really want to change the content-type?");  CopyUTF16toUTF8(aContentType, mContentType); }  NS_IMETHODIMP nsDocument::GetReferrer(nsAString& aReferrer) { CopyUTF8toUTF16(mReferrer, aReferrer); return NS_OK; }  nsresult nsDocument::SetBaseURI(nsIURI* aURI) { nsresult rv = NS_OK;  if (aURI) { nsIPrincipal* principal = GetPrincipal(); NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE);  nsIScriptSecurityManager* securityManager = nsContentUtils::GetSecurityManager(); rv = securityManager-> CheckLoadURIWithPrincipal(principal, aURI, nsIScriptSecurityManager::STANDARD); if (NS_SUCCEEDED(rv)) { mDocumentBaseURI = aURI; } } else { mDocumentBaseURI = nsnull; }  return rv; }  void nsDocument::GetBaseTarget(nsAString &aBaseTarget) const { aBaseTarget.Assign(mBaseTarget); }  void nsDocument::SetBaseTarget(const nsAString &aBaseTarget) { mBaseTarget.Assign(aBaseTarget); }  void nsDocument::SetDocumentCharacterSet(const nsACString& aCharSetID) { if (!mCharacterSet.Equals(aCharSetID)) { mCharacterSet = aCharSetID;  #ifdef DEBUG nsCOMPtr<nsICharsetAlias> calias(do_GetService(kCharsetAliasCID)); if (calias) { nsCAutoString canonicalName; calias->GetPreferred(aCharSetID, canonicalName); NS_ASSERTION(canonicalName.Equals(aCharSetID), "charset name must be canonical"); } #endif  PRInt32 n = mCharSetObservers.Count();  for (PRInt32 i = 0; i < n; i++) { nsIObserver* observer = NS_STATIC_CAST(nsIObserver *, mCharSetObservers.ElementAt(i));  observer->Observe(NS_STATIC_CAST(nsIDocument *, this), "charset", NS_ConvertASCIItoUCS2(aCharSetID).get()); } } }  nsresult nsDocument::AddCharSetObserver(nsIObserver* aObserver) { NS_ENSURE_ARG_POINTER(aObserver);  NS_ENSURE_TRUE(mCharSetObservers.AppendElement(aObserver), NS_ERROR_FAILURE);  return NS_OK; }  void nsDocument::RemoveCharSetObserver(nsIObserver* aObserver) { mCharSetObservers.RemoveElement(aObserver); }  nsILineBreaker* nsDocument::GetLineBreaker() { if (!mLineBreaker) {  nsresult rv; nsCOMPtr<nsILineBreakerFactory> lbf = do_GetService(NS_LWBRK_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, nsnull);  lbf->GetBreaker(EmptyString(), getter_AddRefs(mLineBreaker)); NS_ENSURE_TRUE(mLineBreaker, nsnull); }  return mLineBreaker; }  void nsDocument::SetLineBreaker(nsILineBreaker* aLineBreaker) { mLineBreaker = aLineBreaker; }  nsIWordBreaker* nsDocument::GetWordBreaker() { if (!mWordBreaker) {  nsresult rv; nsCOMPtr<nsIWordBreakerFactory> wbf = do_GetService(NS_LWBRK_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, nsnull);  wbf->GetBreaker(EmptyString(), getter_AddRefs(mWordBreaker)); NS_ENSURE_TRUE(wbf, nsnull); }  return mWordBreaker; }  void nsDocument::SetWordBreaker(nsIWordBreaker* aWordBreaker) { mWordBreaker = aWordBreaker; }  void nsDocument::GetHeaderData(nsIAtom* aHeaderField, nsAString& aData) const { aData.Truncate(); const nsDocHeaderData* data = mHeaderData; while (data) { if (data->mField == aHeaderField) { aData = data->mData;  break; } data = data->mNext; } }  void nsDocument::SetHeaderData(nsIAtom* aHeaderField, const nsAString& aData) { if (!aHeaderField) { NS_ERROR("null headerField"); return; }  if (!mHeaderData) { if (!aData.IsEmpty()) { mHeaderData = new nsDocHeaderData(aHeaderField, aData); } } else { nsDocHeaderData* data = mHeaderData; nsDocHeaderData** lastPtr = &mHeaderData; PRBool found = PR_FALSE; do { if (data->mField == aHeaderField) { if (!aData.IsEmpty()) { data->mData.Assign(aData); } else { *lastPtr = data->mNext; data->mNext = nsnull; delete data; } found = PR_TRUE;  break; } lastPtr = &(data->mNext); data = *lastPtr; } while (data);  if (!aData.IsEmpty() && !found) {  *lastPtr = new nsDocHeaderData(aHeaderField, aData); } }  if (aHeaderField == nsHTMLAtoms::headerContentLanguage) { CopyUTF16toUTF8(aData, mContentLanguage); }  if (aHeaderField == nsHTMLAtoms::headerDefaultStyle) {    nsAutoString type; nsAutoString title; PRInt32 index;  mCSSLoader->SetPreferredSheet(aData);  PRInt32 count = mStyleSheets.Count(); for (index = 0; index < count; index++) { nsIStyleSheet* sheet = mStyleSheets[index]; sheet->GetType(type); if (!type.EqualsLiteral("text/html")) { sheet->GetTitle(title); if (!title.IsEmpty()) { PRBool enabled = (!aData.IsEmpty() && title.Equals(aData, nsCaseInsensitiveStringComparator()));  sheet->SetEnabled(enabled); } } } } }  PRBool nsDocument::TryChannelCharset(nsIChannel *aChannel, PRInt32& aCharsetSource, nsACString& aCharset) { if(kCharsetFromChannel <= aCharsetSource) { return PR_TRUE; }  if (aChannel) { nsCAutoString charsetVal; nsresult rv = aChannel->GetContentCharset(charsetVal); if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsICharsetAlias> calias(do_GetService(kCharsetAliasCID)); if (calias) { nsCAutoString preferred; rv = calias->GetPreferred(charsetVal, preferred); if(NS_SUCCEEDED(rv)) { aCharset = preferred; aCharsetSource = kCharsetFromChannel; return PR_TRUE; } } } } return PR_FALSE; }  nsresult nsDocument::CreateShell(nsPresContext* aContext, nsIViewManager* aViewManager, nsStyleSet* aStyleSet, nsIPresShell** aInstancePtrResult) {    return doCreateShell(aContext, aViewManager, aStyleSet, eCompatibility_FullStandards, aInstancePtrResult); }  nsresult nsDocument::doCreateShell(nsPresContext* aContext, nsIViewManager* aViewManager, nsStyleSet* aStyleSet, nsCompatibility aCompatMode, nsIPresShell** aInstancePtrResult) { *aInstancePtrResult = nsnull;  FillStyleSet(aStyleSet);  nsCOMPtr<nsIPresShell> shell; nsresult rv = NS_NewPresShell(getter_AddRefs(shell)); if (NS_FAILED(rv)) { return rv; }  rv = shell->Init(this, aContext, aViewManager, aStyleSet, aCompatMode); NS_ENSURE_SUCCESS(rv, rv);   mPresShells.AppendElement(shell); shell.swap(*aInstancePtrResult);  return NS_OK; }  PRBool nsDocument::DeleteShell(nsIPresShell* aShell) { return mPresShells.RemoveElement(aShell); }  PRUint32 nsDocument::GetNumberOfShells() const { return mPresShells.Count(); }  nsIPresShell * nsDocument::GetShellAt(PRUint32 aIndex) const { return (nsIPresShell*)mPresShells.SafeElementAt(aIndex); }  PR_STATIC_CALLBACK(void) SubDocClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry) { SubDocMapEntry *e = NS_STATIC_CAST(SubDocMapEntry *, entry);  NS_RELEASE(e->mKey); NS_IF_RELEASE(e->mSubDocument); }  PR_STATIC_CALLBACK(PRBool) SubDocInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry, const void *key) { SubDocMapEntry *e = NS_CONST_CAST(SubDocMapEntry *, NS_STATIC_CAST(const SubDocMapEntry *, entry));  e->mKey = NS_CONST_CAST(nsIContent *, NS_STATIC_CAST(const nsIContent *, key)); NS_ADDREF(e->mKey);  e->mSubDocument = nsnull; return PR_TRUE; }  nsresult nsDocument::SetSubDocumentFor(nsIContent *aContent, nsIDocument* aSubDoc) { NS_ENSURE_TRUE(aContent, NS_ERROR_UNEXPECTED);  if (!aSubDoc) {   if (mSubDocuments) { SubDocMapEntry *entry = NS_STATIC_CAST(SubDocMapEntry*, PL_DHashTableOperate(mSubDocuments, aContent, PL_DHASH_LOOKUP));  if (PL_DHASH_ENTRY_IS_BUSY(entry)) { entry->mSubDocument->SetParentDocument(nsnull);  PL_DHashTableRawRemove(mSubDocuments, entry); } } } else { if (!mSubDocuments) {   static PLDHashTableOps hash_table_ops = { PL_DHashAllocTable, PL_DHashFreeTable, PL_DHashGetKeyStub, PL_DHashVoidPtrKeyStub, PL_DHashMatchEntryStub, PL_DHashMoveEntryStub, SubDocClearEntry, PL_DHashFinalizeStub, SubDocInitEntry };  mSubDocuments = PL_NewDHashTable(&hash_table_ops, nsnull, sizeof(SubDocMapEntry), 16); if (!mSubDocuments) { return NS_ERROR_OUT_OF_MEMORY; } }   SubDocMapEntry *entry = NS_STATIC_CAST(SubDocMapEntry*, PL_DHashTableOperate(mSubDocuments, aContent, PL_DHASH_ADD));  if (!entry) { return NS_ERROR_OUT_OF_MEMORY; }  if (entry->mSubDocument) { entry->mSubDocument->SetParentDocument(nsnull);   NS_RELEASE(entry->mSubDocument); }  entry->mSubDocument = aSubDoc; NS_ADDREF(entry->mSubDocument);  aSubDoc->SetParentDocument(this); }  return NS_OK; }  nsIDocument* nsDocument::GetSubDocumentFor(nsIContent *aContent) const { if (mSubDocuments) { SubDocMapEntry *entry = NS_STATIC_CAST(SubDocMapEntry*, PL_DHashTableOperate(mSubDocuments, aContent, PL_DHASH_LOOKUP));  if (PL_DHASH_ENTRY_IS_BUSY(entry)) { return entry->mSubDocument; } }  return nsnull; }  PR_STATIC_CALLBACK(PLDHashOperator) FindContentEnumerator(PLDHashTable *table, PLDHashEntryHdr *hdr, PRUint32 number, void *arg) { SubDocMapEntry *entry = NS_STATIC_CAST(SubDocMapEntry*, hdr); FindContentData *data = NS_STATIC_CAST(FindContentData*, arg);  if (entry->mSubDocument == data->mSubDocument) { data->mResult = entry->mKey;  return PL_DHASH_STOP; }  return PL_DHASH_NEXT; }  nsIContent* nsDocument::FindContentForSubDocument(nsIDocument *aDocument) const { NS_ENSURE_TRUE(aDocument, nsnull);  if (!mSubDocuments) { return nsnull; }  FindContentData data(aDocument); PL_DHashTableEnumerate(mSubDocuments, FindContentEnumerator, &data);  return data.mResult; }  void nsDocument::SetRootContent(nsIContent* aRoot) { if (mRootContent) { PRInt32 indx = mChildren.IndexOf(mRootContent); if (aRoot) { mChildren.ReplaceObjectAt(aRoot, indx); } else { mChildren.RemoveObjectAt(indx); } } else if (aRoot) { mChildren.AppendObject(aRoot); }  mRootContent = aRoot; }  nsIContent * nsDocument::GetChildAt(PRUint32 aIndex) const { if (aIndex >= (PRUint32)mChildren.Count()) { return nsnull; }  return mChildren[aIndex]; }  PRInt32 nsDocument::IndexOf(nsIContent* aPossibleChild) const { return mChildren.IndexOf(aPossibleChild); }  PRUint32 nsDocument::GetChildCount() const { return mChildren.Count(); }  PRInt32 nsDocument::GetNumberOfStyleSheets() const { return mStyleSheets.Count(); }  nsIStyleSheet* nsDocument::GetStyleSheetAt(PRInt32 aIndex) const { NS_ENSURE_TRUE(0 <= aIndex && aIndex < mStyleSheets.Count(), nsnull); return mStyleSheets[aIndex]; }  PRInt32 nsDocument::GetIndexOfStyleSheet(nsIStyleSheet* aSheet) const { return mStyleSheets.IndexOf(aSheet); }  void nsDocument::AddStyleSheetToStyleSets(nsIStyleSheet* aSheet) { PRInt32 count = mPresShells.Count(); PRInt32 indx; for (indx = 0; indx < count; ++indx) { NS_STATIC_CAST(nsIPresShell*, mPresShells.ElementAt(indx))->StyleSet()-> AddDocStyleSheet(aSheet, this); } }  void nsDocument::AddStyleSheet(nsIStyleSheet* aSheet) { NS_PRECONDITION(aSheet, "null arg"); mStyleSheets.AppendObject(aSheet); aSheet->SetOwningDocument(this);  PRBool applicable; aSheet->GetApplicable(applicable);  if (applicable) { AddStyleSheetToStyleSets(aSheet); }   PRInt32 i; for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver* observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(i));  observer->StyleSheetAdded(this, aSheet, PR_TRUE); } }  void nsDocument::RemoveStyleSheetFromStyleSets(nsIStyleSheet* aSheet) { for (PRInt32 i = 0, i_end = mPresShells.Count(); i < i_end; ++i) NS_STATIC_CAST(nsIPresShell*, mPresShells.ElementAt(i))->StyleSet()-> RemoveStyleSheet(nsStyleSet::eDocSheet, aSheet); }  void nsDocument::RemoveStyleSheet(nsIStyleSheet* aSheet) { NS_PRECONDITION(aSheet, "null arg"); nsCOMPtr<nsIStyleSheet> sheet = aSheet;  if (!mStyleSheets.RemoveObject(aSheet)) { NS_NOTREACHED("stylesheet not found"); return; }  if (!mIsGoingAway) { PRBool applicable = PR_TRUE; aSheet->GetApplicable(applicable); if (applicable) { RemoveStyleSheetFromStyleSets(aSheet); }     for (PRInt32 indx = mObservers.Count() - 1; indx >= 0; --indx) { nsIDocumentObserver *observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(indx));  observer->StyleSheetRemoved(this, aSheet, PR_TRUE); } }  aSheet->SetOwningDocument(nsnull); }  void nsDocument::UpdateStyleSheets(nsCOMArray<nsIStyleSheet>& aOldSheets, nsCOMArray<nsIStyleSheet>& aNewSheets) {   PRInt32 obsIndx; for (obsIndx = mObservers.Count() - 1; obsIndx >= 0; --obsIndx) { nsIDocumentObserver *observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(obsIndx));  observer->BeginUpdate(this, UPDATE_STYLE); }   NS_PRECONDITION(aOldSheets.Count() == aNewSheets.Count(), "The lists must be the same length!"); PRInt32 count = aOldSheets.Count();  nsCOMPtr<nsIStyleSheet> oldSheet; PRInt32 i; for (i = 0; i < count; ++i) { oldSheet = aOldSheets[i];   NS_ASSERTION(oldSheet, "None of the old sheets should be null"); PRInt32 oldIndex = mStyleSheets.IndexOf(oldSheet); RemoveStyleSheet(oldSheet);   nsIStyleSheet* newSheet = aNewSheets[i]; if (newSheet) { mStyleSheets.InsertObjectAt(newSheet, oldIndex); newSheet->SetOwningDocument(this); PRBool applicable = PR_TRUE; newSheet->GetApplicable(applicable); if (applicable) { AddStyleSheetToStyleSets(newSheet); }  for (obsIndx = mObservers.Count() - 1; obsIndx >= 0; --obsIndx) { nsIDocumentObserver *observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(obsIndx));  observer->StyleSheetAdded(this, newSheet, PR_TRUE); } } }  for (obsIndx = mObservers.Count() - 1; obsIndx >= 0; --obsIndx) { nsIDocumentObserver *observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(obsIndx));  observer->EndUpdate(this, UPDATE_STYLE); } }  void nsDocument::InsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex) { NS_PRECONDITION(aSheet, "null ptr"); mStyleSheets.InsertObjectAt(aSheet, aIndex);  aSheet->SetOwningDocument(this);  PRBool applicable; aSheet->GetApplicable(applicable);  if (applicable) { AddStyleSheetToStyleSets(aSheet); }    PRInt32 i; for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver *observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(i));  observer->StyleSheetAdded(this, aSheet, PR_TRUE); } }   void nsDocument::SetStyleSheetApplicableState(nsIStyleSheet* aSheet, PRBool aApplicable) { NS_PRECONDITION(aSheet, "null arg");   if (-1 != mStyleSheets.IndexOf(aSheet)) { if (aApplicable) { AddStyleSheetToStyleSets(aSheet); } else { RemoveStyleSheetFromStyleSets(aSheet); } }      PRInt32 indx;  for (indx = mObservers.Count() - 1; indx >= 0; --indx) { nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(indx); observer->StyleSheetApplicableStateChanged(this, aSheet, aApplicable); } }     PRInt32 nsDocument::GetNumberOfCatalogStyleSheets() const { return mCatalogSheets.Count(); }  nsIStyleSheet* nsDocument::GetCatalogStyleSheetAt(PRInt32 aIndex) const { NS_ENSURE_TRUE(0 <= aIndex && aIndex < mCatalogSheets.Count(), nsnull); return mCatalogSheets[aIndex]; }  void nsDocument::AddCatalogStyleSheet(nsIStyleSheet* aSheet) { mCatalogSheets.AppendObject(aSheet); aSheet->SetOwningDocument(this);  PRBool applicable; aSheet->GetApplicable(applicable);  if (applicable) {  for (PRInt32 i = 0, i_end = mPresShells.Count(); i < i_end; ++i) NS_STATIC_CAST(nsIPresShell*, mPresShells.ElementAt(i))->StyleSet()-> AppendStyleSheet(nsStyleSet::eAgentSheet, aSheet); }   PRInt32 i; for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver* observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(i));  observer->StyleSheetAdded(this, aSheet, PR_FALSE); } }  nsIScriptGlobalObject* nsDocument::GetScriptGlobalObject() const {     if (mIsGoingAway) { nsCOMPtr<nsIInterfaceRequestor> requestor = do_QueryReferent(mDocumentContainer); if (requestor) { nsCOMPtr<nsIScriptGlobalObject> globalObject = do_GetInterface(requestor); return globalObject; } }  return mScriptGlobalObject; }  void nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject) {      if (!aScriptGlobalObject) { PRInt32 count, indx;  count = mChildren.Count();  mIsGoingAway = PR_TRUE;  for (indx = 0; indx < count; ++indx) { mChildren[indx]->SetDocument(nsnull, PR_TRUE, PR_TRUE); }       for (count = mPresShells.Count() - 1; count >= 0; --count) { nsCOMPtr<nsIPresShell> shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[count]); if (!shell) continue;  shell->ReleaseAnonymousContent(); }  #ifdef DEBUG_jst printf ("Content wrapper hash had %d entries.\n", mContentWrapperHash.Count()); #endif  mContentWrapperHash.Reset(); }  mScriptGlobalObject = aScriptGlobalObject; }  nsIScriptLoader * nsDocument::GetScriptLoader() { if (!mScriptLoader) { mScriptLoader = new nsScriptLoader(); if (!mScriptLoader) { return nsnull; } mScriptLoader->Init(this); }  return mScriptLoader; }    void nsDocument::AddObserver(nsIDocumentObserver* aObserver) {  if (mObservers.IndexOf(aObserver) == -1) { mObservers.AppendElement(aObserver); } }  PRBool nsDocument::RemoveObserver(nsIDocumentObserver* aObserver) {     if (!mInDestructor) { return mObservers.RemoveElement(aObserver); }  return (mObservers.IndexOf(aObserver) != -1); }  void nsDocument::BeginUpdate(nsUpdateType aUpdateType) { PRInt32 i; for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i]; observer->BeginUpdate(this, aUpdateType); } }  void nsDocument::EndUpdate(nsUpdateType aUpdateType) { PRInt32 i; for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i]; observer->EndUpdate(this, aUpdateType); } }  void nsDocument::BeginLoad() { PRInt32 i; for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i]; observer->BeginLoad(this); } }  static void GetDocumentFromDocShellTreeItem(nsIDocShellTreeItem *aDocShell, nsIDocument **aDocument) { *aDocument = nsnull;  nsCOMPtr<nsIDOMWindow> window(do_GetInterface(aDocShell));  if (window) { nsCOMPtr<nsIDOMDocument> dom_doc; window->GetDocument(getter_AddRefs(dom_doc));  if (dom_doc) { CallQueryInterface(dom_doc, aDocument); } } }  void nsDocument::EndLoad() { PRInt32 i; for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; observer->EndLoad(this); }     nsCOMPtr<nsIDOMEvent> event; CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));  if (event) { event->InitEvent(NS_LITERAL_STRING("DOMContentLoaded"), PR_TRUE, PR_TRUE); PRBool noDefault; DispatchEvent(event, &noDefault); }       nsCOMPtr<nsIDocShellTreeItem> docShellParent;     nsCOMPtr<nsIDOMEventTarget> target_frame;  if (mScriptGlobalObject) { nsCOMPtr<nsIDocShellTreeItem> docShellAsItem = do_QueryInterface(mScriptGlobalObject->GetDocShell());  if (docShellAsItem) { docShellAsItem->GetSameTypeParent(getter_AddRefs(docShellParent));  nsCOMPtr<nsIDocument> parent_doc;  GetDocumentFromDocShellTreeItem(docShellParent, getter_AddRefs(parent_doc));  if (parent_doc) { target_frame = do_QueryInterface(parent_doc->FindContentForSubDocument(this)); } } }  if (target_frame) { while (docShellParent) { nsCOMPtr<nsIDocument> ancestor_doc;  GetDocumentFromDocShellTreeItem(docShellParent, getter_AddRefs(ancestor_doc));  if (!ancestor_doc) { break; }  nsCOMPtr<nsIPrivateDOMEvent> private_event;  nsCOMPtr<nsIDOMDocumentEvent> document_event = do_QueryInterface(ancestor_doc);  if (document_event) { document_event->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));  private_event = do_QueryInterface(event); }  if (event && private_event) { event->InitEvent(NS_LITERAL_STRING("DOMFrameContentLoaded"), PR_TRUE, PR_TRUE);  private_event->SetTarget(target_frame);        nsEvent* innerEvent; private_event->GetInternalNSEvent(&innerEvent); if (innerEvent) { nsEventStatus status = nsEventStatus_eIgnore;  nsIPresShell *shell = ancestor_doc->GetShellAt(0); if (shell) { nsCOMPtr<nsPresContext> context; shell->GetPresContext(getter_AddRefs(context));  if (context) {    nsIDOMEvent *tmp_event = event; NS_ADDREF(tmp_event);  ancestor_doc->HandleDOMEvent(context, innerEvent, &tmp_event, NS_EVENT_FLAG_INIT, &status);  NS_IF_RELEASE(tmp_event); } } } }  nsCOMPtr<nsIDocShellTreeItem> tmp(docShellParent); tmp->GetSameTypeParent(getter_AddRefs(docShellParent)); } } }  void nsDocument::CharacterDataChanged(nsIContent* aContent, PRBool aAppend) { NS_ABORT_IF_FALSE(aContent, "Null content!");  PRInt32 i; for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver *observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(i));  observer->CharacterDataChanged(this, aContent, aAppend); } }  void nsDocument::ContentStatesChanged(nsIContent* aContent1, nsIContent* aContent2, PRInt32 aStateMask) { PRInt32 i; for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver *observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(i));  observer->ContentStatesChanged(this, aContent1, aContent2, aStateMask); } }   void nsDocument::ContentAppended(nsIContent* aContainer, PRInt32 aNewIndexInContainer) { NS_ABORT_IF_FALSE(aContainer, "Null container!");  PRInt32 i;     for (i = 0; i < mObservers.Count(); i++) { nsIDocumentObserver *observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(i));  observer->ContentAppended(this, aContainer, aNewIndexInContainer);   if (i < mObservers.Count() && observer != (nsIDocumentObserver*)mObservers[i]) { i--; } } }  void nsDocument::ContentInserted(nsIContent* aContainer, nsIContent* aChild, PRInt32 aIndexInContainer) { NS_ABORT_IF_FALSE(aChild, "Null child!");  PRInt32 i;    for (i = 0; i < mObservers.Count(); i++) { nsIDocumentObserver *observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(i));  observer->ContentInserted(this, aContainer, aChild, aIndexInContainer);   if (i < mObservers.Count() && observer != (nsIDocumentObserver*)mObservers[i]) { i--; } } }  void nsDocument::ContentRemoved(nsIContent* aContainer, nsIContent* aChild, PRInt32 aIndexInContainer) { NS_ABORT_IF_FALSE(aChild, "Null child!");  PRInt32 i;    for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; observer->ContentRemoved(this, aContainer, aChild, aIndexInContainer); } }  void nsDocument::AttributeWillChange(nsIContent* aChild, PRInt32 aNameSpaceID, nsIAtom* aAttribute) { NS_ASSERTION(aChild, "Null child!"); }  void nsDocument::AttributeChanged(nsIContent* aChild, PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRInt32 aModType) { NS_ABORT_IF_FALSE(aChild, "Null child!");  PRInt32 i; for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver *observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(i));  observer->AttributeChanged(this, aChild, aNameSpaceID, aAttribute, aModType); } }   void nsDocument::StyleRuleChanged(nsIStyleSheet* aStyleSheet, nsIStyleRule* aOldStyleRule, nsIStyleRule* aNewStyleRule) { PRInt32 i;   for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver *observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(i));  observer->StyleRuleChanged(this, aStyleSheet, aOldStyleRule, aNewStyleRule); } }  void nsDocument::StyleRuleAdded(nsIStyleSheet* aStyleSheet, nsIStyleRule* aStyleRule) { PRInt32 i;   for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver *observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(i));  observer->StyleRuleAdded(this, aStyleSheet, aStyleRule); } }  void nsDocument::StyleRuleRemoved(nsIStyleSheet* aStyleSheet, nsIStyleRule* aStyleRule) { PRInt32 i;   for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver *observer = NS_STATIC_CAST(nsIDocumentObserver *, mObservers.ElementAt(i));  observer->StyleRuleRemoved(this, aStyleSheet, aStyleRule); } }      NS_IMETHODIMP nsDocument::GetDoctype(nsIDOMDocumentType** aDoctype) { NS_ENSURE_ARG_POINTER(aDoctype);  *aDoctype = nsnull; PRInt32 i, count; count = mChildren.Count(); nsCOMPtr<nsIDOMNode> rootContentNode(do_QueryInterface(mRootContent) ); nsCOMPtr<nsIDOMNode> node;  for (i = 0; i < count; i++) { node = do_QueryInterface(mChildren[i]);  NS_ASSERTION(node, "null element of mChildren");     if (node == rootContentNode) return NS_OK;  if (node) { PRUint16 nodeType;  node->GetNodeType(&nodeType);  if (nodeType == nsIDOMNode::DOCUMENT_TYPE_NODE) { return CallQueryInterface(node, aDoctype); } } }  return NS_OK; }  NS_IMETHODIMP nsDocument::GetImplementation(nsIDOMDOMImplementation** aImplementation) {   *aImplementation = new nsDOMImplementation(mDocumentURI); if (!*aImplementation) { return NS_ERROR_OUT_OF_MEMORY; }  NS_ADDREF(*aImplementation);  return NS_OK; }  NS_IMETHODIMP nsDocument::GetDocumentElement(nsIDOMElement** aDocumentElement) { NS_ENSURE_ARG_POINTER(aDocumentElement);  nsresult rv = NS_OK;  if (mRootContent) { rv = CallQueryInterface(mRootContent, aDocumentElement); NS_ASSERTION(NS_OK == rv, "Must be a DOM Element"); } else { *aDocumentElement = nsnull; }  return rv; }  NS_IMETHODIMP nsDocument::CreateElement(const nsAString& aTagName, nsIDOMElement** aReturn) { *aReturn = nsnull;  nsresult rv = nsContentUtils::CheckQName(aTagName, PR_FALSE); NS_ENSURE_SUCCESS(rv, rv);  NS_ASSERTION(IsCaseSensitive(), "nsDocument::CreateElement() called on document that is not " "case sensitive. Fix caller, or fix " "nsDocument::CreateElement()!");  nsCOMPtr<nsIAtom> name = do_GetAtom(aTagName);  nsCOMPtr<nsIContent> content; rv = CreateElem(name, nsnull, GetDefaultNamespaceID(), PR_TRUE, getter_AddRefs(content)); NS_ENSURE_SUCCESS(rv, rv);  return CallQueryInterface(content, aReturn); }  NS_IMETHODIMP nsDocument::CreateElementNS(const nsAString& aNamespaceURI, const nsAString& aQualifiedName, nsIDOMElement** aReturn) { *aReturn = nsnull;  nsCOMPtr<nsINodeInfo> nodeInfo; nsresult rv = nsContentUtils::GetNodeInfoFromQName(aNamespaceURI, aQualifiedName, mNodeInfoManager, getter_AddRefs(nodeInfo)); NS_ENSURE_SUCCESS(rv, rv);  nsCOMPtr<nsIContent> content; rv = CreateElement(nodeInfo, nodeInfo->NamespaceID(), getter_AddRefs(content)); NS_ENSURE_SUCCESS(rv, rv);  return CallQueryInterface(content, aReturn); }  NS_IMETHODIMP nsDocument::CreateTextNode(const nsAString& aData, nsIDOMText** aReturn) { *aReturn = nsnull;  nsCOMPtr<nsITextContent> text; nsresult rv = NS_NewTextNode(getter_AddRefs(text), this);  if (NS_SUCCEEDED(rv)) { rv = CallQueryInterface(text, aReturn); (*aReturn)->AppendData(aData); }  return rv; }  NS_IMETHODIMP nsDocument::CreateDocumentFragment(nsIDOMDocumentFragment** aReturn) { return NS_NewDocumentFragment(aReturn, this); }  NS_IMETHODIMP nsDocument::CreateComment(const nsAString& aData, nsIDOMComment** aReturn) { *aReturn = nsnull;  nsCOMPtr<nsIContent> comment; nsresult rv = NS_NewCommentNode(getter_AddRefs(comment), this);  if (NS_SUCCEEDED(rv)) { rv = CallQueryInterface(comment, aReturn); (*aReturn)->AppendData(aData); }  return rv; }  NS_IMETHODIMP nsDocument::CreateCDATASection(const nsAString& aData, nsIDOMCDATASection** aReturn) { NS_ENSURE_ARG_POINTER(aReturn); *aReturn = nsnull;  nsReadingIterator<PRUnichar> begin; nsReadingIterator<PRUnichar> end; aData.BeginReading(begin); aData.EndReading(end); if (FindInReadable(NS_LITERAL_STRING("]]>"),begin,end)) return NS_ERROR_DOM_INVALID_CHARACTER_ERR;  nsCOMPtr<nsIContent> content; nsresult rv = NS_NewXMLCDATASection(getter_AddRefs(content), this);  if (NS_SUCCEEDED(rv)) { rv = CallQueryInterface(content, aReturn); (*aReturn)->AppendData(aData); }  return rv; }  NS_IMETHODIMP nsDocument::CreateProcessingInstruction(const nsAString& aTarget, const nsAString& aData, nsIDOMProcessingInstruction** aReturn) { *aReturn = nsnull;  nsresult rv = nsContentUtils::CheckQName(aTarget, PR_FALSE); NS_ENSURE_SUCCESS(rv, rv);  nsCOMPtr<nsIContent> content; rv = NS_NewXMLProcessingInstruction(getter_AddRefs(content), aTarget, aData, this); if (NS_FAILED(rv)) { return rv; }  return CallQueryInterface(content, aReturn); }  NS_IMETHODIMP nsDocument::CreateAttribute(const nsAString& aName, nsIDOMAttr** aReturn) { *aReturn = nsnull; NS_ENSURE_TRUE(mNodeInfoManager, NS_ERROR_NOT_INITIALIZED);  nsresult rv = nsContentUtils::CheckQName(aName, PR_FALSE); NS_ENSURE_SUCCESS(rv, rv);  nsAutoString value; nsDOMAttribute* attribute;  nsCOMPtr<nsINodeInfo> nodeInfo; rv = mNodeInfoManager->GetNodeInfo(aName, nsnull, kNameSpaceID_None, getter_AddRefs(nodeInfo)); NS_ENSURE_SUCCESS(rv, rv);  attribute = new nsDOMAttribute(nsnull, nodeInfo, value); NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY);  return CallQueryInterface(attribute, aReturn); }  NS_IMETHODIMP nsDocument::CreateAttributeNS(const nsAString & aNamespaceURI, const nsAString & aQualifiedName, nsIDOMAttr **aResult) { NS_ENSURE_ARG_POINTER(aResult); *aResult = nsnull;  nsCOMPtr<nsINodeInfo> nodeInfo; nsresult rv = nsContentUtils::GetNodeInfoFromQName(aNamespaceURI, aQualifiedName, mNodeInfoManager, getter_AddRefs(nodeInfo)); NS_ENSURE_SUCCESS(rv, rv);  nsAutoString value; nsDOMAttribute* attribute = new nsDOMAttribute(nsnull, nodeInfo, value); NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY);  return CallQueryInterface(attribute, aResult); }  NS_IMETHODIMP nsDocument::CreateEntityReference(const nsAString& aName, nsIDOMEntityReference** aReturn) { NS_ENSURE_ARG_POINTER(aReturn);  *aReturn = nsnull; return NS_OK; }  NS_IMETHODIMP nsDocument::GetElementsByTagName(const nsAString& aTagname, nsIDOMNodeList** aReturn) { nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aTagname); NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);  nsCOMPtr<nsIContentList> list; NS_GetContentList(this, nameAtom, kNameSpaceID_Unknown, nsnull, getter_AddRefs(list)); NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);  return CallQueryInterface(list, aReturn); }  NS_IMETHODIMP nsDocument::GetElementsByTagNameNS(const nsAString& aNamespaceURI, const nsAString& aLocalName, nsIDOMNodeList** aReturn) { PRInt32 nameSpaceId = kNameSpaceID_Unknown;  nsCOMPtr<nsIContentList> list;  if (!aNamespaceURI.EqualsLiteral("*")) { nsContentUtils::GetNSManagerWeakRef()->GetNameSpaceID(aNamespaceURI, &nameSpaceId);  if (nameSpaceId == kNameSpaceID_Unknown) {  NS_GetContentList(this, nsnull, kNameSpaceID_None, nsnull, getter_AddRefs(list)); NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY); } }  if (!list) { nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aLocalName); NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);  NS_GetContentList(this, nameAtom, nameSpaceId, nsnull, getter_AddRefs(list)); NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY); }  return CallQueryInterface(list, aReturn); }  NS_IMETHODIMP nsDocument::GetElementById(const nsAString & elementId, nsIDOMElement **_retval) {  return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsDocument::GetAsync(PRBool *aAsync) { NS_ERROR("nsDocument::GetAsync() should be overriden by subclass!");  return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsDocument::SetAsync(PRBool aAsync) { NS_ERROR("nsDocument::SetAsync() should be overriden by subclass!");  return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsDocument::Load(const nsAString& aUrl, PRBool *aReturn) { NS_ERROR("nsDocument::Load() should be overriden by subclass!");  return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsDocument::EvaluateFIXptr(const nsAString& aExpression, nsIDOMRange **aRange) { NS_ERROR("nsDocument::EvaluateFIXptr() should be overriden by subclass!");  return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsDocument::EvaluateXPointer(const nsAString& aExpression, nsIXPointerResult **aResult) { NS_ERROR("nsDocument::EvaluateXPointer() should be overriden by subclass!");  return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsDocument::GetStyleSheets(nsIDOMStyleSheetList** aStyleSheets) { if (!mDOMStyleSheets) { mDOMStyleSheets = new nsDOMStyleSheetList(this); if (!mDOMStyleSheets) { return NS_ERROR_OUT_OF_MEMORY; } }  *aStyleSheets = mDOMStyleSheets; NS_ADDREF(*aStyleSheets);  return NS_OK; }  NS_IMETHODIMP nsDocument::GetPreferredStylesheetSet(nsAString& aStyleTitle) { if (mCSSLoader) { mCSSLoader->GetPreferredSheet(aStyleTitle); } else { aStyleTitle.Truncate(); } return NS_OK; }  NS_IMETHODIMP nsDocument::GetCharacterSet(nsAString& aCharacterSet) { CopyASCIItoUCS2(GetDocumentCharacterSet(), aCharacterSet); return NS_OK; }  NS_IMETHODIMP nsDocument::ImportNode(nsIDOMNode* aImportedNode, PRBool aDeep, nsIDOMNode** aReturn) { NS_ENSURE_ARG(aImportedNode); NS_PRECONDITION(aReturn, "Null out param!");  nsresult rv = nsContentUtils::CheckSameOrigin(this, aImportedNode); if (NS_FAILED(rv)) { return rv; }  return aImportedNode->CloneNode(aDeep, aReturn); }  NS_IMETHODIMP nsDocument::AddBinding(nsIDOMElement* aContent, const nsAString& aURI) { NS_ENSURE_ARG(aContent);  nsresult rv = nsContentUtils::CheckSameOrigin(this, aContent); if (NS_FAILED(rv)) { return rv; }  nsCOMPtr<nsIContent> content(do_QueryInterface(aContent));  nsCOMPtr<nsIURI> uri; NS_NewURI(getter_AddRefs(uri), aURI); return mBindingManager->AddLayeredBinding(content, uri); }  NS_IMETHODIMP nsDocument::RemoveBinding(nsIDOMElement* aContent, const nsAString& aURI) { NS_ENSURE_ARG(aContent);  nsresult rv = nsContentUtils::CheckSameOrigin(this, aContent); if (NS_FAILED(rv)) { return rv; }  if (mBindingManager) { nsCOMPtr<nsIContent> content(do_QueryInterface(aContent)); nsCOMPtr<nsIURI> uri; rv = NS_NewURI(getter_AddRefs(uri), aURI); if (NS_FAILED(rv)) { return rv; } return mBindingManager->RemoveLayeredBinding(content, uri); }  return NS_ERROR_FAILURE; }  NS_IMETHODIMP nsDocument::LoadBindingDocument(const nsAString& aURI, nsIDOMDocument** aResult) { if (!mBindingManager) { return NS_ERROR_FAILURE; }  nsCOMPtr<nsIURI> uri; nsresult rv = NS_NewURI(getter_AddRefs(uri), aURI, mCharacterSet.get(), NS_STATIC_CAST(nsIDocument *, this)->GetBaseURI());  NS_ENSURE_SUCCESS(rv, rv);  nsCOMPtr<nsIDocument> doc; mBindingManager->LoadBindingDocument(this, uri, getter_AddRefs(doc));  if (doc) { CallQueryInterface(doc, aResult); }  return NS_OK; }  NS_IMETHODIMP nsDocument::GetBindingParent(nsIDOMNode* aNode, nsIDOMElement** aResult) { *aResult = nsnull; nsCOMPtr<nsIContent> content(do_QueryInterface(aNode)); if (!content) return NS_ERROR_FAILURE;  nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(content->GetBindingParent())); NS_IF_ADDREF(*aResult = elt); return NS_OK; }  static nsresult GetElementByAttribute(nsIContent* aContent, nsIAtom* aAttrName, const nsAString& aAttrValue, PRBool aUniversalMatch, nsIDOMElement** aResult) { nsAutoString value; nsresult rv = aContent->GetAttr(kNameSpaceID_None, aAttrName, value); if (rv == NS_CONTENT_ATTR_HAS_VALUE && (aUniversalMatch || value.Equals(aAttrValue))) { return CallQueryInterface(aContent, aResult); }  PRUint32 childCount = aContent->GetChildCount();  for (PRUint32 i = 0; i < childCount; ++i) { nsIContent *current = aContent->GetChildAt(i);  GetElementByAttribute(current, aAttrName, aAttrValue, aUniversalMatch, aResult);  if (*aResult) return NS_OK; }  return NS_OK; }  NS_IMETHODIMP nsDocument::GetAnonymousElementByAttribute(nsIDOMElement* aElement, const nsAString& aAttrName, const nsAString& aAttrValue, nsIDOMElement** aResult) { *aResult = nsnull;  nsCOMPtr<nsIDOMNodeList> nodeList; GetAnonymousNodes(aElement, getter_AddRefs(nodeList));  if (!nodeList) return NS_OK;  nsCOMPtr<nsIAtom> attribute = do_GetAtom(aAttrName);  PRUint32 length; nodeList->GetLength(&length);  PRBool universalMatch = aAttrValue.EqualsLiteral("*");  for (PRUint32 i = 0; i < length; ++i) { nsCOMPtr<nsIDOMNode> current; nodeList->Item(i, getter_AddRefs(current));  nsCOMPtr<nsIContent> content(do_QueryInterface(current));  GetElementByAttribute(content, attribute, aAttrValue, universalMatch, aResult); if (*aResult) return NS_OK; }  return NS_OK; }   NS_IMETHODIMP nsDocument::GetAnonymousNodes(nsIDOMElement* aElement, nsIDOMNodeList** aResult) { *aResult = nsnull; if (!mBindingManager) { return NS_OK; }  nsCOMPtr<nsIContent> content(do_QueryInterface(aElement)); return mBindingManager->GetAnonymousNodesFor(content, aResult); }  NS_IMETHODIMP nsDocument::CreateRange(nsIDOMRange** aReturn) { nsresult rv = NS_NewRange(aReturn);  if (NS_SUCCEEDED(rv)) { (*aReturn)->SetStart(this, 0); (*aReturn)->SetEnd(this, 0); }  return rv; }  NS_IMETHODIMP nsDocument::CreateNodeIterator(nsIDOMNode *aRoot, PRUint32 aWhatToShow, nsIDOMNodeFilter *aFilter, PRBool aEntityReferenceExpansion, nsIDOMNodeIterator **_retval) { return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsDocument::CreateTreeWalker(nsIDOMNode *aRoot, PRUint32 aWhatToShow, nsIDOMNodeFilter *aFilter, PRBool aEntityReferenceExpansion, nsIDOMTreeWalker **_retval) { *_retval = nsnull;  if (!aRoot) { return NS_ERROR_DOM_NOT_SUPPORTED_ERR; }  nsresult rv = nsContentUtils::CheckSameOrigin(this, aRoot); if (NS_FAILED(rv)) { return rv; }  return NS_NewTreeWalker(aRoot, aWhatToShow, aFilter, aEntityReferenceExpansion, _retval); }   NS_IMETHODIMP nsDocument::GetDefaultView(nsIDOMAbstractView** aDefaultView) { NS_ENSURE_ARG_POINTER(aDefaultView); *aDefaultView = nsnull;  NS_ENSURE_TRUE(mPresShells.Count() != 0, NS_OK); nsCOMPtr<nsIPresShell> shell = NS_STATIC_CAST(nsIPresShell *, mPresShells.ElementAt(0)); NS_ENSURE_TRUE(shell, NS_OK);  nsCOMPtr<nsPresContext> ctx; nsresult rv = shell->GetPresContext(getter_AddRefs(ctx)); NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && ctx, rv);  nsCOMPtr<nsISupports> container = ctx->GetContainer(); NS_ENSURE_TRUE(container, NS_OK);  nsCOMPtr<nsIDOMWindowInternal> window = do_GetInterface(container); NS_ENSURE_TRUE(window, NS_OK);  CallQueryInterface(window, aDefaultView);  return NS_OK; }  NS_IMETHODIMP nsDocument::GetLocation(nsIDOMLocation **_retval) { NS_ENSURE_ARG_POINTER(_retval); *_retval = nsnull;  nsCOMPtr<nsIDOMWindowInternal> w(do_QueryInterface(mScriptGlobalObject));  if (!w) { return NS_OK; }  return w->GetLocation(_retval); }  NS_IMETHODIMP nsDocument::GetTitle(nsAString& aTitle) { aTitle.Assign(mDocumentTitle);  return NS_OK; }  NS_IMETHODIMP nsDocument::SetTitle(const nsAString& aTitle) { for (PRInt32 i = mPresShells.Count() - 1; i >= 0; --i) { nsCOMPtr<nsIPresShell> shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[i]);  nsCOMPtr<nsPresContext> context; nsresult rv = shell->GetPresContext(getter_AddRefs(context)); NS_ENSURE_SUCCESS(rv, rv);  nsCOMPtr<nsISupports> container = context->GetContainer(); if (!container) continue;  nsCOMPtr<nsIBaseWindow> docShellWin = do_QueryInterface(container); if (!docShellWin) continue;  rv = docShellWin->SetTitle(PromiseFlatString(aTitle).get()); NS_ENSURE_SUCCESS(rv, rv); }  mDocumentTitle.Assign(aTitle);   nsCOMPtr<nsIDOMEvent> event; CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event)); if (event) { event->InitEvent(NS_LITERAL_STRING("DOMTitleChanged"), PR_TRUE, PR_TRUE); PRBool noDefault; DispatchEvent(event, &noDefault); }  return NS_OK; }  NS_IMETHODIMP nsDocument::GetBoxObjectFor(nsIDOMElement* aElement, nsIBoxObject** aResult) { NS_ENSURE_ARG(aElement);  nsresult rv;  *aResult = nsnull;  if (!mBoxObjectTable) { mBoxObjectTable = new nsSupportsHashtable; } else { nsISupportsKey key(aElement); nsCOMPtr<nsISupports> supports = dont_AddRef(mBoxObjectTable->Get(&key));  nsCOMPtr<nsIBoxObject> boxObject(do_QueryInterface(supports)); if (boxObject) { *aResult = boxObject; NS_ADDREF(*aResult);  return NS_OK; } }  nsIPresShell *shell = GetShellAt(0); if (!shell) return NS_ERROR_FAILURE;  PRInt32 namespaceID; nsCOMPtr<nsIAtom> tag; nsCOMPtr<nsIXBLService> xblService = do_GetService("@mozilla.org/xbl;1", &rv); nsCOMPtr<nsIContent> content(do_QueryInterface(aElement)); xblService->ResolveTag(content, &namespaceID, getter_AddRefs(tag));  nsCAutoString contractID("@mozilla.org/layout/xul-boxobject"); if (namespaceID == kNameSpaceID_XUL) { if (tag == nsXULAtoms::browser) contractID += "-browser"; else if (tag == nsXULAtoms::editor) contractID += "-editor"; else if (tag == nsXULAtoms::iframe) contractID += "-iframe"; else if (tag == nsXULAtoms::menu) contractID += "-menu"; else if (tag == nsXULAtoms::popup || tag == nsXULAtoms::menupopup || tag == nsXULAtoms::tooltip) contractID += "-popup"; else if (tag == nsXULAtoms::tree) contractID += "-tree"; else if (tag == nsXULAtoms::listbox) contractID += "-listbox"; else if (tag == nsXULAtoms::scrollbox) contractID += "-scrollbox"; } contractID += ";1";  nsCOMPtr<nsIBoxObject> boxObject(do_CreateInstance(contractID.get())); if (!boxObject) return NS_ERROR_FAILURE;  nsCOMPtr<nsPIBoxObject> privateBox(do_QueryInterface(boxObject)); rv = privateBox->Init(content, shell);  if (NS_FAILED(rv)) { return rv; }  SetBoxObjectFor(aElement, boxObject);  *aResult = boxObject; NS_ADDREF(*aResult);  return NS_OK; }  NS_IMETHODIMP nsDocument::SetBoxObjectFor(nsIDOMElement* aElement, nsIBoxObject* aBoxObject) { if (!mBoxObjectTable) { if (!aBoxObject) return NS_OK; mBoxObjectTable = new nsSupportsHashtable(12); }  nsISupportsKey key(aElement);  if (aBoxObject) { mBoxObjectTable->Put(&key, aBoxObject); } else { nsCOMPtr<nsISupports> supp; mBoxObjectTable->Remove(&key, getter_AddRefs(supp)); nsCOMPtr<nsPIBoxObject> boxObject(do_QueryInterface(supp)); if (boxObject) { boxObject->SetDocument(nsnull); } }  return NS_OK; }  struct DirTable { const char* mName; PRUint8     mValue;
NS_INTERFACE_MAP_BEGIN(nsXPathDocumentTearoff)  NS_INTERFACE_MAP_ENTRY(nsIDOMXPathEvaluator)NS_INTERFACE_MAP_END_AGGREGATED(mDocument)NS_IMPL_ADDREF_USING_AGGREGATOR(nsXPathDocumentTearoff, mDocument)NS_IMPL_RELEASE_USING_AGGREGATOR(nsXPathDocumentTearoff, mDocument)class OrphansEntry : public PLDHashEntryHdr{public:  nsIContent *mKey; // must be first, to look like PLDHashEntryStub};