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

Side by Side Diff: third_party/WebKit/Source/core/page/PageSerializer.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: Simplified SerializerMarkupAccumulator::appendAttribute. 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) 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 #include "core/css/StylePropertySet.h" 44 #include "core/css/StylePropertySet.h"
45 #include "core/css/StyleRule.h" 45 #include "core/css/StyleRule.h"
46 #include "core/css/StyleSheetContents.h" 46 #include "core/css/StyleSheetContents.h"
47 #include "core/dom/Document.h" 47 #include "core/dom/Document.h"
48 #include "core/dom/Element.h" 48 #include "core/dom/Element.h"
49 #include "core/dom/Text.h" 49 #include "core/dom/Text.h"
50 #include "core/editing/serializers/MarkupAccumulator.h" 50 #include "core/editing/serializers/MarkupAccumulator.h"
51 #include "core/fetch/FontResource.h" 51 #include "core/fetch/FontResource.h"
52 #include "core/fetch/ImageResource.h" 52 #include "core/fetch/ImageResource.h"
53 #include "core/frame/LocalFrame.h" 53 #include "core/frame/LocalFrame.h"
54 #include "core/html/HTMLFrameOwnerElement.h" 54 #include "core/html/HTMLFrameElementBase.h"
55 #include "core/html/HTMLImageElement.h" 55 #include "core/html/HTMLImageElement.h"
56 #include "core/html/HTMLInputElement.h" 56 #include "core/html/HTMLInputElement.h"
57 #include "core/html/HTMLLinkElement.h" 57 #include "core/html/HTMLLinkElement.h"
58 #include "core/html/HTMLMetaElement.h" 58 #include "core/html/HTMLMetaElement.h"
59 #include "core/html/HTMLStyleElement.h" 59 #include "core/html/HTMLStyleElement.h"
60 #include "core/html/ImageDocument.h" 60 #include "core/html/ImageDocument.h"
61 #include "core/html/parser/HTMLParserIdioms.h" 61 #include "core/html/parser/HTMLParserIdioms.h"
62 #include "core/page/Page.h" 62 #include "core/page/Page.h"
63 #include "core/style/StyleFetchedImage.h" 63 #include "core/style/StyleFetchedImage.h"
64 #include "core/style/StyleImage.h" 64 #include "core/style/StyleImage.h"
65 #include "platform/SerializedResource.h" 65 #include "platform/SerializedResource.h"
66 #include "platform/graphics/Image.h" 66 #include "platform/graphics/Image.h"
67 #include "wtf/HashSet.h"
67 #include "wtf/OwnPtr.h" 68 #include "wtf/OwnPtr.h"
68 #include "wtf/text/CString.h" 69 #include "wtf/text/CString.h"
69 #include "wtf/text/StringBuilder.h" 70 #include "wtf/text/StringBuilder.h"
70 #include "wtf/text/TextEncoding.h" 71 #include "wtf/text/TextEncoding.h"
71 #include "wtf/text/WTFString.h" 72 #include "wtf/text/WTFString.h"
72 73
73 namespace blink { 74 namespace blink {
74 75
75 static bool isCharsetSpecifyingNode(const Node& node) 76 static bool isCharsetSpecifyingNode(const Node& node)
76 { 77 {
77 if (!isHTMLMetaElement(node)) 78 if (!isHTMLMetaElement(node))
78 return false; 79 return false;
79 80
80 const HTMLMetaElement& element = toHTMLMetaElement(node); 81 const HTMLMetaElement& element = toHTMLMetaElement(node);
81 HTMLAttributeList attributeList; 82 HTMLAttributeList attributeList;
82 AttributeCollection attributes = element.attributes(); 83 AttributeCollection attributes = element.attributes();
83 for (const Attribute& attr: attributes) { 84 for (const Attribute& attr: attributes) {
84 // FIXME: We should deal appropriately with the attribute if they have a namespace. 85 // FIXME: We should deal appropriately with the attribute if they have a namespace.
85 attributeList.append(std::make_pair(attr.name().localName(), attr.value( ).string())); 86 attributeList.append(std::make_pair(attr.name().localName(), attr.value( ).string()));
86 } 87 }
87 WTF::TextEncoding textEncoding = encodingFromMetaAttributes(attributeList); 88 WTF::TextEncoding textEncoding = encodingFromMetaAttributes(attributeList);
88 return textEncoding.isValid(); 89 return textEncoding.isValid();
89 } 90 }
90 91
91 static bool shouldIgnoreElement(const Element& element) 92 static bool shouldIgnoreElement(const Element& element)
92 { 93 {
93 return isHTMLScriptElement(element) || isHTMLNoScriptElement(element) || isC harsetSpecifyingNode(element); 94 return isHTMLScriptElement(element) || isHTMLNoScriptElement(element) || isC harsetSpecifyingNode(element);
94 } 95 }
95 96
96 static const QualifiedName& frameOwnerURLAttributeName(const HTMLFrameOwnerEleme nt& frameOwner)
97 {
98 // FIXME: We should support all frame owners including applets.
99 return isHTMLObjectElement(frameOwner) ? HTMLNames::dataAttr : HTMLNames::sr cAttr;
100 }
101
102 class SerializerMarkupAccumulator : public MarkupAccumulator { 97 class SerializerMarkupAccumulator : public MarkupAccumulator {
103 STACK_ALLOCATED(); 98 STACK_ALLOCATED();
104 public: 99 public:
105 SerializerMarkupAccumulator(PageSerializer*, const Document&, WillBeHeapVect or<RawPtrWillBeMember<Node>>&); 100 SerializerMarkupAccumulator(PageSerializer*, const Document&, WillBeHeapVect or<RawPtrWillBeMember<Node>>&);
106 ~SerializerMarkupAccumulator() override; 101 ~SerializerMarkupAccumulator() override;
107 102
108 protected: 103 protected:
109 void appendText(StringBuilder& out, Text&) override; 104 void appendText(StringBuilder& out, Text&) override;
110 bool shouldIgnoreAttribute(const Attribute&) override; 105 bool shouldIgnoreAttribute(const Attribute&) override;
111 void appendElement(StringBuilder& out, Element&, Namespaces*) override; 106 void appendElement(StringBuilder& out, Element&, Namespaces*) override;
112 void appendCustomAttributes(StringBuilder& out, const Element&, Namespaces*) override; 107 void appendAttribute(StringBuilder& out, const Element&, const Attribute&, N amespaces*) override;
113 void appendStartTag(Node&, Namespaces* = nullptr) override; 108 void appendStartTag(Node&, Namespaces* = nullptr) override;
114 void appendEndTag(const Element&) override; 109 void appendEndTag(const Element&) override;
115 110
116 const Document& document(); 111 private:
112 void appendAttributeValue(StringBuilder& out, const String& attributeValue);
113 void appendRewrittenAttribute(
114 StringBuilder& out,
115 const Element&,
116 const String& attributeName,
117 const String& attributeValue);
117 118
118 private:
119 PageSerializer* m_serializer; 119 PageSerializer* m_serializer;
120 RawPtrWillBeMember<const Document> m_document; 120 RawPtrWillBeMember<const Document> m_document;
121 121
122 // FIXME: |PageSerializer| uses |m_nodes| for collecting nodes in document 122 // FIXME: |PageSerializer| uses |m_nodes| for collecting nodes in document
123 // included into serialized text then extracts image, object, etc. The size 123 // included into serialized text then extracts image, object, etc. The size
124 // of this vector isn't small for large document. It is better to use 124 // of this vector isn't small for large document. It is better to use
125 // callback like functionality. 125 // callback like functionality.
126 WillBeHeapVector<RawPtrWillBeMember<Node>>& m_nodes; 126 WillBeHeapVector<RawPtrWillBeMember<Node>>& m_nodes;
127
128 // Elements with links rewritten via appendAttribute method.
129 HashSet<const Element*> m_elementsWithRewrittenLinks;
127 }; 130 };
128 131
129 SerializerMarkupAccumulator::SerializerMarkupAccumulator(PageSerializer* seriali zer, const Document& document, WillBeHeapVector<RawPtrWillBeMember<Node>>& nodes ) 132 SerializerMarkupAccumulator::SerializerMarkupAccumulator(PageSerializer* seriali zer, const Document& document, WillBeHeapVector<RawPtrWillBeMember<Node>>& nodes )
130 : MarkupAccumulator(ResolveAllURLs) 133 : MarkupAccumulator(ResolveAllURLs)
131 , m_serializer(serializer) 134 , m_serializer(serializer)
132 , m_document(&document) 135 , m_document(&document)
133 , m_nodes(nodes) 136 , m_nodes(nodes)
134 { 137 {
135 } 138 }
136 139
(...skipping 18 matching lines...) Expand all
155 } 158 }
156 159
157 void SerializerMarkupAccumulator::appendElement(StringBuilder& result, Element& element, Namespaces* namespaces) 160 void SerializerMarkupAccumulator::appendElement(StringBuilder& result, Element& element, Namespaces* namespaces)
158 { 161 {
159 if (!shouldIgnoreElement(element)) 162 if (!shouldIgnoreElement(element))
160 MarkupAccumulator::appendElement(result, element, namespaces); 163 MarkupAccumulator::appendElement(result, element, namespaces);
161 164
162 // TODO(tiger): Refactor MarkupAccumulator so it is easier to append an elem ent like this, without special cases for XHTML 165 // TODO(tiger): Refactor MarkupAccumulator so it is easier to append an elem ent like this, without special cases for XHTML
163 if (isHTMLHeadElement(element)) { 166 if (isHTMLHeadElement(element)) {
164 result.appendLiteral("<meta http-equiv=\"Content-Type\" content=\""); 167 result.appendLiteral("<meta http-equiv=\"Content-Type\" content=\"");
165 MarkupFormatter::appendAttributeValue(result, m_document->suggestedMIMET ype(), m_document->isHTMLDocument()); 168 appendAttributeValue(result, m_document->suggestedMIMEType());
166 result.appendLiteral("; charset="); 169 result.appendLiteral("; charset=");
167 MarkupFormatter::appendAttributeValue(result, m_document->characterSet() , m_document->isHTMLDocument()); 170 appendAttributeValue(result, m_document->characterSet());
168 if (m_document->isXHTMLDocument()) 171 if (m_document->isXHTMLDocument())
169 result.appendLiteral("\" />"); 172 result.appendLiteral("\" />");
170 else 173 else
171 result.appendLiteral("\">"); 174 result.appendLiteral("\">");
172 } 175 }
173 176
174 // FIXME: For object (plugins) tags and video tag we could replace them by a n image of their current contents. 177 // FIXME: For object (plugins) tags and video tag we could replace them by a n image of their current contents.
175 } 178 }
176 179
177 void SerializerMarkupAccumulator::appendCustomAttributes(StringBuilder& result, const Element& element, Namespaces* namespaces) 180 void SerializerMarkupAccumulator::appendAttribute(
181 StringBuilder& out,
182 const Element& element,
183 const Attribute& attribute,
184 Namespaces* namespaces)
178 { 185 {
179 if (!element.isFrameOwnerElement()) 186 // Check if the delegate wants to rewrite the attribute.
187 PageSerializer::Delegate* delegate = m_serializer->delegate();
188 String newValue = delegate ? delegate->rewriteLink(element) : String();
189 if (newValue.isNull()) {
190 // Fallback to appending the original attribute.
191 MarkupAccumulator::appendAttribute(out, element, attribute, namespaces);
180 return; 192 return;
193 }
181 194
182 const HTMLFrameOwnerElement& frameOwner = toHTMLFrameOwnerElement(element); 195 if (element.hasLegalLinkAttribute(attribute.name())) {
yosin_UTC9 2015/11/25 01:21:55 nit: early return style is preferred to get rid of
Łukasz Anforowicz 2015/11/25 17:19:18 Done.
183 Frame* frame = frameOwner.contentFrame(); 196 // Rewrite element links.
184 // FIXME: RemoteFrames not currently supported here. 197 appendRewrittenAttribute(out, element, attribute.name().toString(), newV alue);
185 if (!frame || !frame->isLocalFrame()) 198 } else if (isHTMLFrameElementBase(&element) && attribute.name() == HTMLNames ::srcdocAttr) {
186 return; 199 // Emit src instead of srcdoc attribute for frame elements.
187 200 appendRewrittenAttribute(out, element, HTMLNames::srcAttr.localName(), n ewValue);
188 KURL url = toLocalFrame(frame)->document()->url(); 201 }
189 if (url.isValid() && !url.protocolIsAbout())
190 return;
191
192 // We need to give a fake location to blank frames so they can be referenced by the serialized frame.
193 url = m_serializer->urlForBlankFrame(*toLocalFrame(frame));
194 appendAttribute(result, element, Attribute(frameOwnerURLAttributeName(frameO wner), AtomicString(url.string())), namespaces);
195 } 202 }
196 203
197 void SerializerMarkupAccumulator::appendStartTag(Node& node, Namespaces* namespa ces) 204 void SerializerMarkupAccumulator::appendStartTag(Node& node, Namespaces* namespa ces)
198 { 205 {
199 MarkupAccumulator::appendStartTag(node, namespaces); 206 MarkupAccumulator::appendStartTag(node, namespaces);
200 m_nodes.append(&node); 207 m_nodes.append(&node);
201 } 208 }
202 209
203 void SerializerMarkupAccumulator::appendEndTag(const Element& element) 210 void SerializerMarkupAccumulator::appendEndTag(const Element& element)
204 { 211 {
205 if (!shouldIgnoreElement(element)) 212 if (!shouldIgnoreElement(element))
206 MarkupAccumulator::appendEndTag(element); 213 MarkupAccumulator::appendEndTag(element);
207 } 214 }
208 215
209 const Document& SerializerMarkupAccumulator::document() 216 void SerializerMarkupAccumulator::appendAttributeValue(
217 StringBuilder& out,
218 const String& attributeValue)
210 { 219 {
211 return *m_document; 220 MarkupFormatter::appendAttributeValue(out, attributeValue, m_document->isHTM LDocument());
221 }
222
223 void SerializerMarkupAccumulator::appendRewrittenAttribute(
224 StringBuilder& out,
225 const Element& element,
226 const String& attributeName,
227 const String& attributeValue)
228 {
229 if (m_elementsWithRewrittenLinks.contains(&element))
230 return;
231 m_elementsWithRewrittenLinks.add(&element);
232
233 // Append the rewritten attribute.
234 // TODO(tiger): Refactor MarkupAccumulator so it is easier to append an attr ibute like this.
235 out.append(' ');
236 out.append(attributeName);
237 out.appendLiteral("=\"");
238 appendAttributeValue(out, attributeValue);
239 out.appendLiteral("\"");
212 } 240 }
213 241
214 // TODO(tiger): Right now there is no support for rewriting URLs inside CSS 242 // TODO(tiger): Right now there is no support for rewriting URLs inside CSS
215 // documents which leads to bugs like <https://crbug.com/251898>. Not being 243 // documents which leads to bugs like <https://crbug.com/251898>. Not being
216 // able to rewrite URLs inside CSS documents means that resources imported from 244 // able to rewrite URLs inside CSS documents means that resources imported from
217 // url(...) statements in CSS might not work when rewriting links for the 245 // url(...) statements in CSS might not work when rewriting links for the
218 // "Webpage, Complete" method of saving a page. It will take some work but it 246 // "Webpage, Complete" method of saving a page. It will take some work but it
219 // needs to be done if we want to continue to support non-MHTML saved pages. 247 // needs to be done if we want to continue to support non-MHTML saved pages.
220 //
221 // Once that is fixed it would make sense to make link rewriting a bit more
222 // general. A new method, String& rewriteURL(String&) or similar, could be added
223 // to PageSerializer.Delegate that would allow clients to control this. Some of
224 // the change link logic could be moved back to WebPageSerializer.
225 //
226 // The remaining code in LinkChangeSerializerMarkupAccumulator could probably
227 // be merged back into SerializerMarkupAccumulator with additional methods in
228 // PageSerializer.Delegate to control MOTW and Base tag rewrite.
229 class LinkChangeSerializerMarkupAccumulator final : public SerializerMarkupAccum ulator {
230 STACK_ALLOCATED();
231 public:
232 LinkChangeSerializerMarkupAccumulator(PageSerializer*, const Document&, Will BeHeapVector<RawPtrWillBeMember<Node>>&, HashMap<String, String>& rewriteURLs, c onst String& rewriteFolder);
233 248
234 private: 249 PageSerializer::PageSerializer(
235 void appendElement(StringBuilder&, Element&, Namespaces*) override; 250 Vector<SerializedResource>* resources,
236 void appendAttribute(StringBuilder&, const Element&, const Attribute&, Names paces*) override; 251 Delegate* delegate)
237
238 // m_rewriteURLs include all pairs of local resource paths and corresponding original links.
239 HashMap<String, String> m_rewriteURLs;
240 String m_rewriteFolder;
241 };
242
243 LinkChangeSerializerMarkupAccumulator::LinkChangeSerializerMarkupAccumulator(Pag eSerializer* serializer, const Document& document, WillBeHeapVector<RawPtrWillBe Member<Node>>& nodes, HashMap<String, String>& rewriteURLs, const String& rewrit eFolder)
244 : SerializerMarkupAccumulator(serializer, document, nodes)
245 , m_rewriteURLs(rewriteURLs)
246 , m_rewriteFolder(rewriteFolder)
247 {
248 }
249
250 void LinkChangeSerializerMarkupAccumulator::appendElement(StringBuilder& result, Element& element, Namespaces* namespaces)
251 {
252 if (element.hasTagName(HTMLNames::htmlTag)) {
253 // Add MOTW (Mark of the Web) declaration before html tag.
254 // See http://msdn2.microsoft.com/en-us/library/ms537628(VS.85).aspx.
255 result.append('\n');
256 MarkupFormatter::appendComment(result, PageSerializer::markOfTheWebDecla ration(document().url()));
257 result.append('\n');
258 }
259
260 if (element.hasTagName(HTMLNames::baseTag)) {
261 // TODO(tiger): Refactor MarkupAccumulator so it is easier to append an element like this, without special cases for XHTML
262 // Append a new base tag declaration.
263 result.appendLiteral("<base href=\".\"");
264 if (!document().baseTarget().isEmpty()) {
265 result.appendLiteral(" target=\"");
266 MarkupFormatter::appendAttributeValue(result, document().baseTarget( ), document().isHTMLDocument());
267 result.append('"');
268 }
269 if (document().isXHTMLDocument())
270 result.appendLiteral(" />");
271 else
272 result.appendLiteral(">");
273 } else {
274 SerializerMarkupAccumulator::appendElement(result, element, namespaces);
275 }
276 }
277
278 void LinkChangeSerializerMarkupAccumulator::appendAttribute(StringBuilder& resul t, const Element& element, const Attribute& attribute, Namespaces* namespaces)
279 {
280 if (!m_rewriteURLs.isEmpty() && element.isURLAttribute(attribute)) {
281
282 String completeURL = document().completeURL(attribute.value());
283
284 if (m_rewriteURLs.contains(completeURL)) {
285 // TODO(tiger): Refactor MarkupAccumulator so it is easier to append an attribute like this.
286 result.append(' ');
287 result.append(attribute.name().toString());
288 result.appendLiteral("=\"");
289 if (!m_rewriteFolder.isEmpty())
290 MarkupFormatter::appendAttributeValue(result, m_rewriteFolder + "/", document().isHTMLDocument());
291 MarkupFormatter::appendAttributeValue(result, m_rewriteURLs.get(comp leteURL), document().isHTMLDocument());
292 result.appendLiteral("\"");
293 return;
294 }
295 }
296 MarkupAccumulator::appendAttribute(result, element, attribute, namespaces);
297 }
298
299
300 PageSerializer::PageSerializer(Vector<SerializedResource>* resources, PassOwnPtr <Delegate> delegate)
301 : m_resources(resources) 252 : m_resources(resources)
302 , m_blankFrameCounter(0)
303 , m_delegate(delegate) 253 , m_delegate(delegate)
304 { 254 {
305 } 255 }
306 256
307 void PageSerializer::serializeFrame(const LocalFrame& frame) 257 void PageSerializer::serializeFrame(const LocalFrame& frame)
308 { 258 {
309 ASSERT(frame.document()); 259 ASSERT(frame.document());
310 Document& document = *frame.document(); 260 Document& document = *frame.document();
311 KURL url = document.url(); 261 KURL url = document.url();
312 // FIXME: This probably wants isAboutBlankURL? to exclude other about: urls (like about:srcdoc)?
313 if (!url.isValid() || url.protocolIsAbout()) {
314 // For blank frames we generate a fake URL so they can be referenced by their containing frame.
315 url = urlForBlankFrame(frame);
316 }
317
318 if (m_resourceURLs.contains(url)) {
319 // FIXME: We could have 2 frame with the same URL but which were dynamic ally changed and have now
320 // different content. So we should serialize both and somehow rename the frame src in the containing
321 // frame. Arg!
322 return;
323 }
324 262
325 // If frame is an image document, add the image and don't continue 263 // If frame is an image document, add the image and don't continue
326 if (document.isImageDocument()) { 264 if (document.isImageDocument()) {
327 ImageDocument& imageDocument = toImageDocument(document); 265 ImageDocument& imageDocument = toImageDocument(document);
328 addImageToResources(imageDocument.cachedImage(), url); 266 addImageToResources(imageDocument.cachedImage(), url);
329 return; 267 return;
330 } 268 }
331 269
332 WillBeHeapVector<RawPtrWillBeMember<Node>> serializedNodes; 270 WillBeHeapVector<RawPtrWillBeMember<Node>> serializedNodes;
333 String text; 271 SerializerMarkupAccumulator accumulator(this, document, serializedNodes);
334 if (!m_rewriteURLs.isEmpty()) { 272 String text = serializeNodes<EditingStrategy>(accumulator, document, Include Node);
335 LinkChangeSerializerMarkupAccumulator accumulator(this, document, serial izedNodes, m_rewriteURLs, m_rewriteFolder);
336 text = serializeNodes<EditingStrategy>(accumulator, document, IncludeNod e);
337 } else {
338 SerializerMarkupAccumulator accumulator(this, document, serializedNodes) ;
339 text = serializeNodes<EditingStrategy>(accumulator, document, IncludeNod e);
340 }
341 273
342 CString frameHTML = document.encoding().encode(text, WTF::EntitiesForUnencod ables); 274 CString frameHTML = document.encoding().encode(text, WTF::EntitiesForUnencod ables);
343 m_resources->append(SerializedResource(url, document.suggestedMIMEType(), Sh aredBuffer::create(frameHTML.data(), frameHTML.length()))); 275 m_resources->append(SerializedResource(url, document.suggestedMIMEType(), Sh aredBuffer::create(frameHTML.data(), frameHTML.length())));
344 m_resourceURLs.add(url); 276 m_resourceURLs.add(url);
345 277
346 for (Node* node: serializedNodes) { 278 for (Node* node: serializedNodes) {
347 ASSERT(node); 279 ASSERT(node);
348 if (!node->isElementNode()) 280 if (!node->isElementNode())
349 continue; 281 continue;
350 282
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 } 464 }
533 465
534 addFontToResources(fontFaceSrcValue->fetch(&document)); 466 addFontToResources(fontFaceSrcValue->fetch(&document));
535 } else if (cssValue->isValueList()) { 467 } else if (cssValue->isValueList()) {
536 CSSValueList* cssValueList = toCSSValueList(cssValue); 468 CSSValueList* cssValueList = toCSSValueList(cssValue);
537 for (unsigned i = 0; i < cssValueList->length(); i++) 469 for (unsigned i = 0; i < cssValueList->length(); i++)
538 retrieveResourcesForCSSValue(cssValueList->item(i), document); 470 retrieveResourcesForCSSValue(cssValueList->item(i), document);
539 } 471 }
540 } 472 }
541 473
542 void PageSerializer::registerRewriteURL(const String& from, const String& to)
543 {
544 m_rewriteURLs.set(from, to);
545 }
546
547 void PageSerializer::setRewriteURLFolder(const String& rewriteFolder)
548 {
549 m_rewriteFolder = rewriteFolder;
550 }
551
552 KURL PageSerializer::urlForBlankFrame(const LocalFrame& frame)
553 {
554 BlankFrameURLMap::iterator iter = m_blankFrameURLs.find(&frame);
555 if (iter != m_blankFrameURLs.end())
556 return iter->value;
557 String url = "wyciwyg://frame/" + String::number(m_blankFrameCounter++);
558 KURL fakeURL(ParsedURLString, url);
559 m_blankFrameURLs.add(&frame, fakeURL);
560
561 return fakeURL;
562 }
563
564 PageSerializer::Delegate* PageSerializer::delegate() 474 PageSerializer::Delegate* PageSerializer::delegate()
565 { 475 {
566 return m_delegate.get(); 476 return m_delegate;
567 } 477 }
568 478
569 // Returns MOTW (Mark of the Web) declaration before html tag which is in 479 // Returns MOTW (Mark of the Web) declaration before html tag which is in
570 // HTML comment, e.g. "<!-- saved from url=(%04d)%s -->" 480 // HTML comment, e.g. "<!-- saved from url=(%04d)%s -->"
571 // See http://msdn2.microsoft.com/en-us/library/ms537628(VS.85).aspx. 481 // See http://msdn2.microsoft.com/en-us/library/ms537628(VS.85).aspx.
572 String PageSerializer::markOfTheWebDeclaration(const KURL& url) 482 String PageSerializer::markOfTheWebDeclaration(const KURL& url)
573 { 483 {
574 StringBuilder builder; 484 StringBuilder builder;
575 bool emitsMinus = false; 485 bool emitsMinus = false;
576 CString orignalUrl = url.string().ascii(); 486 CString orignalUrl = url.string().ascii();
577 for (const char* string = orignalUrl.data(); *string; ++string) { 487 for (const char* string = orignalUrl.data(); *string; ++string) {
578 const char ch = *string; 488 const char ch = *string;
579 if (ch == '-' && emitsMinus) { 489 if (ch == '-' && emitsMinus) {
580 builder.append("%2D"); 490 builder.append("%2D");
581 emitsMinus = false; 491 emitsMinus = false;
582 continue; 492 continue;
583 } 493 }
584 emitsMinus = ch == '-'; 494 emitsMinus = ch == '-';
585 builder.append(ch); 495 builder.append(ch);
586 } 496 }
587 CString escapedUrl = builder.toString().ascii(); 497 CString escapedUrl = builder.toString().ascii();
588 return String::format("saved from url=(%04d)%s", static_cast<int>(escapedUrl .length()), escapedUrl.data()); 498 return String::format("saved from url=(%04d)%s", static_cast<int>(escapedUrl .length()), escapedUrl.data());
589 } 499 }
590 500
591 } // namespace blink 501 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698