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

Side by Side 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: Using references for out parameters in Blink. 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved. 2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 27 matching lines...) Expand all
38 #include "core/html/HTMLAllCollection.h" 38 #include "core/html/HTMLAllCollection.h"
39 #include "core/html/HTMLFrameElementBase.h" 39 #include "core/html/HTMLFrameElementBase.h"
40 #include "core/html/HTMLFrameOwnerElement.h" 40 #include "core/html/HTMLFrameOwnerElement.h"
41 #include "core/html/HTMLInputElement.h" 41 #include "core/html/HTMLInputElement.h"
42 #include "core/html/HTMLTableElement.h" 42 #include "core/html/HTMLTableElement.h"
43 #include "core/loader/DocumentLoader.h" 43 #include "core/loader/DocumentLoader.h"
44 #include "core/page/Page.h" 44 #include "core/page/Page.h"
45 #include "core/page/PageSerializer.h" 45 #include "core/page/PageSerializer.h"
46 #include "platform/SerializedResource.h" 46 #include "platform/SerializedResource.h"
47 #include "platform/mhtml/MHTMLArchive.h" 47 #include "platform/mhtml/MHTMLArchive.h"
48 #include "platform/mhtml/MHTMLParser.h"
48 #include "platform/weborigin/KURL.h" 49 #include "platform/weborigin/KURL.h"
49 #include "public/platform/WebCString.h" 50 #include "public/platform/WebCString.h"
50 #include "public/platform/WebString.h" 51 #include "public/platform/WebString.h"
51 #include "public/platform/WebURL.h" 52 #include "public/platform/WebURL.h"
52 #include "public/platform/WebVector.h" 53 #include "public/platform/WebVector.h"
53 #include "public/web/WebFrame.h" 54 #include "public/web/WebFrame.h"
54 #include "public/web/WebPageSerializerClient.h" 55 #include "public/web/WebPageSerializerClient.h"
55 #include "public/web/WebView.h" 56 #include "public/web/WebView.h"
56 #include "web/WebLocalFrameImpl.h" 57 #include "web/WebLocalFrameImpl.h"
57 #include "web/WebPageSerializerImpl.h" 58 #include "web/WebPageSerializerImpl.h"
58 #include "web/WebViewImpl.h" 59 #include "web/WebViewImpl.h"
60 #include "wtf/Assertions.h"
61 #include "wtf/HashMap.h"
59 #include "wtf/Vector.h" 62 #include "wtf/Vector.h"
60 #include "wtf/text/StringConcatenate.h" 63 #include "wtf/text/StringConcatenate.h"
61 64
62 namespace blink { 65 namespace blink {
63 66
64 namespace { 67 namespace {
65 68
66 class MHTMLPageSerializerDelegate final : public PageSerializer::Delegate { 69 class MHTMLPageSerializerDelegate final : public PageSerializer::Delegate {
67 public: 70 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
68 ~MHTMLPageSerializerDelegate() override; 71 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
69 bool shouldIgnoreAttribute(const Attribute&) override; 72 bool shouldIgnoreAttribute(const Attribute&) override;
73 bool rewriteLink(const Element&, String& rewrittenLink) override;
74 private:
tkent 2015/12/02 00:59:59 nit: add a blank line before |private:|
Łukasz Anforowicz 2015/12/02 02:57:08 Done.
75 HashMap<Frame*, String>* m_frameToContentID;
70 }; 76 };
71 77
72 78 MHTMLPageSerializerDelegate::MHTMLPageSerializerDelegate(
73 MHTMLPageSerializerDelegate::~MHTMLPageSerializerDelegate() 79 HashMap<Frame*, String>* frameToContentID)
80 : m_frameToContentID(frameToContentID)
74 { 81 {
75 } 82 }
76 83
77 bool MHTMLPageSerializerDelegate::shouldIgnoreAttribute(const Attribute& attribu te) 84 bool MHTMLPageSerializerDelegate::shouldIgnoreAttribute(const Attribute& attribu te)
78 { 85 {
79 // TODO(fgorski): Presence of srcset attribute causes MHTML to not display i mages, as only the value of src 86 // TODO(fgorski): Presence of srcset attribute causes MHTML to not display i mages, as only the value of src
80 // is pulled into the archive. Discarding srcset prevents the problem. Long term we should make sure to MHTML 87 // is pulled into the archive. Discarding srcset prevents the problem. Long term we should make sure to MHTML
81 // plays nicely with srcset. 88 // plays nicely with srcset.
82 return attribute.localName() == HTMLNames::srcsetAttr; 89 return attribute.localName() == HTMLNames::srcsetAttr;
83 } 90 }
84 91
92 bool MHTMLPageSerializerDelegate::rewriteLink(
93 const Element& element,
94 String& rewrittenLink)
95 {
96 if (!element.isFrameOwnerElement())
97 return false;
98
99 auto* frameOwnerElement = toHTMLFrameOwnerElement(&element);
100 Frame* frame = frameOwnerElement->contentFrame();
101 if (!frame)
102 return false;
103
104 KURL cidURI = MHTMLParser::convertContentIDToURI(m_frameToContentID->get(fra me));
105 ASSERT(cidURI.isValid());
106
107 if (isHTMLFrameElementBase(&element)) {
108 rewrittenLink = cidURI.string();
109 return true;
110 }
111
112 if (isHTMLObjectElement(&element)) {
113 Document* doc = frameOwnerElement->contentDocument();
114 bool isHandledBySerializer = doc->isHTMLDocument()
115 || doc->isXHTMLDocument() || doc->isImageDocument();
116 if (isHandledBySerializer) {
117 rewrittenLink = cidURI.string();
118 return true;
119 }
120 }
121
122 return false;
123 }
124
85 } // namespace 125 } // namespace
86 126
127 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
128 {
129 HashMap<Frame*, String> frameToContentID;
130 int frameID = 0;
131 for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverse Next()) {
132 // TODO(lukasza): Move cid generation to the browser + use base/guid.h
133 // (see the draft at crrev.com/1386873003).
134 StringBuilder contentIDBuilder;
135 contentIDBuilder.appendLiteral("<frame");
136 contentIDBuilder.appendNumber(frameID++);
137 contentIDBuilder.appendLiteral("@mhtml.blink>");
138
139 frameToContentID.add(frame, contentIDBuilder.toString());
140 }
141 return frameToContentID;
142 }
143
87 static PassRefPtr<SharedBuffer> serializePageToMHTML(Page* page, MHTMLArchive::E ncodingPolicy encodingPolicy) 144 static PassRefPtr<SharedBuffer> serializePageToMHTML(Page* page, MHTMLArchive::E ncodingPolicy encodingPolicy)
88 { 145 {
89 Vector<SerializedResource> resources; 146 Vector<SerializedResource> resources;
90 PageSerializer serializer(&resources, adoptPtr(new MHTMLPageSerializerDelega te)); 147 HashMap<Frame*, String> frameToContentID = generateFrameContentIDs(page);
148 MHTMLPageSerializerDelegate delegate(&frameToContentID);
149 PageSerializer serializer(resources, &delegate);
91 150
92 RefPtr<SharedBuffer> output = SharedBuffer::create(); 151 RefPtr<SharedBuffer> output = SharedBuffer::create();
93 String boundary = MHTMLArchive::generateMHTMLBoundary(); 152 String boundary = MHTMLArchive::generateMHTMLBoundary();
94 153
95 Document* document = page->deprecatedLocalMainFrame()->document(); 154 Document* document = page->deprecatedLocalMainFrame()->document();
96 MHTMLArchive::generateMHTMLHeader( 155 MHTMLArchive::generateMHTMLHeader(
97 boundary, document->title(), document->suggestedMIMEType(), *output); 156 boundary, document->title(), document->suggestedMIMEType(), *output);
98 157
99 for (Frame* frame = page->deprecatedLocalMainFrame(); frame; frame = frame-> tree().traverseNext()) { 158 for (Frame* frame = page->deprecatedLocalMainFrame(); frame; frame = frame-> tree().traverseNext()) {
100 // TODO(lukasza): This causes incomplete MHTML for OOPIFs. 159 // TODO(lukasza): This causes incomplete MHTML for OOPIFs.
101 // (crbug.com/538766) 160 // (crbug.com/538766)
102 if (!frame->isLocalFrame()) 161 if (!frame->isLocalFrame())
103 continue; 162 continue;
104 163
105 resources.clear(); 164 resources.clear();
106 serializer.serializeFrame(*toLocalFrame(frame)); 165 serializer.serializeFrame(*toLocalFrame(frame));
107 166
108 for (const auto& resource : resources) { 167 bool isFirstResource = true;
168 for (const SerializedResource& resource : resources) {
169 // Frame is the 1st resource (see PageSerializer::serializeFrame doc
170 // comment). Frames need a Content-ID header.
171 String contentID = isFirstResource ? frameToContentID.get(frame) : S tring();
172
109 MHTMLArchive::generateMHTMLPart( 173 MHTMLArchive::generateMHTMLPart(
110 boundary, encodingPolicy, resource, *output); 174 boundary, contentID, encodingPolicy, resource, *output);
175
176 isFirstResource = false;
111 } 177 }
112 } 178 }
113 179
114 MHTMLArchive::generateMHTMLFooter(boundary, *output); 180 MHTMLArchive::generateMHTMLFooter(boundary, *output);
115 return output.release(); 181 return output.release();
116 } 182 }
117 183
118 WebCString WebPageSerializer::serializeToMHTML(WebView* view) 184 WebCString WebPageSerializer::serializeToMHTML(WebView* view)
119 { 185 {
120 RefPtr<SharedBuffer> mhtml = serializePageToMHTML(toWebViewImpl(view)->page( ), MHTMLArchive::UseDefaultEncoding); 186 RefPtr<SharedBuffer> mhtml = serializePageToMHTML(toWebViewImpl(view)->page( ), MHTMLArchive::UseDefaultEncoding);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 WebString WebPageSerializer::generateBaseTagDeclaration(const WebString& baseTar get) 225 WebString WebPageSerializer::generateBaseTagDeclaration(const WebString& baseTar get)
160 { 226 {
161 // TODO(yosin) We should call |PageSerializer::baseTagDeclarationOf()|. 227 // TODO(yosin) We should call |PageSerializer::baseTagDeclarationOf()|.
162 if (baseTarget.isEmpty()) 228 if (baseTarget.isEmpty())
163 return String("<base href=\".\">"); 229 return String("<base href=\".\">");
164 String baseString = "<base href=\".\" target=\"" + static_cast<const String& >(baseTarget) + "\">"; 230 String baseString = "<base href=\".\" target=\"" + static_cast<const String& >(baseTarget) + "\">";
165 return baseString; 231 return baseString;
166 } 232 }
167 233
168 } // namespace blink 234 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698