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/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: Added a code comment explaining OfflinePageBridgeTest.java changes. 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 do {
yosin_UTC9 2015/11/24 01:59:04 Using |do { ... } while (false)| other than macro
Łukasz Anforowicz 2015/11/24 18:40:42 I simplified that function and got rid of do...whi
180 return; 187 // Check if the delegate wants to rewrite the attribute.
188 PageSerializer::Delegate* delegate = m_serializer->delegate();
189 if (!delegate)
190 break;
191 String newValue = delegate->rewriteLink(element);
192 if (newValue.isNull())
193 break;
181 194
182 const HTMLFrameOwnerElement& frameOwner = toHTMLFrameOwnerElement(element); 195 // Rewrite element links.
183 Frame* frame = frameOwner.contentFrame(); 196 if (element.hasLegalLinkAttribute(attribute.name())) {
184 // FIXME: RemoteFrames not currently supported here. 197 appendRewrittenAttribute(out, element, attribute.name().toString(), newValue);
185 if (!frame || !frame->isLocalFrame()) 198 return;
186 return; 199 }
187 200
188 KURL url = toLocalFrame(frame)->document()->url(); 201 // Emit src instead of srcdoc attribute for frame elements.
189 if (url.isValid() && !url.protocolIsAbout()) 202 if (isHTMLFrameElementBase(&element) && attribute.name() == HTMLNames::s rcdocAttr) {
190 return; 203 appendRewrittenAttribute(out, element, HTMLNames::srcAttr.localName( ), newValue);
204 return;
205 }
206 } while (false);
191 207
192 // We need to give a fake location to blank frames so they can be referenced by the serialized frame. 208 // Fallback to appending the original attribute.
193 url = m_serializer->urlForBlankFrame(*toLocalFrame(frame)); 209 MarkupAccumulator::appendAttribute(out, element, attribute, namespaces);
194 appendAttribute(result, element, Attribute(frameOwnerURLAttributeName(frameO wner), AtomicString(url.string())), namespaces);
195 } 210 }
196 211
197 void SerializerMarkupAccumulator::appendStartTag(Node& node, Namespaces* namespa ces) 212 void SerializerMarkupAccumulator::appendStartTag(Node& node, Namespaces* namespa ces)
198 { 213 {
199 MarkupAccumulator::appendStartTag(node, namespaces); 214 MarkupAccumulator::appendStartTag(node, namespaces);
200 m_nodes.append(&node); 215 m_nodes.append(&node);
201 } 216 }
202 217
203 void SerializerMarkupAccumulator::appendEndTag(const Element& element) 218 void SerializerMarkupAccumulator::appendEndTag(const Element& element)
204 { 219 {
205 if (!shouldIgnoreElement(element)) 220 if (!shouldIgnoreElement(element))
206 MarkupAccumulator::appendEndTag(element); 221 MarkupAccumulator::appendEndTag(element);
207 } 222 }
208 223
209 const Document& SerializerMarkupAccumulator::document() 224 void SerializerMarkupAccumulator::appendAttributeValue(
225 StringBuilder& out,
226 const String& attributeValue)
210 { 227 {
211 return *m_document; 228 MarkupFormatter::appendAttributeValue(out, attributeValue, m_document->isHTM LDocument());
229 }
230
231 void SerializerMarkupAccumulator::appendRewrittenAttribute(
232 StringBuilder& out,
233 const Element& element,
234 const String& attributeName,
235 const String& attributeValue)
236 {
237 if (m_elementsWithRewrittenLinks.contains(&element))
238 return;
239 m_elementsWithRewrittenLinks.add(&element);
240
241 // Append the rewritten attribute.
242 // TODO(tiger): Refactor MarkupAccumulator so it is easier to append an attr ibute like this.
243 out.append(' ');
244 out.append(attributeName);
245 out.appendLiteral("=\"");
246 appendAttributeValue(out, attributeValue);
247 out.appendLiteral("\"");
212 } 248 }
213 249
214 // TODO(tiger): Right now there is no support for rewriting URLs inside CSS 250 // 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 251 // 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 252 // 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 253 // 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 254 // "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. 255 // 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 256
234 private: 257 PageSerializer::PageSerializer(
235 void appendElement(StringBuilder&, Element&, Namespaces*) override; 258 Vector<SerializedResource>* resources,
236 void appendAttribute(StringBuilder&, const Element&, const Attribute&, Names paces*) override; 259 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) 260 : m_resources(resources)
302 , m_blankFrameCounter(0)
303 , m_delegate(delegate) 261 , m_delegate(delegate)
304 { 262 {
305 } 263 }
306 264
307 void PageSerializer::serializeFrame(const LocalFrame& frame) 265 void PageSerializer::serializeFrame(const LocalFrame& frame)
308 { 266 {
309 ASSERT(frame.document()); 267 ASSERT(frame.document());
310 Document& document = *frame.document(); 268 Document& document = *frame.document();
311 KURL url = document.url(); 269 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 270
325 // If frame is an image document, add the image and don't continue 271 // If frame is an image document, add the image and don't continue
326 if (document.isImageDocument()) { 272 if (document.isImageDocument()) {
327 ImageDocument& imageDocument = toImageDocument(document); 273 ImageDocument& imageDocument = toImageDocument(document);
328 addImageToResources(imageDocument.cachedImage(), url); 274 addImageToResources(imageDocument.cachedImage(), url);
329 return; 275 return;
330 } 276 }
331 277
332 WillBeHeapVector<RawPtrWillBeMember<Node>> serializedNodes; 278 WillBeHeapVector<RawPtrWillBeMember<Node>> serializedNodes;
333 String text; 279 SerializerMarkupAccumulator accumulator(this, document, serializedNodes);
334 if (!m_rewriteURLs.isEmpty()) { 280 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 281
342 CString frameHTML = document.encoding().encode(text, WTF::EntitiesForUnencod ables); 282 CString frameHTML = document.encoding().encode(text, WTF::EntitiesForUnencod ables);
343 m_resources->append(SerializedResource(url, document.suggestedMIMEType(), Sh aredBuffer::create(frameHTML.data(), frameHTML.length()))); 283 m_resources->append(SerializedResource(url, document.suggestedMIMEType(), Sh aredBuffer::create(frameHTML.data(), frameHTML.length())));
344 m_resourceURLs.add(url); 284 m_resourceURLs.add(url);
345 285
346 for (Node* node: serializedNodes) { 286 for (Node* node: serializedNodes) {
347 ASSERT(node); 287 ASSERT(node);
348 if (!node->isElementNode()) 288 if (!node->isElementNode())
349 continue; 289 continue;
350 290
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 } 472 }
533 473
534 addFontToResources(fontFaceSrcValue->fetch(&document)); 474 addFontToResources(fontFaceSrcValue->fetch(&document));
535 } else if (cssValue->isValueList()) { 475 } else if (cssValue->isValueList()) {
536 CSSValueList* cssValueList = toCSSValueList(cssValue); 476 CSSValueList* cssValueList = toCSSValueList(cssValue);
537 for (unsigned i = 0; i < cssValueList->length(); i++) 477 for (unsigned i = 0; i < cssValueList->length(); i++)
538 retrieveResourcesForCSSValue(cssValueList->item(i), document); 478 retrieveResourcesForCSSValue(cssValueList->item(i), document);
539 } 479 }
540 } 480 }
541 481
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() 482 PageSerializer::Delegate* PageSerializer::delegate()
565 { 483 {
566 return m_delegate.get(); 484 return m_delegate;
567 } 485 }
568 486
569 // Returns MOTW (Mark of the Web) declaration before html tag which is in 487 // Returns MOTW (Mark of the Web) declaration before html tag which is in
570 // HTML comment, e.g. "<!-- saved from url=(%04d)%s -->" 488 // HTML comment, e.g. "<!-- saved from url=(%04d)%s -->"
571 // See http://msdn2.microsoft.com/en-us/library/ms537628(VS.85).aspx. 489 // See http://msdn2.microsoft.com/en-us/library/ms537628(VS.85).aspx.
572 String PageSerializer::markOfTheWebDeclaration(const KURL& url) 490 String PageSerializer::markOfTheWebDeclaration(const KURL& url)
573 { 491 {
574 StringBuilder builder; 492 StringBuilder builder;
575 bool emitsMinus = false; 493 bool emitsMinus = false;
576 CString orignalUrl = url.string().ascii(); 494 CString orignalUrl = url.string().ascii();
577 for (const char* string = orignalUrl.data(); *string; ++string) { 495 for (const char* string = orignalUrl.data(); *string; ++string) {
578 const char ch = *string; 496 const char ch = *string;
579 if (ch == '-' && emitsMinus) { 497 if (ch == '-' && emitsMinus) {
580 builder.append("%2D"); 498 builder.append("%2D");
581 emitsMinus = false; 499 emitsMinus = false;
582 continue; 500 continue;
583 } 501 }
584 emitsMinus = ch == '-'; 502 emitsMinus = ch == '-';
585 builder.append(ch); 503 builder.append(ch);
586 } 504 }
587 CString escapedUrl = builder.toString().ascii(); 505 CString escapedUrl = builder.toString().ascii();
588 return String::format("saved from url=(%04d)%s", static_cast<int>(escapedUrl .length()), escapedUrl.data()); 506 return String::format("saved from url=(%04d)%s", static_cast<int>(escapedUrl .length()), escapedUrl.data());
589 } 507 }
590 508
591 } // namespace blink 509 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698