Index: third_party/WebKit/Source/web/WebPageSerializer.cpp |
diff --git a/third_party/WebKit/Source/web/WebPageSerializer.cpp b/third_party/WebKit/Source/web/WebPageSerializer.cpp |
index c6954126ab227b4c3426e95364bc56011dc3c294..2629b11fb187739814af34109ebe6b9ddbcb0b47 100644 |
--- a/third_party/WebKit/Source/web/WebPageSerializer.cpp |
+++ b/third_party/WebKit/Source/web/WebPageSerializer.cpp |
@@ -45,6 +45,7 @@ |
#include "core/page/PageSerializer.h" |
#include "platform/SerializedResource.h" |
#include "platform/mhtml/MHTMLArchive.h" |
+#include "platform/mhtml/MHTMLParser.h" |
#include "platform/weborigin/KURL.h" |
#include "public/platform/WebCString.h" |
#include "public/platform/WebString.h" |
@@ -56,6 +57,8 @@ |
#include "web/WebLocalFrameImpl.h" |
#include "web/WebPageSerializerImpl.h" |
#include "web/WebViewImpl.h" |
+#include "wtf/Assertions.h" |
+#include "wtf/HashMap.h" |
#include "wtf/Vector.h" |
#include "wtf/text/StringConcatenate.h" |
@@ -65,12 +68,16 @@ namespace { |
class MHTMLPageSerializerDelegate final : public PageSerializer::Delegate { |
public: |
tkent
2015/12/02 00:59:59
Please add STACK_ALLCOATED(); for oilpan
Łukasz Anforowicz
2015/12/02 02:57:08
After doing this I got the following error: [blink
tkent
2015/12/02 06:33:54
Looks ok. It seems it's hard to make Delegate STA
|
- ~MHTMLPageSerializerDelegate() override; |
+ MHTMLPageSerializerDelegate(HashMap<Frame*, String>* frameToContentID); |
tkent
2015/12/02 00:59:59
The argument and m_frameToContentId should be |con
Łukasz Anforowicz
2015/12/02 02:57:08
I made the change you've suggested, but I wanted t
Łukasz Anforowicz
2015/12/02 03:11:47
Actually, I don't know how I managed to confuse my
|
bool shouldIgnoreAttribute(const Attribute&) override; |
+ bool rewriteLink(const Element&, String& rewrittenLink) override; |
+private: |
tkent
2015/12/02 00:59:59
nit: add a blank line before |private:|
Łukasz Anforowicz
2015/12/02 02:57:08
Done.
|
+ HashMap<Frame*, String>* m_frameToContentID; |
}; |
- |
-MHTMLPageSerializerDelegate::~MHTMLPageSerializerDelegate() |
+MHTMLPageSerializerDelegate::MHTMLPageSerializerDelegate( |
+ HashMap<Frame*, String>* frameToContentID) |
+ : m_frameToContentID(frameToContentID) |
{ |
} |
@@ -82,12 +89,64 @@ bool MHTMLPageSerializerDelegate::shouldIgnoreAttribute(const Attribute& attribu |
return attribute.localName() == HTMLNames::srcsetAttr; |
} |
+bool MHTMLPageSerializerDelegate::rewriteLink( |
+ const Element& element, |
+ String& rewrittenLink) |
+{ |
+ if (!element.isFrameOwnerElement()) |
+ return false; |
+ |
+ auto* frameOwnerElement = toHTMLFrameOwnerElement(&element); |
+ Frame* frame = frameOwnerElement->contentFrame(); |
+ if (!frame) |
+ return false; |
+ |
+ KURL cidURI = MHTMLParser::convertContentIDToURI(m_frameToContentID->get(frame)); |
+ ASSERT(cidURI.isValid()); |
+ |
+ if (isHTMLFrameElementBase(&element)) { |
+ rewrittenLink = cidURI.string(); |
+ return true; |
+ } |
+ |
+ if (isHTMLObjectElement(&element)) { |
+ Document* doc = frameOwnerElement->contentDocument(); |
+ bool isHandledBySerializer = doc->isHTMLDocument() |
+ || doc->isXHTMLDocument() || doc->isImageDocument(); |
+ if (isHandledBySerializer) { |
+ rewrittenLink = cidURI.string(); |
+ return true; |
+ } |
+ } |
+ |
+ return false; |
+} |
+ |
} // namespace |
+static HashMap<Frame*, String> generateFrameContentIDs(Page* page) |
tkent
2015/12/02 00:59:59
The function should be in anonymous namespace abov
Łukasz Anforowicz
2015/12/02 02:57:08
Done (for this and the next function). I am not s
|
+{ |
+ HashMap<Frame*, String> frameToContentID; |
+ int frameID = 0; |
+ for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) { |
+ // TODO(lukasza): Move cid generation to the browser + use base/guid.h |
+ // (see the draft at crrev.com/1386873003). |
+ StringBuilder contentIDBuilder; |
+ contentIDBuilder.appendLiteral("<frame"); |
+ contentIDBuilder.appendNumber(frameID++); |
+ contentIDBuilder.appendLiteral("@mhtml.blink>"); |
+ |
+ frameToContentID.add(frame, contentIDBuilder.toString()); |
+ } |
+ return frameToContentID; |
+} |
+ |
static PassRefPtr<SharedBuffer> serializePageToMHTML(Page* page, MHTMLArchive::EncodingPolicy encodingPolicy) |
{ |
Vector<SerializedResource> resources; |
- PageSerializer serializer(&resources, adoptPtr(new MHTMLPageSerializerDelegate)); |
+ HashMap<Frame*, String> frameToContentID = generateFrameContentIDs(page); |
+ MHTMLPageSerializerDelegate delegate(&frameToContentID); |
+ PageSerializer serializer(resources, &delegate); |
RefPtr<SharedBuffer> output = SharedBuffer::create(); |
String boundary = MHTMLArchive::generateMHTMLBoundary(); |
@@ -105,9 +164,16 @@ static PassRefPtr<SharedBuffer> serializePageToMHTML(Page* page, MHTMLArchive::E |
resources.clear(); |
serializer.serializeFrame(*toLocalFrame(frame)); |
- for (const auto& resource : resources) { |
+ bool isFirstResource = true; |
+ for (const SerializedResource& resource : resources) { |
+ // Frame is the 1st resource (see PageSerializer::serializeFrame doc |
+ // comment). Frames need a Content-ID header. |
+ String contentID = isFirstResource ? frameToContentID.get(frame) : String(); |
+ |
MHTMLArchive::generateMHTMLPart( |
- boundary, encodingPolicy, resource, *output); |
+ boundary, contentID, encodingPolicy, resource, *output); |
+ |
+ isFirstResource = false; |
} |
} |