Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Unified Diff: third_party/WebKit/Source/web/WebPageSerializer.cpp

Issue 1441553002: Generating CIDs in Blink during MHTML serialization. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mhtml-per-frame-page-serializer-only
Patch Set: Replace list Replaced initializer lists with array initialization. Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..501cb39b75a8879c5e99d2228c0265b63df5b420 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,9 @@
#include "web/WebLocalFrameImpl.h"
#include "web/WebPageSerializerImpl.h"
#include "web/WebViewImpl.h"
+#include "wtf/Assertions.h"
+#include "wtf/HashMap.h"
+#include "wtf/Noncopyable.h"
#include "wtf/Vector.h"
#include "wtf/text/StringConcatenate.h"
@@ -63,14 +67,28 @@ namespace blink {
namespace {
-class MHTMLPageSerializerDelegate final : public PageSerializer::Delegate {
+using ContentIDMap = WillBeHeapHashMap<RawPtrWillBeMember<Frame>, String>;
+
+class MHTMLPageSerializerDelegate final :
+ public NoBaseWillBeGarbageCollected<MHTMLPageSerializerDelegate>,
+ public PageSerializer::Delegate {
+ WTF_MAKE_NONCOPYABLE(MHTMLPageSerializerDelegate);
public:
- ~MHTMLPageSerializerDelegate() override;
+ MHTMLPageSerializerDelegate(const ContentIDMap& frameToContentID);
bool shouldIgnoreAttribute(const Attribute&) override;
-};
+ bool rewriteLink(const Element&, String& rewrittenLink) override;
+
+#if ENABLE(OILPAN)
+ void trace(Visitor* visitor) { visitor->trace(m_frameToContentID); }
+#endif
+private:
+ const ContentIDMap& m_frameToContentID;
+};
-MHTMLPageSerializerDelegate::~MHTMLPageSerializerDelegate()
+MHTMLPageSerializerDelegate::MHTMLPageSerializerDelegate(
+ const ContentIDMap& frameToContentID)
+ : m_frameToContentID(frameToContentID)
{
}
@@ -82,12 +100,62 @@ bool MHTMLPageSerializerDelegate::shouldIgnoreAttribute(const Attribute& attribu
return attribute.localName() == HTMLNames::srcsetAttr;
}
-} // namespace
+bool MHTMLPageSerializerDelegate::rewriteLink(
+ const Element& element,
+ String& rewrittenLink)
+{
+ if (!element.isFrameOwnerElement())
+ return false;
-static PassRefPtr<SharedBuffer> serializePageToMHTML(Page* page, MHTMLArchive::EncodingPolicy encodingPolicy)
+ 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;
+}
+
+ContentIDMap generateFrameContentIDs(Page* page)
+{
+ ContentIDMap 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;
+}
+
+PassRefPtr<SharedBuffer> serializePageToMHTML(Page* page, MHTMLArchive::EncodingPolicy encodingPolicy)
{
Vector<SerializedResource> resources;
- PageSerializer serializer(&resources, adoptPtr(new MHTMLPageSerializerDelegate));
+ ContentIDMap frameToContentID = generateFrameContentIDs(page);
+ MHTMLPageSerializerDelegate delegate(frameToContentID);
+ PageSerializer serializer(resources, &delegate);
RefPtr<SharedBuffer> output = SharedBuffer::create();
String boundary = MHTMLArchive::generateMHTMLBoundary();
@@ -105,9 +173,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;
}
}
@@ -115,6 +190,8 @@ static PassRefPtr<SharedBuffer> serializePageToMHTML(Page* page, MHTMLArchive::E
return output.release();
}
+} // namespace
+
WebCString WebPageSerializer::serializeToMHTML(WebView* view)
{
RefPtr<SharedBuffer> mhtml = serializePageToMHTML(toWebViewImpl(view)->page(), MHTMLArchive::UseDefaultEncoding);
« no previous file with comments | « third_party/WebKit/Source/platform/mhtml/MHTMLParser.cpp ('k') | third_party/WebKit/Source/web/tests/MHTMLTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698