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

Side by Side Diff: Source/core/page/PageSerializer.cpp

Issue 68613003: Merges the two different page serializers (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 1 month 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) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 #include "core/dom/Element.h" 46 #include "core/dom/Element.h"
47 #include "core/dom/Text.h" 47 #include "core/dom/Text.h"
48 #include "core/editing/MarkupAccumulator.h" 48 #include "core/editing/MarkupAccumulator.h"
49 #include "core/fetch/FontResource.h" 49 #include "core/fetch/FontResource.h"
50 #include "core/fetch/ImageResource.h" 50 #include "core/fetch/ImageResource.h"
51 #include "core/html/HTMLFrameOwnerElement.h" 51 #include "core/html/HTMLFrameOwnerElement.h"
52 #include "core/html/HTMLImageElement.h" 52 #include "core/html/HTMLImageElement.h"
53 #include "core/html/HTMLInputElement.h" 53 #include "core/html/HTMLInputElement.h"
54 #include "core/html/HTMLLinkElement.h" 54 #include "core/html/HTMLLinkElement.h"
55 #include "core/html/HTMLStyleElement.h" 55 #include "core/html/HTMLStyleElement.h"
56 #include "core/html/ImageDocument.h"
56 #include "core/html/parser/HTMLMetaCharsetParser.h" 57 #include "core/html/parser/HTMLMetaCharsetParser.h"
57 #include "core/frame/Frame.h" 58 #include "core/frame/Frame.h"
58 #include "core/page/Page.h" 59 #include "core/page/Page.h"
59 #include "core/platform/graphics/Image.h" 60 #include "core/platform/graphics/Image.h"
60 #include "core/rendering/RenderImage.h" 61 #include "core/rendering/RenderImage.h"
61 #include "core/rendering/style/StyleFetchedImage.h" 62 #include "core/rendering/style/StyleFetchedImage.h"
62 #include "core/rendering/style/StyleImage.h" 63 #include "core/rendering/style/StyleImage.h"
63 #include "platform/SerializedResource.h" 64 #include "platform/SerializedResource.h"
65 #include "wtf/OwnPtr.h"
abarth-chromium 2013/11/14 16:55:03 Undoubtedly one of these other headers pulls in Ow
64 #include "wtf/text/CString.h" 66 #include "wtf/text/CString.h"
65 #include "wtf/text/StringBuilder.h" 67 #include "wtf/text/StringBuilder.h"
66 #include "wtf/text/TextEncoding.h" 68 #include "wtf/text/TextEncoding.h"
67 #include "wtf/text/WTFString.h" 69 #include "wtf/text/WTFString.h"
68 70
69 namespace WebCore { 71 namespace WebCore {
70 72
71 static bool isCharsetSpecifyingNode(Node* node) 73 static bool isCharsetSpecifyingNode(Node* node)
72 { 74 {
73 if (!node->isHTMLElement()) 75 if (!node->isHTMLElement())
(...skipping 24 matching lines...) Expand all
98 // FIXME: We should support all frame owners including applets. 100 // FIXME: We should support all frame owners including applets.
99 return frameOwner.hasTagName(HTMLNames::objectTag) ? HTMLNames::dataAttr : H TMLNames::srcAttr; 101 return frameOwner.hasTagName(HTMLNames::objectTag) ? HTMLNames::dataAttr : H TMLNames::srcAttr;
100 } 102 }
101 103
102 class SerializerMarkupAccumulator : public WebCore::MarkupAccumulator { 104 class SerializerMarkupAccumulator : public WebCore::MarkupAccumulator {
103 public: 105 public:
104 SerializerMarkupAccumulator(PageSerializer*, Document*, Vector<Node*>*); 106 SerializerMarkupAccumulator(PageSerializer*, Document*, Vector<Node*>*);
105 virtual ~SerializerMarkupAccumulator(); 107 virtual ~SerializerMarkupAccumulator();
106 108
107 protected: 109 protected:
108 virtual void appendText(StringBuilder& out, Text*); 110 virtual void appendText(StringBuilder&, Text*) OVERRIDE;
109 virtual void appendElement(StringBuilder& out, Element*, Namespaces*); 111 virtual void appendElement(StringBuilder&, Element*, Namespaces*) OVERRIDE;
110 virtual void appendCustomAttributes(StringBuilder& out, Element*, Namespaces *); 112 virtual void appendCustomAttributes(StringBuilder&, Element*, Namespaces*) O VERRIDE;
111 virtual void appendEndTag(Node*); 113 virtual void appendEndTag(Node*) OVERRIDE;
112 114
113 private:
114 PageSerializer* m_serializer; 115 PageSerializer* m_serializer;
115 Document* m_document; 116 Document* m_document;
116 }; 117 };
117 118
118 SerializerMarkupAccumulator::SerializerMarkupAccumulator(PageSerializer* seriali zer, Document* document, Vector<Node*>* nodes) 119 SerializerMarkupAccumulator::SerializerMarkupAccumulator(PageSerializer* seriali zer, Document* document, Vector<Node*>* nodes)
119 : MarkupAccumulator(nodes, ResolveAllURLs) 120 : MarkupAccumulator(nodes, ResolveAllURLs)
120 , m_serializer(serializer) 121 , m_serializer(serializer)
121 , m_document(document) 122 , m_document(document)
122 { 123 {
124
abarth-chromium 2013/11/14 16:55:03 This blank line is not needed.
123 } 125 }
124 126
125 SerializerMarkupAccumulator::~SerializerMarkupAccumulator() 127 SerializerMarkupAccumulator::~SerializerMarkupAccumulator()
126 { 128 {
127 } 129 }
128 130
129 void SerializerMarkupAccumulator::appendText(StringBuilder& out, Text* text) 131 void SerializerMarkupAccumulator::appendText(StringBuilder& result, Text* text)
130 { 132 {
131 Element* parent = text->parentElement(); 133 Element* parent = text->parentElement();
132 if (parent && !shouldIgnoreElement(parent)) 134 if (parent && !shouldIgnoreElement(parent))
133 MarkupAccumulator::appendText(out, text); 135 MarkupAccumulator::appendText(result, text);
134 } 136 }
135 137
136 void SerializerMarkupAccumulator::appendElement(StringBuilder& out, Element* ele ment, Namespaces* namespaces) 138 void SerializerMarkupAccumulator::appendElement(StringBuilder& result, Element* element, Namespaces* namespaces)
137 { 139 {
138 if (!shouldIgnoreElement(element)) 140 if (!shouldIgnoreElement(element))
139 MarkupAccumulator::appendElement(out, element, namespaces); 141 MarkupAccumulator::appendElement(result, element, namespaces);
140 142
141 if (element->hasTagName(HTMLNames::headTag)) { 143 if (element->hasTagName(HTMLNames::headTag)) {
142 out.append("<meta charset=\""); 144 result.appendLiteral("<meta charset=\"");
143 out.append(m_document->charset()); 145 result.append(m_document->charset());
144 out.append("\">"); 146 if (m_document->isXHTMLDocument())
147 result.appendLiteral("\" />");
148 else
149 result.appendLiteral("\">");
145 } 150 }
146 151
147 // FIXME: For object (plugins) tags and video tag we could replace them by a n image of their current contents. 152 // FIXME: For object (plugins) tags and video tag we could replace them by a n image of their current contents.
148 } 153 }
149 154
150 void SerializerMarkupAccumulator::appendCustomAttributes(StringBuilder& out, Ele ment* element, Namespaces* namespaces) 155 void SerializerMarkupAccumulator::appendCustomAttributes(StringBuilder& result, Element* element, Namespaces* namespaces)
151 { 156 {
152 if (!element->isFrameOwnerElement()) 157 if (!element->isFrameOwnerElement())
153 return; 158 return;
154 159
155 HTMLFrameOwnerElement* frameOwner = toHTMLFrameOwnerElement(element); 160 HTMLFrameOwnerElement* frameOwner = toHTMLFrameOwnerElement(element);
156 Frame* frame = frameOwner->contentFrame(); 161 Frame* frame = frameOwner->contentFrame();
157 if (!frame) 162 if (!frame)
158 return; 163 return;
159 164
160 KURL url = frame->document()->url(); 165 KURL url = frame->document()->url();
161 if (url.isValid() && !url.isBlankURL()) 166 if (url.isValid() && !url.isBlankURL())
162 return; 167 return;
163 168
164 // We need to give a fake location to blank frames so they can be referenced by the serialized frame. 169 // We need to give a fake location to blank frames so they can be referenced by the serialized frame.
165 url = m_serializer->urlForBlankFrame(frame); 170 url = m_serializer->urlForBlankFrame(frame);
166 appendAttribute(out, element, Attribute(frameOwnerURLAttributeName(*frameOwn er), url.string()), namespaces); 171 appendAttribute(result, element, Attribute(frameOwnerURLAttributeName(*frame Owner), url.string()), namespaces);
167 } 172 }
168 173
169 void SerializerMarkupAccumulator::appendEndTag(Node* node) 174 void SerializerMarkupAccumulator::appendEndTag(Node* node)
170 { 175 {
171 if (node->isElementNode() && !shouldIgnoreElement(toElement(node))) 176 if (node->isElementNode() && !shouldIgnoreElement(toElement(node)))
172 MarkupAccumulator::appendEndTag(node); 177 MarkupAccumulator::appendEndTag(node);
173 } 178 }
174 179
175 PageSerializer::PageSerializer(Vector<SerializedResource>* resources) 180
176 : m_resources(resources) 181
abarth-chromium 2013/11/14 16:55:03 You've got two extra blank lines here.
177 , m_blankFrameCounter(0) 182 class LinkChangeSerializerMarkupAccumulator : public SerializerMarkupAccumulator {
183 public:
184 LinkChangeSerializerMarkupAccumulator(PageSerializer*, Document*, Vector<Nod e*>*, LinkLocalPathMap*, String);
185
186 protected:
187 virtual void appendElement(StringBuilder&, Element*, Namespaces*) OVERRIDE;
188 virtual void appendAttribute(StringBuilder&, Element*, const Attribute&, Nam espaces*) OVERRIDE;
189
190 private:
191 // local_links_ include all pair of local resource path and corresponding
192 // original link.
193 LinkLocalPathMap* m_replaceLinks;
194 String m_directoryName;
195 };
196
197 LinkChangeSerializerMarkupAccumulator::LinkChangeSerializerMarkupAccumulator(Pag eSerializer* serializer, Document* document, Vector<Node*>* nodes, LinkLocalPath Map* links, String directoryName)
198 : SerializerMarkupAccumulator(serializer, document, nodes)
199 , m_replaceLinks(links)
200 , m_directoryName(directoryName)
178 { 201 {
179 } 202 }
180 203
204 void LinkChangeSerializerMarkupAccumulator::appendElement(StringBuilder& result, Element* element, Namespaces* namespaces)
205 {
206 // TODO: or move to append open tag / close tag
abarth-chromium 2013/11/14 16:55:03 TODO -> FIXME Also, please use complete sentences
207
208 if (element->hasTagName(HTMLNames::baseTag)) {
209 // Comment the BASE tag when serializing dom.
210 result.append("<!--");
211 } else if (element->hasTagName(HTMLNames::htmlTag)) {
212 // Add MOTW (Mark of the Web) declaration before html tag.
213 // See http://msdn2.microsoft.com/en-us/library/ms537628(VS.85).aspx.
214 result.append(String::format("\n<!-- saved from url=(%04d)%s -->\n",
215 static_cast<int>(m_document->url().string().utf8().length()),
216 m_document->url().string().utf8().data()));
217 }
218
219 SerializerMarkupAccumulator::appendElement(result, element, namespaces);
220
221 if (element->hasTagName(HTMLNames::baseTag)) {
222 // Comment the BASE tag when serializing dom.
223 result.appendLiteral("-->");
224
225 // Append a new base tag declaration.
226 result.appendLiteral("<base href=\".\"");
227 if (!m_document->baseTarget().isEmpty()) {
228 result.appendLiteral(" target=\"");
229 result.append(m_document->baseTarget());
230 result.append('"');
231 }
232 if (m_document->isXHTMLDocument())
233 result.appendLiteral(" />");
234 else
235 result.appendLiteral(">");
236 }
237 }
238 void LinkChangeSerializerMarkupAccumulator::appendAttribute(StringBuilder& resul t, Element* element, const Attribute& attribute, Namespaces* namespaces)
239 {
240 if (m_replaceLinks && element->isURLAttribute(attribute)
241 && !element->isJavaScriptURLAttribute(attribute)) {
242
243 // Get the absolute link
abarth-chromium 2013/11/14 16:55:03 You can remove these comments that just way what t
244 String completeURL = m_document->completeURL(attribute.value());
245
246 // Check whether we have local files for those link.
247 if (m_replaceLinks->contains(completeURL)) {
248 // TODO: refactor markupaccumulator, reuse code
abarth-chromium 2013/11/14 16:55:03 TODO -> FIXME
249 result.append(' ');
250 result.append(attribute.name().toString());
251 result.appendLiteral("=\"");
252 if (!m_directoryName.isEmpty()) {
253 result.appendLiteral("./");
254 result.append(m_directoryName);
255 result.append('/');
256 }
257 result.append(m_replaceLinks->get(completeURL));
258 result.appendLiteral("\"");
259 return;
260 }
261 }
262 MarkupAccumulator::appendAttribute(result, element, attribute, namespaces);
263 }
264
265
abarth-chromium 2013/11/14 16:55:03 You've got an extra blank line here.
266 PageSerializer::PageSerializer(Vector<SerializedResource>* resources, LinkLocalP athMap* urls, String directory)
267 : m_resources(resources)
268 , m_URLs(urls)
269 , m_directory(directory)
270 , m_blankFrameCounter(0)
271 {
272
273 }
274
181 void PageSerializer::serialize(Page* page) 275 void PageSerializer::serialize(Page* page)
182 { 276 {
183 serializeFrame(page->mainFrame()); 277 serializeFrame(page->mainFrame());
184 } 278 }
185 279
186 void PageSerializer::serializeFrame(Frame* frame) 280 void PageSerializer::serializeFrame(Frame* frame)
187 { 281 {
188 Document* document = frame->document(); 282 Document* document = frame->document();
189 KURL url = document->url(); 283 KURL url = document->url();
190 if (!url.isValid() || url.isBlankURL()) { 284 if (!url.isValid() || url.isBlankURL()) {
191 // For blank frames we generate a fake URL so they can be referenced by their containing frame. 285 // For blank frames we generate a fake URL so they can be referenced by their containing frame.
192 url = urlForBlankFrame(frame); 286 url = urlForBlankFrame(frame);
193 } 287 }
194 288
195 if (m_resourceURLs.contains(url)) { 289 if (m_resourceURLs.contains(url)) {
196 // FIXME: We could have 2 frame with the same URL but which were dynamic ally changed and have now 290 // FIXME: We could have 2 frame with the same URL but which were dynamic ally changed and have now
197 // different content. So we should serialize both and somehow rename the frame src in the containing 291 // different content. So we should serialize both and somehow rename the frame src in the containing
198 // frame. Arg! 292 // frame. Arg!
199 return; 293 return;
200 } 294 }
201 295
296 // If frame is an image document, add the image and don't continue
297 if (document->isImageDocument()) {
298 ImageDocument* imageDocument = toImageDocument(document);
299 addImageToResources(imageDocument->cachedImage(), imageDocument->imageEl ement()->renderer(), url);
300 return;
301 }
302
202 Vector<Node*> nodes; 303 Vector<Node*> nodes;
203 SerializerMarkupAccumulator accumulator(this, document, &nodes); 304 WTF::OwnPtr<SerializerMarkupAccumulator> accumulator;
abarth-chromium 2013/11/14 16:55:03 No need for WTF:: here. OwnPtr has a using WTF::O
305 if (m_URLs) {
306 accumulator = adoptPtr(new LinkChangeSerializerMarkupAccumulator(this, d ocument, &nodes, m_URLs, m_directory));
307 } else {
308 accumulator = adoptPtr(new SerializerMarkupAccumulator(this, document, & nodes));
309 }
abarth-chromium 2013/11/14 16:55:03 No need for { } in either branch of the if here.
310 String text = accumulator->serializeNodes(document, IncludeNode);
204 WTF::TextEncoding textEncoding(document->charset()); 311 WTF::TextEncoding textEncoding(document->charset());
205 CString data;
206 if (!textEncoding.isValid()) {
207 // FIXME: iframes used as images trigger this. We should deal with them correctly.
208 return;
209 }
210 String text = accumulator.serializeNodes(document, IncludeNode);
211 CString frameHTML = textEncoding.normalizeAndEncode(text, WTF::EntitiesForUn encodables); 312 CString frameHTML = textEncoding.normalizeAndEncode(text, WTF::EntitiesForUn encodables);
212 m_resources->append(SerializedResource(url, document->suggestedMIMEType(), S haredBuffer::create(frameHTML.data(), frameHTML.length()))); 313 m_resources->append(SerializedResource(url, document->suggestedMIMEType(), S haredBuffer::create(frameHTML.data(), frameHTML.length())));
213 m_resourceURLs.add(url); 314 m_resourceURLs.add(url);
214 315
215 for (Vector<Node*>::iterator iter = nodes.begin(); iter != nodes.end(); ++it er) { 316 for (Vector<Node*>::iterator iter = nodes.begin(); iter != nodes.end(); ++it er) {
216 Node* node = *iter; 317 Node* node = *iter;
217 if (!node->isElementNode()) 318 if (!node->isElementNode())
218 continue; 319 continue;
219 320
220 Element* element = toElement(node); 321 Element* element = toElement(node);
221 // We have to process in-line style as it might contain some resources ( typically background images). 322 // We have to process in-line style as it might contain some resources ( typically background images).
222 if (element->isStyledElement()) 323 if (element->isStyledElement()) {
223 retrieveResourcesForProperties(element->inlineStyle(), document); 324 retrieveResourcesForProperties(element->inlineStyle(), document);
325 retrieveResourcesForProperties(element->presentationAttributeStyle() , document);
326 }
224 327
225 if (element->hasTagName(HTMLNames::imgTag)) { 328 if (element->hasTagName(HTMLNames::imgTag)) {
226 HTMLImageElement* imageElement = toHTMLImageElement(element); 329 HTMLImageElement* imageElement = toHTMLImageElement(element);
227 KURL url = document->completeURL(imageElement->getAttribute(HTMLName s::srcAttr)); 330 KURL url = document->completeURL(imageElement->getAttribute(HTMLName s::srcAttr));
228 ImageResource* cachedImage = imageElement->cachedImage(); 331 ImageResource* cachedImage = imageElement->cachedImage();
229 addImageToResources(cachedImage, imageElement->renderer(), url); 332 addImageToResources(cachedImage, imageElement->renderer(), url);
230 } else if (element->hasTagName(HTMLNames::inputTag)) { 333 } else if (element->hasTagName(HTMLNames::inputTag)) {
231 HTMLInputElement* inputElement = toHTMLInputElement(element); 334 HTMLInputElement* inputElement = toHTMLInputElement(element);
232 if (inputElement->isImageButton() && inputElement->hasImageLoader()) { 335 if (inputElement->isImageButton() && inputElement->hasImageLoader()) {
233 KURL url = inputElement->src(); 336 KURL url = inputElement->src();
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 String mimeType = resource->response().mimeType(); 407 String mimeType = resource->response().mimeType();
305 m_resources->append(SerializedResource(url, mimeType, data)); 408 m_resources->append(SerializedResource(url, mimeType, data));
306 m_resourceURLs.add(url); 409 m_resourceURLs.add(url);
307 } 410 }
308 411
309 void PageSerializer::addImageToResources(ImageResource* image, RenderObject* ima geRenderer, const KURL& url) 412 void PageSerializer::addImageToResources(ImageResource* image, RenderObject* ima geRenderer, const KURL& url)
310 { 413 {
311 if (!shouldAddURL(url)) 414 if (!shouldAddURL(url))
312 return; 415 return;
313 416
314 if (!image || image->image() == Image::nullImage()) 417 if (!image->hasImage() || image->image() == Image::nullImage())
315 return; 418 return;
316 419
317 RefPtr<SharedBuffer> data = imageRenderer ? image->imageForRenderer(imageRen derer)->data() : 0; 420 RefPtr<SharedBuffer> data = imageRenderer ? image->imageForRenderer(imageRen derer)->data() : 0;
318 if (!data) 421 if (!data)
319 data = image->image()->data(); 422 data = image->image()->data();
320 423
321 addToResources(image, data, url); 424 addToResources(image, data, url);
322 } 425 }
323 426
324 void PageSerializer::addFontToResources(FontResource* font) 427 void PageSerializer::addFontToResources(FontResource* font)
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 if (iter != m_blankFrameURLs.end()) 479 if (iter != m_blankFrameURLs.end())
377 return iter->value; 480 return iter->value;
378 String url = "wyciwyg://frame/" + String::number(m_blankFrameCounter++); 481 String url = "wyciwyg://frame/" + String::number(m_blankFrameCounter++);
379 KURL fakeURL(ParsedURLString, url); 482 KURL fakeURL(ParsedURLString, url);
380 m_blankFrameURLs.add(frame, fakeURL); 483 m_blankFrameURLs.add(frame, fakeURL);
381 484
382 return fakeURL; 485 return fakeURL;
383 } 486 }
384 487
385 } 488 }
489
abarth-chromium 2013/11/14 16:55:03 No need for this blank line.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698