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;
|
||||
}
|
||||
|
||||
@@ -873,7 +873,7 @@ nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,
|
||||
// If you're here, it's because we were in the midst of consuming a start
|
||||
// tag but ran out of data (not in the stream, but in this *part* of the
|
||||
// stream. For simplicity, we have to unwind our input. Therefore, we pop
|
||||
// and discard any new tokens we've cued this round. Later we can get
|
||||
// and discard any new tokens we've queued this round. Later we can get
|
||||
// smarter about this.
|
||||
if (NS_FAILED(result)) {
|
||||
while (mTokenDeque.GetSize()>theDequeSize) {
|
||||
|
||||
@@ -74,3 +74,310 @@ Expected closing tag after </.
|
||||
| <style>
|
||||
| "
|
||||
x { content:"</style" } "
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><tr><td></td><input><td></td></tr></table></body>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <input>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><tr><td></td><input type="hidden"><td></td></tr></table></body>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <input>
|
||||
| type="hidden"
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><tr><td></td><input tYPe=" hiDDen "><td></td></tr></table></body>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <input>
|
||||
| type="hidden"
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><tr><td></td><input tYPe=" hiDDen "><td></td></tr></table></body>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <input>
|
||||
| type=" hiDDen "
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><tr><td></td><input type="text" type="hidden"><td></td></tr></table></body>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <input>
|
||||
| type="text"
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><tr><td></td><input type="hidden" type="text"><td></td></tr></table></body>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <input>
|
||||
| type="hidden"
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><tr><td></td><input id="one"><input type="hidden"><input id="two"><td></td></tr></table></body>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <input>
|
||||
| id="one"
|
||||
| <input>
|
||||
| id="two"
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <input>
|
||||
| type="hidden"
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><tr><td></td><input id="one" type="hidden"><input id="two"><input id="three" type="hidden"><td></td></tr></table></body>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <input>
|
||||
| id="two"
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <input>
|
||||
| type="hidden"
|
||||
| id="one"
|
||||
| <input>
|
||||
| type="hidden"
|
||||
| id="three"
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><input><tr><td></td><td></td></tr></table></body>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <input>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><input type="hidden"><tr><td></td><td></td></tr></table></body>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <input>
|
||||
| type="hidden"
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><tbody><input><tr><td></td><td></td></tr></tbody></table></body>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <input>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><tbody><input type="hidden"><tr><td></td><td></td></tr></tbody></table></body>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <input>
|
||||
| type="hidden"
|
||||
| <tr>
|
||||
| <td>
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><thead><input><tr><td></td><td></td></tr></thead></table></body>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <input>
|
||||
| <table>
|
||||
| <thead>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><thead><input type="hidden"><tr><td></td><td></td></tr></thead></table></body>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <thead>
|
||||
| <input>
|
||||
| type="hidden"
|
||||
| <tr>
|
||||
| <td>
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><tfoot><input><tr><td></td><td></td></tr></tfoot></table></body>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <input>
|
||||
| <table>
|
||||
| <tfoot>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><tfoot><input type="hidden"><tr><td></td><td></td></tr></tfoot></table></body>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tfoot>
|
||||
| <input>
|
||||
| type="hidden"
|
||||
| <tr>
|
||||
| <td>
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><html><head></head><form><input></form><frameset rows="*"><frame></frameset></html>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <form>
|
||||
| <input>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><html><head></head><form><input type="hidden"></form><frameset rows="*"><frame></frameset></html>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <frameset>
|
||||
| rows="*"
|
||||
| <frame>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><html><head></head><form><input tYpE=" HIdDen "></form><frameset rows="*"><frame></frameset></html>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <frameset>
|
||||
| rows="*"
|
||||
| <frame>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><html><head></head><form><input type=" hidden"></form><frameset rows="*"><frame></frameset></html>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE HTML>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <form>
|
||||
| <input>
|
||||
| type=" hidden"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user