From ebf772c85a934a5c54bf6624adaeecdb641a8bb3 Mon Sep 17 00:00:00 2001 From: Laurent Jouanneau Date: Tue, 23 Mar 2010 21:55:39 +0100 Subject: [PATCH] Bug 541937 - XMLSerializer should serialize content of link tags. r=Olli.Pettay sr=bzbarsky --- content/base/src/nsXHTMLContentSerializer.cpp | 69 ++++++++--- content/base/src/nsXHTMLContentSerializer.h | 1 + content/base/test/Makefile.in | 3 + content/base/test/file_bug541937.html | 8 ++ content/base/test/file_bug541937.xhtml | 12 ++ content/base/test/test_bug541937.html | 115 ++++++++++++++++++ 6 files changed, 188 insertions(+), 20 deletions(-) create mode 100644 content/base/test/file_bug541937.html create mode 100644 content/base/test/file_bug541937.xhtml create mode 100644 content/base/test/test_bug541937.html diff --git a/content/base/src/nsXHTMLContentSerializer.cpp b/content/base/src/nsXHTMLContentSerializer.cpp index 7656d04483d..83001e129e1 100644 --- a/content/base/src/nsXHTMLContentSerializer.cpp +++ b/content/base/src/nsXHTMLContentSerializer.cpp @@ -461,18 +461,26 @@ nsXHTMLContentSerializer::AppendEndOfElementStart(nsIDOMElement *aOriginalElemen return; } - nsIParserService* parserService = nsContentUtils::GetParserService(); + nsCOMPtr content = do_QueryInterface(aOriginalElement); - if (parserService) { - PRBool isContainer; - parserService->IsContainer(parserService->HTMLAtomTagToId(aName), - isContainer); - if (!isContainer) { - // for backward compatibility with HTML 4 user agents - // only non-container HTML elements can be closed immediatly, - // and a space is added before /> - AppendToString(NS_LITERAL_STRING(" />"), aStr); - return; + // for non empty elements, even if they are not a container, we always + // serialize their content, because the XHTML element could contain non XHTML + // nodes useful in some context, like in an XSLT stylesheet + if (HasNoChildren(content)) { + + nsIParserService* parserService = nsContentUtils::GetParserService(); + + if (parserService) { + PRBool isContainer; + parserService->IsContainer(parserService->HTMLAtomTagToId(aName), + isContainer); + if (!isContainer) { + // for backward compatibility with HTML 4 user agents + // only non-container HTML elements can be closed immediatly, + // and a space is added before /> + AppendToString(NS_LITERAL_STRING(" />"), aStr); + return; + } } } AppendToString(kGreaterThan, aStr); @@ -605,17 +613,19 @@ nsXHTMLContentSerializer::CheckElementEnd(nsIContent * aContent, } } - nsIParserService* parserService = nsContentUtils::GetParserService(); + if (HasNoChildren(aContent)) { + nsIParserService* parserService = nsContentUtils::GetParserService(); - if (parserService) { - PRBool isContainer; + if (parserService) { + PRBool isContainer; - parserService->IsContainer(parserService->HTMLAtomTagToId(name), - isContainer); - if (!isContainer) { - // non-container HTML elements are already closed, - // see AppendEndOfElementStart - return PR_FALSE; + parserService->IsContainer(parserService->HTMLAtomTagToId(name), + isContainer); + if (!isContainer) { + // non-container HTML elements are already closed, + // see AppendEndOfElementStart + return PR_FALSE; + } } } // for backward compatibility with old HTML user agents, @@ -1066,3 +1076,22 @@ nsXHTMLContentSerializer::IsFirstChildOfOL(nsIDOMElement* aElement) else return PR_FALSE; } + +PRBool +nsXHTMLContentSerializer::HasNoChildren(nsIContent * aContent) { + + PRUint32 i, childCount = aContent->GetChildCount(); + + for (i = 0; i < childCount; ++i) { + + nsIContent* child = aContent->GetChildAt(i); + + if (!child->IsNodeOfType(nsINode::eTEXT)) + return PR_FALSE; + + if (child->TextLength()) + return PR_FALSE; + } + + return PR_TRUE; +} diff --git a/content/base/src/nsXHTMLContentSerializer.h b/content/base/src/nsXHTMLContentSerializer.h index 8088f384804..8e745b2e857 100644 --- a/content/base/src/nsXHTMLContentSerializer.h +++ b/content/base/src/nsXHTMLContentSerializer.h @@ -200,6 +200,7 @@ class nsXHTMLContentSerializer : public nsXMLContentSerializer { // Stack to store one olState struct per
    . nsAutoTArray mOLStateStack; + PRBool HasNoChildren(nsIContent* aContent); }; nsresult diff --git a/content/base/test/Makefile.in b/content/base/test/Makefile.in index 7fe61e1e0cc..22076cc1611 100644 --- a/content/base/test/Makefile.in +++ b/content/base/test/Makefile.in @@ -362,6 +362,9 @@ _TEST_FILES = test_bug5141.html \ test_bug545644.html \ test_bug545644.xhtml \ test_bug553896.xhtml \ + test_bug541937.html \ + file_bug541937.html \ + file_bug541937.xhtml \ $(NULL) # This test fails on the Mac for some reason diff --git a/content/base/test/file_bug541937.html b/content/base/test/file_bug541937.html new file mode 100644 index 00000000000..af45fb65f13 --- /dev/null +++ b/content/base/test/file_bug541937.html @@ -0,0 +1,8 @@ + + Test + foo + + +

    Hello world

    + + \ No newline at end of file diff --git a/content/base/test/file_bug541937.xhtml b/content/base/test/file_bug541937.xhtml new file mode 100644 index 00000000000..f4e5f3d320b --- /dev/null +++ b/content/base/test/file_bug541937.xhtml @@ -0,0 +1,12 @@ + + + + + Test + foo + + + +

    Hello world

    + + \ No newline at end of file diff --git a/content/base/test/test_bug541937.html b/content/base/test/test_bug541937.html new file mode 100644 index 00000000000..b1efac3eed8 --- /dev/null +++ b/content/base/test/test_bug541937.html @@ -0,0 +1,115 @@ + + + + + Test for XHTML serializer, bug 541937 + + + + + +Mozilla Bug +

    + + +
    +
    +
    + + + +