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

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: Fix Review Issues 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"
64 #include "wtf/text/CString.h" 65 #include "wtf/text/CString.h"
65 #include "wtf/text/StringBuilder.h" 66 #include "wtf/text/StringBuilder.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 // FIXME: We should support all frame owners including applets. 99 // FIXME: We should support all frame owners including applets.
99 return frameOwner.hasTagName(HTMLNames::objectTag) ? HTMLNames::dataAttr : H TMLNames::srcAttr; 100 return frameOwner.hasTagName(HTMLNames::objectTag) ? HTMLNames::dataAttr : H TMLNames::srcAttr;
100 } 101 }
101 102
102 class SerializerMarkupAccumulator : public WebCore::MarkupAccumulator { 103 class SerializerMarkupAccumulator : public WebCore::MarkupAccumulator {
103 public: 104 public:
104 SerializerMarkupAccumulator(PageSerializer*, Document*, Vector<Node*>*); 105 SerializerMarkupAccumulator(PageSerializer*, Document*, Vector<Node*>*);
105 virtual ~SerializerMarkupAccumulator(); 106 virtual ~SerializerMarkupAccumulator();
106 107
107 protected: 108 protected:
108 virtual void appendText(StringBuilder& out, Text*); 109 virtual void appendText(StringBuilder&, Text*) OVERRIDE;
109 virtual void appendElement(StringBuilder& out, Element*, Namespaces*); 110 virtual void appendElement(StringBuilder&, Element*, Namespaces*) OVERRIDE;
110 virtual void appendCustomAttributes(StringBuilder& out, Element*, Namespaces *); 111 virtual void appendCustomAttributes(StringBuilder&, Element*, Namespaces*) O VERRIDE;
111 virtual void appendEndTag(Node*); 112 virtual void appendEndTag(Node*) OVERRIDE;
112 113
113 private:
114 PageSerializer* m_serializer; 114 PageSerializer* m_serializer;
115 Document* m_document; 115 Document* m_document;
116 }; 116 };
117 117
118 SerializerMarkupAccumulator::SerializerMarkupAccumulator(PageSerializer* seriali zer, Document* document, Vector<Node*>* nodes) 118 SerializerMarkupAccumulator::SerializerMarkupAccumulator(PageSerializer* seriali zer, Document* document, Vector<Node*>* nodes)
119 : MarkupAccumulator(nodes, ResolveAllURLs) 119 : MarkupAccumulator(nodes, ResolveAllURLs)
120 , m_serializer(serializer) 120 , m_serializer(serializer)
121 , m_document(document) 121 , m_document(document)
122 { 122 {
123 } 123 }
124 124
125 SerializerMarkupAccumulator::~SerializerMarkupAccumulator() 125 SerializerMarkupAccumulator::~SerializerMarkupAccumulator()
126 { 126 {
127 } 127 }
128 128
129 void SerializerMarkupAccumulator::appendText(StringBuilder& out, Text* text) 129 void SerializerMarkupAccumulator::appendText(StringBuilder& result, Text* text)
130 { 130 {
131 Element* parent = text->parentElement(); 131 Element* parent = text->parentElement();
132 if (parent && !shouldIgnoreElement(parent)) 132 if (parent && !shouldIgnoreElement(parent))
133 MarkupAccumulator::appendText(out, text); 133 MarkupAccumulator::appendText(result, text);
134 } 134 }
135 135
136 void SerializerMarkupAccumulator::appendElement(StringBuilder& out, Element* ele ment, Namespaces* namespaces) 136 void SerializerMarkupAccumulator::appendElement(StringBuilder& result, Element* element, Namespaces* namespaces)
137 { 137 {
138 if (!shouldIgnoreElement(element)) 138 if (!shouldIgnoreElement(element))
139 MarkupAccumulator::appendElement(out, element, namespaces); 139 MarkupAccumulator::appendElement(result, element, namespaces);
140 140
141 // FIXME: Refactor MarkupAccumulator so it is easier to append an element li ke this, without special cases for XHTML
141 if (element->hasTagName(HTMLNames::headTag)) { 142 if (element->hasTagName(HTMLNames::headTag)) {
142 out.append("<meta charset=\""); 143 result.appendLiteral("<meta charset=\"");
143 out.append(m_document->charset()); 144 result.append(m_document->charset());
144 out.append("\">"); 145 if (m_document->isXHTMLDocument())
146 result.appendLiteral("\" />");
147 else
148 result.appendLiteral("\">");
145 } 149 }
146 150
147 // FIXME: For object (plugins) tags and video tag we could replace them by a n image of their current contents. 151 // FIXME: For object (plugins) tags and video tag we could replace them by a n image of their current contents.
148 } 152 }
149 153
150 void SerializerMarkupAccumulator::appendCustomAttributes(StringBuilder& out, Ele ment* element, Namespaces* namespaces) 154 void SerializerMarkupAccumulator::appendCustomAttributes(StringBuilder& result, Element* element, Namespaces* namespaces)
151 { 155 {
152 if (!element->isFrameOwnerElement()) 156 if (!element->isFrameOwnerElement())
153 return; 157 return;
154 158
155 HTMLFrameOwnerElement* frameOwner = toHTMLFrameOwnerElement(element); 159 HTMLFrameOwnerElement* frameOwner = toHTMLFrameOwnerElement(element);
156 Frame* frame = frameOwner->contentFrame(); 160 Frame* frame = frameOwner->contentFrame();
157 if (!frame) 161 if (!frame)
158 return; 162 return;
159 163
160 KURL url = frame->document()->url(); 164 KURL url = frame->document()->url();
161 if (url.isValid() && !url.isBlankURL()) 165 if (url.isValid() && !url.isBlankURL())
162 return; 166 return;
163 167
164 // We need to give a fake location to blank frames so they can be referenced by the serialized frame. 168 // 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); 169 url = m_serializer->urlForBlankFrame(frame);
166 appendAttribute(out, element, Attribute(frameOwnerURLAttributeName(*frameOwn er), url.string()), namespaces); 170 appendAttribute(result, element, Attribute(frameOwnerURLAttributeName(*frame Owner), url.string()), namespaces);
167 } 171 }
168 172
169 void SerializerMarkupAccumulator::appendEndTag(Node* node) 173 void SerializerMarkupAccumulator::appendEndTag(Node* node)
170 { 174 {
171 if (node->isElementNode() && !shouldIgnoreElement(toElement(node))) 175 if (node->isElementNode() && !shouldIgnoreElement(toElement(node)))
172 MarkupAccumulator::appendEndTag(node); 176 MarkupAccumulator::appendEndTag(node);
173 } 177 }
174 178
175 PageSerializer::PageSerializer(Vector<SerializedResource>* resources) 179 class LinkChangeSerializerMarkupAccumulator : public SerializerMarkupAccumulator {
176 : m_resources(resources) 180 public:
177 , m_blankFrameCounter(0) 181 LinkChangeSerializerMarkupAccumulator(PageSerializer*, Document*, Vector<Nod e*>*, LinkLocalPathMap*, String);
182
183 protected:
184 virtual void appendElement(StringBuilder&, Element*, Namespaces*) OVERRIDE;
185 virtual void appendAttribute(StringBuilder&, Element*, const Attribute&, Nam espaces*) OVERRIDE;
186
187 private:
188 // local_links_ include all pair of local resource path and corresponding
abarth-chromium 2013/11/15 15:58:51 What is local_links_? Do you mean m_replaceLinks?
189 // original link.
190 LinkLocalPathMap* m_replaceLinks;
191 String m_directoryName;
192 };
193
194 LinkChangeSerializerMarkupAccumulator::LinkChangeSerializerMarkupAccumulator(Pag eSerializer* serializer, Document* document, Vector<Node*>* nodes, LinkLocalPath Map* links, String directoryName)
195 : SerializerMarkupAccumulator(serializer, document, nodes)
196 , m_replaceLinks(links)
197 , m_directoryName(directoryName)
178 { 198 {
179 } 199 }
180 200
201 void LinkChangeSerializerMarkupAccumulator::appendElement(StringBuilder& result, Element* element, Namespaces* namespaces)
202 {
203 // FIXME: We could move the uncommenting to appendOpenTag and appendCloseTag , or just remove it
204 if (element->hasTagName(HTMLNames::baseTag)) {
205 // Comment the BASE tag when serializing dom.
206 result.append("<!--");
207 } else if (element->hasTagName(HTMLNames::htmlTag)) {
208 // Add MOTW (Mark of the Web) declaration before html tag.
209 // See http://msdn2.microsoft.com/en-us/library/ms537628(VS.85).aspx.
210 result.append(String::format("\n<!-- saved from url=(%04d)%s -->\n",
211 static_cast<int>(m_document->url().string().utf8().length()),
212 m_document->url().string().utf8().data()));
213 }
214
215 SerializerMarkupAccumulator::appendElement(result, element, namespaces);
216
217 if (element->hasTagName(HTMLNames::baseTag)) {
218 // Comment the BASE tag when serializing dom.
219 result.appendLiteral("-->");
220
221 // FIXME: Refactor MarkupAccumulator so it is easier to append an elemen t like this, without special cases for XHTML
222 // Append a new base tag declaration.
223 result.appendLiteral("<base href=\".\"");
224 if (!m_document->baseTarget().isEmpty()) {
225 result.appendLiteral(" target=\"");
226 result.append(m_document->baseTarget());
227 result.append('"');
228 }
229 if (m_document->isXHTMLDocument())
230 result.appendLiteral(" />");
231 else
232 result.appendLiteral(">");
233 }
234 }
235 void LinkChangeSerializerMarkupAccumulator::appendAttribute(StringBuilder& resul t, Element* element, const Attribute& attribute, Namespaces* namespaces)
236 {
237 if (m_replaceLinks && element->isURLAttribute(attribute)
238 && !element->isJavaScriptURLAttribute(attribute)) {
abarth-chromium 2013/11/15 15:58:51 You can merge these lines. There's no 80 col limi
239
240 String completeURL = m_document->completeURL(attribute.value());
241
242 if (m_replaceLinks->contains(completeURL)) {
243 // FIXME: Refactor MarkupAccumulator so it is easier to append an at tribute like this.
244 result.append(' ');
245 result.append(attribute.name().toString());
246 result.appendLiteral("=\"");
247 if (!m_directoryName.isEmpty()) {
248 result.appendLiteral("./");
249 result.append(m_directoryName);
abarth-chromium 2013/11/15 15:58:51 Do we need to escape the directory name at all?
250 result.append('/');
251 }
252 result.append(m_replaceLinks->get(completeURL));
253 result.appendLiteral("\"");
254 return;
255 }
256 }
257 MarkupAccumulator::appendAttribute(result, element, attribute, namespaces);
258 }
259
260
abarth-chromium 2013/11/15 15:58:51 no need for this blank line
261 PageSerializer::PageSerializer(Vector<SerializedResource>* resources, LinkLocalP athMap* urls, String directory)
262 : m_resources(resources)
263 , m_URLs(urls)
264 , m_directory(directory)
265 , m_blankFrameCounter(0)
266 {
267
abarth-chromium 2013/11/15 15:58:51 ditto
268 }
269
181 void PageSerializer::serialize(Page* page) 270 void PageSerializer::serialize(Page* page)
182 { 271 {
183 serializeFrame(page->mainFrame()); 272 serializeFrame(page->mainFrame());
184 } 273 }
185 274
186 void PageSerializer::serializeFrame(Frame* frame) 275 void PageSerializer::serializeFrame(Frame* frame)
187 { 276 {
188 Document* document = frame->document(); 277 Document* document = frame->document();
189 KURL url = document->url(); 278 KURL url = document->url();
190 if (!url.isValid() || url.isBlankURL()) { 279 if (!url.isValid() || url.isBlankURL()) {
191 // For blank frames we generate a fake URL so they can be referenced by their containing frame. 280 // For blank frames we generate a fake URL so they can be referenced by their containing frame.
192 url = urlForBlankFrame(frame); 281 url = urlForBlankFrame(frame);
193 } 282 }
194 283
195 if (m_resourceURLs.contains(url)) { 284 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 285 // 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 286 // different content. So we should serialize both and somehow rename the frame src in the containing
198 // frame. Arg! 287 // frame. Arg!
199 return; 288 return;
200 } 289 }
201 290
291 // If frame is an image document, add the image and don't continue
292 if (document->isImageDocument()) {
293 ImageDocument* imageDocument = toImageDocument(document);
294 addImageToResources(imageDocument->cachedImage(), imageDocument->imageEl ement()->renderer(), url);
295 return;
296 }
297
202 Vector<Node*> nodes; 298 Vector<Node*> nodes;
203 SerializerMarkupAccumulator accumulator(this, document, &nodes); 299 OwnPtr<SerializerMarkupAccumulator> accumulator;
300 if (m_URLs)
301 accumulator = adoptPtr(new LinkChangeSerializerMarkupAccumulator(this, d ocument, &nodes, m_URLs, m_directory));
302 else
303 accumulator = adoptPtr(new SerializerMarkupAccumulator(this, document, & nodes));
304 String text = accumulator->serializeNodes(document, IncludeNode);
204 WTF::TextEncoding textEncoding(document->charset()); 305 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); 306 CString frameHTML = textEncoding.normalizeAndEncode(text, WTF::EntitiesForUn encodables);
212 m_resources->append(SerializedResource(url, document->suggestedMIMEType(), S haredBuffer::create(frameHTML.data(), frameHTML.length()))); 307 m_resources->append(SerializedResource(url, document->suggestedMIMEType(), S haredBuffer::create(frameHTML.data(), frameHTML.length())));
213 m_resourceURLs.add(url); 308 m_resourceURLs.add(url);
214 309
215 for (Vector<Node*>::iterator iter = nodes.begin(); iter != nodes.end(); ++it er) { 310 for (Vector<Node*>::iterator iter = nodes.begin(); iter != nodes.end(); ++it er) {
216 Node* node = *iter; 311 Node* node = *iter;
217 if (!node->isElementNode()) 312 if (!node->isElementNode())
218 continue; 313 continue;
219 314
220 Element* element = toElement(node); 315 Element* element = toElement(node);
221 // We have to process in-line style as it might contain some resources ( typically background images). 316 // We have to process in-line style as it might contain some resources ( typically background images).
222 if (element->isStyledElement()) 317 if (element->isStyledElement()) {
223 retrieveResourcesForProperties(element->inlineStyle(), document); 318 retrieveResourcesForProperties(element->inlineStyle(), document);
319 retrieveResourcesForProperties(element->presentationAttributeStyle() , document);
320 }
224 321
225 if (element->hasTagName(HTMLNames::imgTag)) { 322 if (element->hasTagName(HTMLNames::imgTag)) {
226 HTMLImageElement* imageElement = toHTMLImageElement(element); 323 HTMLImageElement* imageElement = toHTMLImageElement(element);
227 KURL url = document->completeURL(imageElement->getAttribute(HTMLName s::srcAttr)); 324 KURL url = document->completeURL(imageElement->getAttribute(HTMLName s::srcAttr));
228 ImageResource* cachedImage = imageElement->cachedImage(); 325 ImageResource* cachedImage = imageElement->cachedImage();
229 addImageToResources(cachedImage, imageElement->renderer(), url); 326 addImageToResources(cachedImage, imageElement->renderer(), url);
230 } else if (element->hasTagName(HTMLNames::inputTag)) { 327 } else if (element->hasTagName(HTMLNames::inputTag)) {
231 HTMLInputElement* inputElement = toHTMLInputElement(element); 328 HTMLInputElement* inputElement = toHTMLInputElement(element);
232 if (inputElement->isImageButton() && inputElement->hasImageLoader()) { 329 if (inputElement->isImageButton() && inputElement->hasImageLoader()) {
233 KURL url = inputElement->src(); 330 KURL url = inputElement->src();
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 String mimeType = resource->response().mimeType(); 401 String mimeType = resource->response().mimeType();
305 m_resources->append(SerializedResource(url, mimeType, data)); 402 m_resources->append(SerializedResource(url, mimeType, data));
306 m_resourceURLs.add(url); 403 m_resourceURLs.add(url);
307 } 404 }
308 405
309 void PageSerializer::addImageToResources(ImageResource* image, RenderObject* ima geRenderer, const KURL& url) 406 void PageSerializer::addImageToResources(ImageResource* image, RenderObject* ima geRenderer, const KURL& url)
310 { 407 {
311 if (!shouldAddURL(url)) 408 if (!shouldAddURL(url))
312 return; 409 return;
313 410
314 if (!image || image->image() == Image::nullImage()) 411 if (!image || !image->hasImage() || image->image() == Image::nullImage())
315 return; 412 return;
316 413
317 RefPtr<SharedBuffer> data = imageRenderer ? image->imageForRenderer(imageRen derer)->data() : 0; 414 RefPtr<SharedBuffer> data = imageRenderer ? image->imageForRenderer(imageRen derer)->data() : 0;
318 if (!data) 415 if (!data)
319 data = image->image()->data(); 416 data = image->image()->data();
320 417
321 addToResources(image, data, url); 418 addToResources(image, data, url);
322 } 419 }
323 420
324 void PageSerializer::addFontToResources(FontResource* font) 421 void PageSerializer::addFontToResources(FontResource* font)
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 if (iter != m_blankFrameURLs.end()) 473 if (iter != m_blankFrameURLs.end())
377 return iter->value; 474 return iter->value;
378 String url = "wyciwyg://frame/" + String::number(m_blankFrameCounter++); 475 String url = "wyciwyg://frame/" + String::number(m_blankFrameCounter++);
379 KURL fakeURL(ParsedURLString, url); 476 KURL fakeURL(ParsedURLString, url);
380 m_blankFrameURLs.add(frame, fakeURL); 477 m_blankFrameURLs.add(frame, fakeURL);
381 478
382 return fakeURL; 479 return fakeURL;
383 } 480 }
384 481
385 } 482 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698