OLD | NEW |
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 14 matching lines...) Expand all Loading... |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #include "config.h" | 31 #include "config.h" |
32 #include "core/page/PageSerializer.h" | 32 #include "core/page/PageSerializer.h" |
33 | 33 |
34 #include "HTMLNames.h" | 34 #include "HTMLNames.h" |
| 35 #include "core/css/CSSFontFaceRule.h" |
| 36 #include "core/css/CSSFontFaceSrcValue.h" |
35 #include "core/css/CSSImageValue.h" | 37 #include "core/css/CSSImageValue.h" |
36 #include "core/css/CSSImportRule.h" | 38 #include "core/css/CSSImportRule.h" |
| 39 #include "core/css/CSSStyleDeclaration.h" |
37 #include "core/css/CSSStyleRule.h" | 40 #include "core/css/CSSStyleRule.h" |
| 41 #include "core/css/CSSValueList.h" |
38 #include "core/css/StylePropertySet.h" | 42 #include "core/css/StylePropertySet.h" |
39 #include "core/css/StyleRule.h" | 43 #include "core/css/StyleRule.h" |
40 #include "core/css/StyleSheetContents.h" | 44 #include "core/css/StyleSheetContents.h" |
41 #include "core/dom/Document.h" | 45 #include "core/dom/Document.h" |
42 #include "core/dom/Element.h" | 46 #include "core/dom/Element.h" |
43 #include "core/dom/Text.h" | 47 #include "core/dom/Text.h" |
44 #include "core/editing/MarkupAccumulator.h" | 48 #include "core/editing/MarkupAccumulator.h" |
| 49 #include "core/fetch/FontResource.h" |
45 #include "core/fetch/ImageResource.h" | 50 #include "core/fetch/ImageResource.h" |
46 #include "core/html/HTMLFrameOwnerElement.h" | 51 #include "core/html/HTMLFrameOwnerElement.h" |
47 #include "core/html/HTMLImageElement.h" | 52 #include "core/html/HTMLImageElement.h" |
48 #include "core/html/HTMLInputElement.h" | 53 #include "core/html/HTMLInputElement.h" |
49 #include "core/html/HTMLLinkElement.h" | 54 #include "core/html/HTMLLinkElement.h" |
50 #include "core/html/HTMLStyleElement.h" | 55 #include "core/html/HTMLStyleElement.h" |
51 #include "core/html/parser/HTMLMetaCharsetParser.h" | 56 #include "core/html/parser/HTMLMetaCharsetParser.h" |
52 #include "core/page/Frame.h" | 57 #include "core/page/Frame.h" |
53 #include "core/page/Page.h" | 58 #include "core/page/Page.h" |
54 #include "core/platform/SerializedResource.h" | 59 #include "core/platform/SerializedResource.h" |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 CSSRule* rule = styleSheet->item(i); | 259 CSSRule* rule = styleSheet->item(i); |
255 String itemText = rule->cssText(); | 260 String itemText = rule->cssText(); |
256 if (!itemText.isEmpty()) { | 261 if (!itemText.isEmpty()) { |
257 cssText.append(itemText); | 262 cssText.append(itemText); |
258 if (i < styleSheet->length() - 1) | 263 if (i < styleSheet->length() - 1) |
259 cssText.append("\n\n"); | 264 cssText.append("\n\n"); |
260 } | 265 } |
261 Document* document = styleSheet->ownerDocument(); | 266 Document* document = styleSheet->ownerDocument(); |
262 // Some rules have resources associated with them that we need to retrie
ve. | 267 // Some rules have resources associated with them that we need to retrie
ve. |
263 if (rule->type() == CSSRule::IMPORT_RULE) { | 268 if (rule->type() == CSSRule::IMPORT_RULE) { |
264 CSSImportRule* importRule = static_cast<CSSImportRule*>(rule); | 269 CSSImportRule* importRule = toCSSImportRule(rule); |
265 KURL importURL = document->completeURL(importRule->href()); | 270 KURL importURL = document->completeURL(importRule->href()); |
266 if (m_resourceURLs.contains(importURL)) | 271 if (m_resourceURLs.contains(importURL)) |
267 continue; | 272 continue; |
268 serializeCSSStyleSheet(importRule->styleSheet(), importURL); | 273 serializeCSSStyleSheet(importRule->styleSheet(), importURL); |
269 } else if (rule->type() == CSSRule::FONT_FACE_RULE) { | 274 } else if (rule->type() == CSSRule::FONT_FACE_RULE) { |
270 // FIXME: Add support for font face rule. It is not clear to me at t
his point if the actual otf/eot file can | 275 retrieveResourcesForProperties(toCSSFontFaceRule(rule)->styleRule()-
>properties(), document); |
271 // be retrieved from the CSSFontFaceRule object. | |
272 } else if (rule->type() == CSSRule::STYLE_RULE) { | 276 } else if (rule->type() == CSSRule::STYLE_RULE) { |
273 retrieveResourcesForRule(static_cast<CSSStyleRule*>(rule)->styleRule
(), document); | 277 retrieveResourcesForProperties(toCSSStyleRule(rule)->styleRule()->pr
operties(), document); |
274 } | 278 } |
275 } | 279 } |
276 | 280 |
277 if (url.isValid() && !m_resourceURLs.contains(url)) { | 281 if (url.isValid() && !m_resourceURLs.contains(url)) { |
278 // FIXME: We should check whether a charset has been specified and if no
ne was found add one. | 282 // FIXME: We should check whether a charset has been specified and if no
ne was found add one. |
279 WTF::TextEncoding textEncoding(styleSheet->contents()->charset()); | 283 WTF::TextEncoding textEncoding(styleSheet->contents()->charset()); |
280 ASSERT(textEncoding.isValid()); | 284 ASSERT(textEncoding.isValid()); |
281 String textString = cssText.toString(); | 285 String textString = cssText.toString(); |
282 CString text = textEncoding.normalizeAndEncode(textString, WTF::Entities
ForUnencodables); | 286 CString text = textEncoding.normalizeAndEncode(textString, WTF::Entities
ForUnencodables); |
283 m_resources->append(SerializedResource(url, String("text/css"), SharedBu
ffer::create(text.data(), text.length()))); | 287 m_resources->append(SerializedResource(url, String("text/css"), SharedBu
ffer::create(text.data(), text.length()))); |
284 m_resourceURLs.add(url); | 288 m_resourceURLs.add(url); |
285 } | 289 } |
286 } | 290 } |
287 | 291 |
| 292 bool PageSerializer::shouldAddURL(const KURL& url) |
| 293 { |
| 294 return url.isValid() && !m_resourceURLs.contains(url) && !url.protocolIsData
(); |
| 295 } |
| 296 |
| 297 void PageSerializer::addToResources(Resource* resource, PassRefPtr<SharedBuffer>
data, const KURL& url) |
| 298 { |
| 299 if (!data) { |
| 300 LOG_ERROR("No data for resource %s", url.string().utf8().data()); |
| 301 return; |
| 302 } |
| 303 |
| 304 String mimeType = resource->response().mimeType(); |
| 305 m_resources->append(SerializedResource(url, mimeType, data)); |
| 306 m_resourceURLs.add(url); |
| 307 } |
| 308 |
288 void PageSerializer::addImageToResources(ImageResource* image, RenderObject* ima
geRenderer, const KURL& url) | 309 void PageSerializer::addImageToResources(ImageResource* image, RenderObject* ima
geRenderer, const KURL& url) |
289 { | 310 { |
290 if (!url.isValid() || m_resourceURLs.contains(url) || url.protocolIsData()) | 311 if (!shouldAddURL(url)) |
291 return; | 312 return; |
292 | 313 |
293 if (!image || image->image() == Image::nullImage()) | 314 if (!image || image->image() == Image::nullImage()) |
294 return; | 315 return; |
295 | 316 |
296 RefPtr<SharedBuffer> data = imageRenderer ? image->imageForRenderer(imageRen
derer)->data() : 0; | 317 RefPtr<SharedBuffer> data = imageRenderer ? image->imageForRenderer(imageRen
derer)->data() : 0; |
297 if (!data) | 318 if (!data) |
298 data = image->image()->data(); | 319 data = image->image()->data(); |
299 | 320 |
300 if (!data) { | 321 addToResources(image, data, url); |
301 LOG_ERROR("No data for image %s", url.string().utf8().data()); | 322 } |
| 323 |
| 324 void PageSerializer::addFontToResources(FontResource* font) |
| 325 { |
| 326 if (!font || !shouldAddURL(font->url()) || !font->isLoaded() || !font->resou
rceBuffer()) { |
302 return; | 327 return; |
303 } | 328 } |
| 329 RefPtr<SharedBuffer> data(font->resourceBuffer()); |
304 | 330 |
305 String mimeType = image->response().mimeType(); | 331 addToResources(font, data, font->url()); |
306 m_resources->append(SerializedResource(url, mimeType, data)); | |
307 m_resourceURLs.add(url); | |
308 } | |
309 | |
310 void PageSerializer::retrieveResourcesForRule(StyleRule* rule, Document* documen
t) | |
311 { | |
312 retrieveResourcesForProperties(rule->properties(), document); | |
313 } | 332 } |
314 | 333 |
315 void PageSerializer::retrieveResourcesForProperties(const StylePropertySet* styl
eDeclaration, Document* document) | 334 void PageSerializer::retrieveResourcesForProperties(const StylePropertySet* styl
eDeclaration, Document* document) |
316 { | 335 { |
317 if (!styleDeclaration) | 336 if (!styleDeclaration) |
318 return; | 337 return; |
319 | 338 |
320 // The background-image and list-style-image (for ul or ol) are the CSS prop
erties | 339 // The background-image and list-style-image (for ul or ol) are the CSS prop
erties |
321 // that make use of images. We iterate to make sure we include any other | 340 // that make use of images. We iterate to make sure we include any other |
322 // image properties there might be. | 341 // image properties there might be. |
323 unsigned propertyCount = styleDeclaration->propertyCount(); | 342 unsigned propertyCount = styleDeclaration->propertyCount(); |
324 for (unsigned i = 0; i < propertyCount; ++i) { | 343 for (unsigned i = 0; i < propertyCount; ++i) { |
325 RefPtr<CSSValue> cssValue = styleDeclaration->propertyAt(i).value(); | 344 RefPtr<CSSValue> cssValue = styleDeclaration->propertyAt(i).value(); |
326 if (!cssValue->isImageValue()) | 345 retrieveResourcesForCSSValue(cssValue.get(), document); |
327 continue; | 346 } |
| 347 } |
328 | 348 |
329 CSSImageValue* imageValue = toCSSImageValue(cssValue.get()); | 349 void PageSerializer::retrieveResourcesForCSSValue(CSSValue* cssValue, Document*
document) |
| 350 { |
| 351 if (cssValue->isImageValue()) { |
| 352 CSSImageValue* imageValue = toCSSImageValue(cssValue); |
330 StyleImage* styleImage = imageValue->cachedOrPendingImage(); | 353 StyleImage* styleImage = imageValue->cachedOrPendingImage(); |
331 // Non cached-images are just place-holders and do not contain data. | 354 // Non cached-images are just place-holders and do not contain data. |
332 if (!styleImage || !styleImage->isImageResource()) | 355 if (!styleImage || !styleImage->isImageResource()) |
333 continue; | 356 return; |
334 | 357 |
335 ImageResource* image = static_cast<StyleFetchedImage*>(styleImage)->cach
edImage(); | 358 addImageToResources(styleImage->cachedImage(), 0, styleImage->cachedImag
e()->url()); |
336 addImageToResources(image, 0, image->url()); | 359 } else if (cssValue->isFontFaceSrcValue()) { |
| 360 CSSFontFaceSrcValue* fontFaceSrcValue = toCSSFontFaceSrcValue(cssValue); |
| 361 if (fontFaceSrcValue->isLocal()) { |
| 362 return; |
| 363 } |
| 364 |
| 365 addFontToResources(fontFaceSrcValue->fetch(document)); |
| 366 } else if (cssValue->isValueList()) { |
| 367 CSSValueList* cssValueList = toCSSValueList(cssValue); |
| 368 for (unsigned i = 0; i < cssValueList->length(); i++) |
| 369 retrieveResourcesForCSSValue(cssValueList->item(i), document); |
337 } | 370 } |
338 } | 371 } |
339 | 372 |
340 KURL PageSerializer::urlForBlankFrame(Frame* frame) | 373 KURL PageSerializer::urlForBlankFrame(Frame* frame) |
341 { | 374 { |
342 HashMap<Frame*, KURL>::iterator iter = m_blankFrameURLs.find(frame); | 375 HashMap<Frame*, KURL>::iterator iter = m_blankFrameURLs.find(frame); |
343 if (iter != m_blankFrameURLs.end()) | 376 if (iter != m_blankFrameURLs.end()) |
344 return iter->value; | 377 return iter->value; |
345 String url = "wyciwyg://frame/" + String::number(m_blankFrameCounter++); | 378 String url = "wyciwyg://frame/" + String::number(m_blankFrameCounter++); |
346 KURL fakeURL(ParsedURLString, url); | 379 KURL fakeURL(ParsedURLString, url); |
347 m_blankFrameURLs.add(frame, fakeURL); | 380 m_blankFrameURLs.add(frame, fakeURL); |
348 | 381 |
349 return fakeURL; | 382 return fakeURL; |
350 } | 383 } |
351 | 384 |
352 } | 385 } |
OLD | NEW |