summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjnd@chromium.org <jnd@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-11 17:02:33 +0000
committerjnd@chromium.org <jnd@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-11 17:02:33 +0000
commitb83f95b49b0137d3a2014b7bb8c0c29dcb590c1a (patch)
treec85146aeb9d9807df1ca29fdf7960b420da3a259
parent581e0d06dc3599bec309d34203b6b5693446fe7f (diff)
downloadchromium_src-b83f95b49b0137d3a2014b7bb8c0c29dcb590c1a.zip
chromium_src-b83f95b49b0137d3a2014b7bb8c0c29dcb590c1a.tar.gz
chromium_src-b83f95b49b0137d3a2014b7bb8c0c29dcb590c1a.tar.bz2
Fix bug about webpage with an empty HEAD tag is incorrectly saved.
BUG=11616 Review URL: http://codereview.chromium.org/112013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15761 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--webkit/glue/dom_serializer.cc14
-rw-r--r--webkit/glue/dom_serializer.h6
-rw-r--r--webkit/glue/dom_serializer_unittest.cc61
3 files changed, 77 insertions, 4 deletions
diff --git a/webkit/glue/dom_serializer.cc b/webkit/glue/dom_serializer.cc
index 36dfd53..dedf92b 100644
--- a/webkit/glue/dom_serializer.cc
+++ b/webkit/glue/dom_serializer.cc
@@ -250,6 +250,7 @@ WebCore::String DomSerializer::PostActionAfterSerializeOpenTag(
const WebCore::Element* element, SerializeDomParam* param) {
WebCore::String result;
+ param->has_added_contents_before_end = false;
if (!param->is_html_document)
return result;
// Check after processing the open tag of HEAD element
@@ -268,6 +269,7 @@ WebCore::String DomSerializer::PostActionAfterSerializeOpenTag(
ASCIIToWide(param->text_encoding.name()).c_str());
result += StdWStringToString(str_meta);
+ param->has_added_contents_before_end = true;
// Will search each META which has charset declaration, and skip them all
// in PreActionBeforeSerializeOpenTag.
} else if (element->hasTagName(WebCore::HTMLNames::scriptTag) ||
@@ -399,11 +401,15 @@ void DomSerializer::OpenTagToString(const WebCore::Element* element,
result += "\"";
}
}
+
+ // Do post action for open tag.
+ WebCore::String added_contents =
+ PostActionAfterSerializeOpenTag(element, param);
// Complete the open tag for element when it has child/children.
- if (element->hasChildNodes())
+ if (element->hasChildNodes() || param->has_added_contents_before_end)
result += ">";
- // Do post action for open tag.
- result += PostActionAfterSerializeOpenTag(element, param);
+ // Append the added contents generate in post action of open tag.
+ result += added_contents;
// Save the result to data buffer.
SaveHtmlContentToBuffer(result, param);
}
@@ -419,7 +425,7 @@ void DomSerializer::EndTagToString(const WebCore::Element* element,
if (need_skip)
return;
// Write end tag when element has child/children.
- if (element->hasChildNodes()) {
+ if (element->hasChildNodes() || param->has_added_contents_before_end) {
result += "</";
result += element->nodeName();
result += ">";
diff --git a/webkit/glue/dom_serializer.h b/webkit/glue/dom_serializer.h
index a69082f..62b6702 100644
--- a/webkit/glue/dom_serializer.h
+++ b/webkit/glue/dom_serializer.h
@@ -113,6 +113,12 @@ class DomSerializer {
// Flag indicates whether we have written xml document declaration.
// It is only used in xml document
bool has_doc_declaration;
+ // Flag indicates whether we have added additional contents before end tag.
+ // This flag will be re-assigned in each call of function
+ // PostActionAfterSerializeOpenTag and it could be changed in function
+ // PreActionBeforeSerializeEndTag if the function adds new contents into
+ // serialization stream.
+ bool has_added_contents_before_end;
// Constructor.
SerializeDomParam(
diff --git a/webkit/glue/dom_serializer_unittest.cc b/webkit/glue/dom_serializer_unittest.cc
index 39b5e31..76a576e 100644
--- a/webkit/glue/dom_serializer_unittest.cc
+++ b/webkit/glue/dom_serializer_unittest.cc
@@ -721,4 +721,65 @@ TEST_F(DomSerializerTests, SerialzeHTMLDOMWithBaseTag) {
ASSERT_EQ(new_base_url, path_dir_url);
}
+// Serializing page which has an empty HEAD tag.
+TEST_F(DomSerializerTests, SerialzeHTMLDOMWithEmptyHead) {
+ FilePath page_file_path = data_dir_;
+ page_file_path = page_file_path.AppendASCII("dom_serializer");
+ page_file_path = page_file_path.AppendASCII("empty_head.htm");
+ GURL file_url = net::FilePathToFileURL(page_file_path);
+ ASSERT_TRUE(file_url.SchemeIsFile());
+
+ // Load the test html content.
+ static const char* const empty_head_contents =
+ "<HTML><HEAD></HEAD><BODY>hello world</BODY></HTML>";
+ LoadContents(empty_head_contents, file_url, "");
+
+ // Make sure the head tag is empty.
+ WebFrameImpl* web_frame =
+ static_cast<WebFrameImpl*>(test_shell_->webView()->GetMainFrame());
+ ASSERT_TRUE(web_frame != NULL);
+ WebCore::Document* doc = web_frame->frame()->document();
+ ASSERT_TRUE(doc->isHTMLDocument());
+ WebCore::HTMLHeadElement* head_ele = doc->head();
+ ASSERT_TRUE(head_ele != NULL);
+ WTF::PassRefPtr<WebCore::HTMLCollection> children = head_ele->children();
+ ASSERT_TRUE(0 == children->length());
+
+ // Do serialization.
+ SerializeDomForURL(file_url, false);
+ // Make sure the serialized contents have META ;
+ ASSERT_TRUE(HasSerializedFrame(file_url));
+ const std::string& serialized_contents =
+ GetSerializedContentForFrame(file_url);
+
+ // Reload serialized contents and make sure there is only one META tag.
+ LoadContents(serialized_contents, file_url,
+ web_frame->frame()->loader()->encoding());
+ web_frame =
+ static_cast<WebFrameImpl*>(test_shell_->webView()->GetMainFrame());
+ ASSERT_TRUE(web_frame != NULL);
+ doc = web_frame->frame()->document();
+ ASSERT_TRUE(doc->isHTMLDocument());
+ head_ele = doc->head();
+ ASSERT_TRUE(head_ele != NULL);
+ children = head_ele->children();
+ ASSERT_TRUE(1 == children->length());
+ WebCore::Node* meta_node = head_ele->firstChild();
+ ASSERT_TRUE(meta_node != NULL);
+ // Get meta charset info.
+ WebCore::String charset_info;
+ ASSERT_TRUE(IsMetaElement(meta_node, &charset_info));
+ ASSERT_TRUE(!charset_info.isEmpty());
+ ASSERT_TRUE(charset_info == web_frame->frame()->loader()->encoding());
+
+ // Check the body's first node is text node and its contents are
+ // "hello world"
+ WebCore::HTMLElement* body_ele = doc->body();
+ ASSERT_TRUE(body_ele != NULL);
+ WebCore::Node* text_node = body_ele->firstChild();
+ ASSERT_TRUE(text_node->isTextNode());
+ const WebCore::String& text_node_contents = text_node->nodeValue();
+ ASSERT_TRUE(text_node_contents == WebCore::String("hello world"));
+}
+
} // namespace