tag in the head.) To move content, we throw it onto the * misplacedcontent deque until we can deal with it. */ switch(theTag) { case eHTMLTag_html: case eHTMLTag_noframes: case eHTMLTag_script: case eHTMLTag_doctypeDecl: case eHTMLTag_instruction: break; default: if (!gHTMLElements[eHTMLTag_html].SectionContains(theTag, PR_FALSE)) { if (!(mFlags & (NS_DTD_FLAG_HAS_MAIN_CONTAINER | NS_DTD_FLAG_ALTERNATE_CONTENT))) { // For bug examples from this code, see bugs: 18928, 20989. // At this point we know the body/frameset aren't open. // If the child belongs in the head, then handle it (which may open // the head); otherwise, push it onto the misplaced stack. PRBool isExclusive = PR_FALSE; PRBool theChildBelongsInHead = gHTMLElements[eHTMLTag_head].IsChildOfHead(theTag, isExclusive); if (theChildBelongsInHead && !isExclusive && !gHTMLElements[theTag].HasSpecialProperty(kPreferHead)) { if (mMisplacedContent.GetSize() == 0 && (!gHTMLElements[theTag].HasSpecialProperty(kPreferBody) || (mFlags & NS_DTD_FLAG_HAS_EXPLICIT_HEAD))) { // This tag can either be in the body or the head. Since // there is no indication that the body should be open, // put this token in the head. break; } // Otherwise, we have received some indication that the body is // "open", so push this token onto the misplaced content stack. theChildBelongsInHead = PR_FALSE; } if (!theChildBelongsInHead) { eHTMLTags top = mBodyContext->Last(); NS_ASSERTION(top != eHTMLTag_userdefined, "Userdefined tags should act as leaves in the head"); if (top != eHTMLTag_html && top != eHTMLTag_head && gHTMLElements[top].CanContain(theTag, mDTDMode)) { // Some tags (such as
There PRInt32 theParentContains = -1; if (!CanOmit(theParentTag, theChildTag, theParentContains)) { CToken* theStartToken = mTokenAllocator->CreateTokenOfType(eToken_start, theChildTag); NS_ENSURE_TRUE(theStartToken, NS_ERROR_OUT_OF_MEMORY); // This check for NS_DTD_FLAG_IN_MISPLACED_CONTENT was added // to fix bug 142965. if (!(mFlags & NS_DTD_FLAG_IN_MISPLACED_CONTENT)) { // We're not handling misplaced content right now, just push // these new tokens back on the stack and handle them in the // regular flow of HandleToken. IF_HOLD(aToken); mTokenizer->PushTokenFront(aToken); mTokenizer->PushTokenFront(theStartToken); } else { // Oops, we're in misplaced content. Handle these tokens // directly instead of trying to push them onto the tokenizer // stack. result = HandleToken(theStartToken); NS_ENSURE_SUCCESS(result, result); IF_HOLD(aToken); result = HandleToken(aToken); } } } return result; } if (result == NS_OK) { eHTMLTags theTarget = FindAutoCloseTargetForEndTag(theChildTag, *mBodyContext, mDTDMode); if (eHTMLTag_unknown != theTarget) { result = CloseContainersTo(theTarget, PR_FALSE); } } } } break; } return result; } /** * This method will be triggered when the end of a table is * encountered. Its primary purpose is to process all the * bad-contents pertaining a particular table. The position * of the table is the token bank ID. * * @update harishd 03/24/99 * @param aTag - This ought to be a table tag * */ nsresult CNavDTD::HandleSavedTokens(PRInt32 anIndex) { NS_PRECONDITION(mBodyContext != nsnull && mBodyContext->GetCount() > 0, "invalid context"); nsresult result = NS_OK; if (mSink && (anIndex > kNotFound)) { PRInt32 theBadTokenCount = mMisplacedContent.GetSize(); if (theBadTokenCount > 0) { mFlags |= NS_DTD_FLAG_IN_MISPLACED_CONTENT; if (!mTempContext && !(mTempContext = new nsDTDContext())) { return NS_ERROR_OUT_OF_MEMORY; } CToken* theToken; eHTMLTags theTag; PRInt32 attrCount; PRInt32 theTopIndex = anIndex + 1; PRInt32 theTagCount = mBodyContext->GetCount(); PRBool formWasOnStack = mSink->IsFormOnStack(); if (formWasOnStack) { // Do this to synchronize dtd stack and the sink stack. // Note: FORM is never on the dtd stack because its always // considered as a leaf. However, in the sink FORM can either // be a container or a leaf. Therefore, we have to check // with the sink -- Ref: Bug 20087. ++anIndex; } // Pause the main context and switch to the new context. result = mSink->BeginContext(anIndex); NS_ENSURE_SUCCESS(result, result); // The body context should contain contents only upto the marked position. mBodyContext->MoveEntries(*mTempContext, theTagCount - theTopIndex); // Now flush out all the bad contents. while (theBadTokenCount-- > 0){ theToken = (CToken*)mMisplacedContent.PopFront(); if (theToken) { theTag = (eHTMLTags)theToken->GetTypeID(); attrCount = theToken->GetAttributeCount(); // Put back attributes, which once got popped out, into the // tokenizer. Make sure we preserve their ordering, however! // XXXbz would it be faster to get the tokens out with ObjectAt and // put them in the tokenizer and then PopFront them all from // mMisplacedContent? nsDeque temp; for (PRInt32 j = 0; j < attrCount; ++j) { CToken* theAttrToken = (CToken*)mMisplacedContent.PopFront(); if (theAttrToken) { temp.Push(theAttrToken); } theBadTokenCount--; } mTokenizer->PrependTokens(temp); if (eToken_end == theToken->GetTokenType()) { // Ref: Bug 25202 // Make sure that the BeginContext() is ended only by the call to // EndContext(). Ex: