| 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..71786e05a37d62ab240161c0316513302e930d39 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:
|
| - ~MHTMLPageSerializerDelegate() override;
|
| + MHTMLPageSerializerDelegate(HashMap<Frame*, String>* frameToContentID);
|
| bool shouldIgnoreAttribute(const Attribute&) override;
|
| + String rewriteLink(const Element&) override;
|
| +private:
|
| + HashMap<Frame*, String>* m_frameToContentID;
|
| };
|
|
|
| -
|
| -MHTMLPageSerializerDelegate::~MHTMLPageSerializerDelegate()
|
| +MHTMLPageSerializerDelegate::MHTMLPageSerializerDelegate(
|
| + HashMap<Frame*, String>* frameToContentID)
|
| + : m_frameToContentID(frameToContentID)
|
| {
|
| }
|
|
|
| @@ -82,12 +89,58 @@ bool MHTMLPageSerializerDelegate::shouldIgnoreAttribute(const Attribute& attribu
|
| return attribute.localName() == HTMLNames::srcsetAttr;
|
| }
|
|
|
| +String MHTMLPageSerializerDelegate::rewriteLink(const Element& element)
|
| +{
|
| + if (!element.isFrameOwnerElement())
|
| + return String();
|
| +
|
| + auto* frameOwnerElement = toHTMLFrameOwnerElement(&element);
|
| + Frame* frame = frameOwnerElement->contentFrame();
|
| + if (!frame)
|
| + return String();
|
| +
|
| + KURL cidURI = MHTMLParser::convertContentIDToURI(m_frameToContentID->get(frame));
|
| + ASSERT(cidURI.isValid());
|
| +
|
| + if (isHTMLFrameElementBase(&element))
|
| + return cidURI.string();
|
| +
|
| + if (isHTMLObjectElement(&element)) {
|
| + Document* doc = frameOwnerElement->contentDocument();
|
| + bool isHandledBySerializer = doc->isHTMLDocument()
|
| + || doc->isXHTMLDocument() || doc->isImageDocument();
|
| + if (isHandledBySerializer)
|
| + return cidURI.string();
|
| + }
|
| +
|
| + return String();
|
| +}
|
| +
|
| } // namespace
|
|
|
| +static HashMap<Frame*, String> generateFrameContentIDs(Page* page)
|
| +{
|
| + 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 +158,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;
|
| }
|
| }
|
|
|
|
|