Fix bug 390565. r+sr=mrbkap
git-svn-id: svn://10.0.0.236/trunk@240269 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -474,47 +474,52 @@ CNavDTD::GetType()
|
||||
return NS_IPARSER_FLAG_HTML;
|
||||
}
|
||||
|
||||
/**
|
||||
* Text and some tags require a body when they're added, this function returns
|
||||
* true for those tags.
|
||||
*
|
||||
* @param aToken The current token that we care about.
|
||||
* @param aTokenizer A tokenizer that we can get the tags attributes off of.
|
||||
* @return PR_TRUE if aToken does indeed force the body to open.
|
||||
*/
|
||||
static PRBool
|
||||
DoesRequireBody(CToken* aToken, nsITokenizer* aTokenizer)
|
||||
ValueIsHidden(const nsAString& aValue)
|
||||
{
|
||||
PRBool result = PR_FALSE;
|
||||
// Having to deal with whitespace here sucks, but we have to match
|
||||
// what the content sink does.
|
||||
nsAutoString str(aValue);
|
||||
str.Trim("\n\r\t\b");
|
||||
return str.LowerCaseEqualsLiteral("hidden");
|
||||
}
|
||||
|
||||
if (aToken) {
|
||||
eHTMLTags theTag = (eHTMLTags)aToken->GetTypeID();
|
||||
if (gHTMLElements[theTag].HasSpecialProperty(kRequiresBody)) {
|
||||
if (theTag == eHTMLTag_input) {
|
||||
// IE & Nav4x opens up a body for type=text - Bug 66985
|
||||
PRInt32 ac = aToken->GetAttributeCount();
|
||||
for(PRInt32 i = 0; i < ac; ++i) {
|
||||
CAttributeToken* attr = static_cast<CAttributeToken*>
|
||||
(aTokenizer->GetTokenAt(i));
|
||||
const nsSubstring& name = attr->GetKey();
|
||||
const nsAString& value = attr->GetValue();
|
||||
|
||||
if ((name.EqualsLiteral("type") ||
|
||||
name.EqualsLiteral("TYPE"))
|
||||
&&
|
||||
!(value.EqualsLiteral("hidden") ||
|
||||
value.EqualsLiteral("HIDDEN"))) {
|
||||
result = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result = PR_TRUE;
|
||||
}
|
||||
// Check whether aToken corresponds to a <input type="hidden"> tag. The token
|
||||
// must be a start tag token for an <input>. This must be called at a point
|
||||
// when all the attributes for the input are still in the tokenizer.
|
||||
static PRBool
|
||||
IsHiddenInput(CToken* aToken, nsITokenizer* aTokenizer)
|
||||
{
|
||||
NS_PRECONDITION(eHTMLTokenTypes(aToken->GetTokenType()) == eToken_start,
|
||||
"Must be start token");
|
||||
NS_PRECONDITION(eHTMLTags(aToken->GetTypeID()) == eHTMLTag_input,
|
||||
"Must be <input> tag");
|
||||
|
||||
PRInt32 ac = aToken->GetAttributeCount();
|
||||
NS_ASSERTION(ac <= aTokenizer->GetCount(),
|
||||
"Not enough tokens in the tokenizer");
|
||||
// But we don't really trust ourselves to get that right
|
||||
ac = PR_MIN(ac, aTokenizer->GetCount());
|
||||
|
||||
for (PRInt32 i = 0; i < ac; ++i) {
|
||||
NS_ASSERTION(eHTMLTokenTypes(aTokenizer->GetTokenAt(i)->GetTokenType()) ==
|
||||
eToken_attribute, "Unexpected token type");
|
||||
// Again, we're not sure we actually manage to guarantee that
|
||||
if (eHTMLTokenTypes(aTokenizer->GetTokenAt(i)->GetTokenType()) !=
|
||||
eToken_attribute) {
|
||||
break;
|
||||
}
|
||||
|
||||
CAttributeToken* attrToken =
|
||||
static_cast<CAttributeToken*>(aTokenizer->GetTokenAt(i));
|
||||
if (!attrToken->GetKey().LowerCaseEqualsLiteral("type")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return ValueIsHidden(attrToken->GetValue());
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -566,7 +571,6 @@ CNavDTD::HandleToken(CToken* aToken, nsIParser* aParser)
|
||||
}
|
||||
|
||||
eHTMLTags theParentTag = mBodyContext->Last();
|
||||
theTag = (eHTMLTags)theToken->GetTypeID();
|
||||
if (FindTagInSet(theTag, gLegalElements,
|
||||
NS_ARRAY_LENGTH(gLegalElements)) ||
|
||||
(gHTMLElements[theParentTag].CanContain(theTag, mDTDMode) &&
|
||||
@@ -581,7 +585,11 @@ CNavDTD::HandleToken(CToken* aToken, nsIParser* aParser)
|
||||
// noscript, etc). Script is special, though. Shipping it out
|
||||
// breaks document.write stuff. See bug 243064.
|
||||
(!gHTMLElements[theTag].HasSpecialProperty(kLegalOpen) ||
|
||||
theTag == eHTMLTag_script))) {
|
||||
theTag == eHTMLTag_script)) ||
|
||||
(theTag == eHTMLTag_input && theType == eToken_start &&
|
||||
FindTagInSet(theParentTag, gLegalElements,
|
||||
NS_ARRAY_LENGTH(gLegalElements)) &&
|
||||
IsHiddenInput(theToken, mTokenizer))) {
|
||||
// Reset the state since all the misplaced tokens are about to get
|
||||
// handled.
|
||||
mFlags &= ~NS_DTD_FLAG_MISPLACED_CONTENT;
|
||||
@@ -677,7 +685,9 @@ CNavDTD::HandleToken(CToken* aToken, nsIParser* aParser)
|
||||
// end tag.
|
||||
}
|
||||
|
||||
if (DoesRequireBody(aToken, mTokenizer)) {
|
||||
if (gHTMLElements[theTag].HasSpecialProperty(kRequiresBody) &&
|
||||
((theTag != eHTMLTag_input) ||
|
||||
!IsHiddenInput(aToken, mTokenizer))) {
|
||||
CToken* theBodyToken =
|
||||
mTokenAllocator->CreateTokenOfType(eToken_start,
|
||||
eHTMLTag_body,
|
||||
@@ -875,9 +885,33 @@ CNavDTD::HandleDefaultStartToken(CToken* aToken, eHTMLTags aChildTag,
|
||||
do {
|
||||
eHTMLTags theParentTag = mBodyContext->TagAt(--theIndex);
|
||||
|
||||
// Figure out whether this is a hidden input inside a
|
||||
// table/tbody/thead/tfoot/tr
|
||||
static eHTMLTags sTableElements[] = {
|
||||
eHTMLTag_table, eHTMLTag_thead, eHTMLTag_tbody,
|
||||
eHTMLTag_tr, eHTMLTag_tfoot
|
||||
};
|
||||
|
||||
PRBool isHiddenInputInsideTableElement = PR_FALSE;
|
||||
if (aChildTag == eHTMLTag_input &&
|
||||
FindTagInSet(theParentTag, sTableElements,
|
||||
NS_ARRAY_LENGTH(sTableElements))) {
|
||||
PRInt32 attrCount = aNode->GetAttributeCount();
|
||||
for (PRInt32 attrIndex = 0; attrIndex < attrCount; ++attrIndex) {
|
||||
const nsAString& key = aNode->GetKeyAt(attrIndex);
|
||||
if (key.LowerCaseEqualsLiteral("type")) {
|
||||
isHiddenInputInsideTableElement =
|
||||
ValueIsHidden(aNode->GetValueAt(attrIndex));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Precompute containment, and pass it to CanOmit()...
|
||||
theParentContains = CanContain(theParentTag, aChildTag);
|
||||
if (CanOmit(theParentTag, aChildTag, theParentContains)) {
|
||||
theParentContains =
|
||||
isHiddenInputInsideTableElement || CanContain(theParentTag, aChildTag);
|
||||
if (!isHiddenInputInsideTableElement &&
|
||||
CanOmit(theParentTag, aChildTag, theParentContains)) {
|
||||
HandleOmittedTag(aToken, aChildTag, theParentTag, aNode);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user