| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserv
ed. | 4 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserv
ed. |
| 5 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
| 10 * | 10 * |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 #include "core/frame/Settings.h" | 39 #include "core/frame/Settings.h" |
| 40 #include "core/frame/UseCounter.h" | 40 #include "core/frame/UseCounter.h" |
| 41 #include "core/html/HTMLImageElement.h" | 41 #include "core/html/HTMLImageElement.h" |
| 42 #include "core/html/parser/HTMLParserIdioms.h" | 42 #include "core/html/parser/HTMLParserIdioms.h" |
| 43 #include "core/layout/LayoutImage.h" | 43 #include "core/layout/LayoutImage.h" |
| 44 #include "core/layout/LayoutVideo.h" | 44 #include "core/layout/LayoutVideo.h" |
| 45 #include "core/layout/svg/LayoutSVGImage.h" | 45 #include "core/layout/svg/LayoutSVGImage.h" |
| 46 #include "core/svg/graphics/SVGImage.h" | 46 #include "core/svg/graphics/SVGImage.h" |
| 47 #include "platform/Logging.h" | 47 #include "platform/Logging.h" |
| 48 #include "platform/weborigin/SecurityOrigin.h" | 48 #include "platform/weborigin/SecurityOrigin.h" |
| 49 #include "platform/weborigin/SecurityPolicy.h" |
| 49 #include "public/platform/WebURLRequest.h" | 50 #include "public/platform/WebURLRequest.h" |
| 50 | 51 |
| 51 namespace blink { | 52 namespace blink { |
| 52 | 53 |
| 53 static ImageEventSender& loadEventSender() | 54 static ImageEventSender& loadEventSender() |
| 54 { | 55 { |
| 55 DEFINE_STATIC_LOCAL(ImageEventSender, sender, (EventTypeNames::load)); | 56 DEFINE_STATIC_LOCAL(ImageEventSender, sender, (EventTypeNames::load)); |
| 56 return sender; | 57 return sender; |
| 57 } | 58 } |
| 58 | 59 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 71 { | 72 { |
| 72 ASSERT(loader); | 73 ASSERT(loader); |
| 73 ASSERT(loader->element()); | 74 ASSERT(loader->element()); |
| 74 if (loader->element()->document().frame() && loader->element()->document().f
rame()->script().shouldBypassMainWorldCSP()) | 75 if (loader->element()->document().frame() && loader->element()->document().f
rame()->script().shouldBypassMainWorldCSP()) |
| 75 return ImageLoader::BypassMainWorldCSP; | 76 return ImageLoader::BypassMainWorldCSP; |
| 76 return ImageLoader::DoNotBypassMainWorldCSP; | 77 return ImageLoader::DoNotBypassMainWorldCSP; |
| 77 } | 78 } |
| 78 | 79 |
| 79 class ImageLoader::Task : public WebThread::Task { | 80 class ImageLoader::Task : public WebThread::Task { |
| 80 public: | 81 public: |
| 81 static PassOwnPtr<Task> create(ImageLoader* loader, UpdateFromElementBehavio
r updateBehavior) | 82 static PassOwnPtr<Task> create(ImageLoader* loader, UpdateFromElementBehavio
r updateBehavior, ReferrerPolicy referrerPolicy) |
| 82 { | 83 { |
| 83 return adoptPtr(new Task(loader, updateBehavior)); | 84 return adoptPtr(new Task(loader, updateBehavior, referrerPolicy)); |
| 84 } | 85 } |
| 85 | 86 |
| 86 Task(ImageLoader* loader, UpdateFromElementBehavior updateBehavior) | 87 Task(ImageLoader* loader, UpdateFromElementBehavior updateBehavior, Referrer
Policy referrerPolicy) |
| 87 : m_loader(loader) | 88 : m_loader(loader) |
| 88 , m_shouldBypassMainWorldCSP(shouldBypassMainWorldCSP(loader)) | 89 , m_shouldBypassMainWorldCSP(shouldBypassMainWorldCSP(loader)) |
| 89 , m_updateBehavior(updateBehavior) | 90 , m_updateBehavior(updateBehavior) |
| 90 , m_weakFactory(this) | 91 , m_weakFactory(this) |
| 92 , m_referrerPolicy(referrerPolicy) |
| 91 { | 93 { |
| 92 v8::Isolate* isolate = V8PerIsolateData::mainThreadIsolate(); | 94 v8::Isolate* isolate = V8PerIsolateData::mainThreadIsolate(); |
| 93 v8::HandleScope scope(isolate); | 95 v8::HandleScope scope(isolate); |
| 94 // If we're invoked from C++ without a V8 context on the stack, we shoul
d | 96 // If we're invoked from C++ without a V8 context on the stack, we shoul
d |
| 95 // run the microtask in the context of the element's document's main wor
ld. | 97 // run the microtask in the context of the element's document's main wor
ld. |
| 96 if (ScriptState::hasCurrentScriptState(isolate)) | 98 if (ScriptState::hasCurrentScriptState(isolate)) |
| 97 m_scriptState = ScriptState::current(isolate); | 99 m_scriptState = ScriptState::current(isolate); |
| 98 else | 100 else |
| 99 m_scriptState = ScriptState::forMainWorld(loader->element()->documen
t().frame()); | 101 m_scriptState = ScriptState::forMainWorld(loader->element()->documen
t().frame()); |
| 100 } | 102 } |
| 101 | 103 |
| 102 ~Task() override | 104 ~Task() override |
| 103 { | 105 { |
| 104 } | 106 } |
| 105 | 107 |
| 106 void run() override | 108 void run() override |
| 107 { | 109 { |
| 108 if (!m_loader) | 110 if (!m_loader) |
| 109 return; | 111 return; |
| 110 if (m_scriptState->contextIsValid()) { | 112 if (m_scriptState->contextIsValid()) { |
| 111 ScriptState::Scope scope(m_scriptState.get()); | 113 ScriptState::Scope scope(m_scriptState.get()); |
| 112 m_loader->doUpdateFromElement(m_shouldBypassMainWorldCSP, m_updateBe
havior); | 114 m_loader->doUpdateFromElement(m_shouldBypassMainWorldCSP, m_updateBe
havior, m_referrerPolicy); |
| 113 } else { | 115 } else { |
| 114 m_loader->doUpdateFromElement(m_shouldBypassMainWorldCSP, m_updateBe
havior); | 116 m_loader->doUpdateFromElement(m_shouldBypassMainWorldCSP, m_updateBe
havior, m_referrerPolicy); |
| 115 } | 117 } |
| 116 } | 118 } |
| 117 | 119 |
| 118 void clearLoader() | 120 void clearLoader() |
| 119 { | 121 { |
| 120 m_loader = nullptr; | 122 m_loader = nullptr; |
| 121 m_scriptState.clear(); | 123 m_scriptState.clear(); |
| 122 } | 124 } |
| 123 | 125 |
| 124 WeakPtr<Task> createWeakPtr() | 126 WeakPtr<Task> createWeakPtr() |
| 125 { | 127 { |
| 126 return m_weakFactory.createWeakPtr(); | 128 return m_weakFactory.createWeakPtr(); |
| 127 } | 129 } |
| 128 | 130 |
| 129 private: | 131 private: |
| 130 RawPtrWillBeWeakPersistent<ImageLoader> m_loader; | 132 RawPtrWillBeWeakPersistent<ImageLoader> m_loader; |
| 131 BypassMainWorldBehavior m_shouldBypassMainWorldCSP; | 133 BypassMainWorldBehavior m_shouldBypassMainWorldCSP; |
| 132 UpdateFromElementBehavior m_updateBehavior; | 134 UpdateFromElementBehavior m_updateBehavior; |
| 133 RefPtr<ScriptState> m_scriptState; | 135 RefPtr<ScriptState> m_scriptState; |
| 134 WeakPtrFactory<Task> m_weakFactory; | 136 WeakPtrFactory<Task> m_weakFactory; |
| 137 ReferrerPolicy m_referrerPolicy; |
| 135 }; | 138 }; |
| 136 | 139 |
| 137 ImageLoader::ImageLoader(Element* element) | 140 ImageLoader::ImageLoader(Element* element) |
| 138 : m_element(element) | 141 : m_element(element) |
| 139 , m_image(0) | 142 , m_image(0) |
| 140 , m_derefElementTimer(this, &ImageLoader::timerFired) | 143 , m_derefElementTimer(this, &ImageLoader::timerFired) |
| 141 , m_hasPendingLoadEvent(false) | 144 , m_hasPendingLoadEvent(false) |
| 142 , m_hasPendingErrorEvent(false) | 145 , m_hasPendingErrorEvent(false) |
| 143 , m_imageComplete(true) | 146 , m_imageComplete(true) |
| 144 , m_loadingImageDocument(false) | 147 , m_loadingImageDocument(false) |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 inline void ImageLoader::crossSiteOrCSPViolationOccurred(AtomicString imageSourc
eURL) | 269 inline void ImageLoader::crossSiteOrCSPViolationOccurred(AtomicString imageSourc
eURL) |
| 267 { | 270 { |
| 268 m_failedLoadURL = imageSourceURL; | 271 m_failedLoadURL = imageSourceURL; |
| 269 } | 272 } |
| 270 | 273 |
| 271 inline void ImageLoader::clearFailedLoadURL() | 274 inline void ImageLoader::clearFailedLoadURL() |
| 272 { | 275 { |
| 273 m_failedLoadURL = AtomicString(); | 276 m_failedLoadURL = AtomicString(); |
| 274 } | 277 } |
| 275 | 278 |
| 276 inline void ImageLoader::enqueueImageLoadingMicroTask(UpdateFromElementBehavior
updateBehavior) | 279 inline void ImageLoader::enqueueImageLoadingMicroTask(UpdateFromElementBehavior
updateBehavior, ReferrerPolicy referrerPolicy) |
| 277 { | 280 { |
| 278 OwnPtr<Task> task = Task::create(this, updateBehavior); | 281 OwnPtr<Task> task = Task::create(this, updateBehavior, referrerPolicy); |
| 279 m_pendingTask = task->createWeakPtr(); | 282 m_pendingTask = task->createWeakPtr(); |
| 280 Microtask::enqueueMicrotask(task.release()); | 283 Microtask::enqueueMicrotask(task.release()); |
| 281 m_loadDelayCounter = IncrementLoadEventDelayCount::create(m_element->documen
t()); | 284 m_loadDelayCounter = IncrementLoadEventDelayCount::create(m_element->documen
t()); |
| 282 } | 285 } |
| 283 | 286 |
| 284 void ImageLoader::doUpdateFromElement(BypassMainWorldBehavior bypassBehavior, Up
dateFromElementBehavior updateBehavior) | 287 void ImageLoader::doUpdateFromElement(BypassMainWorldBehavior bypassBehavior, Up
dateFromElementBehavior updateBehavior, ReferrerPolicy referrerPolicy) |
| 285 { | 288 { |
| 286 // FIXME: According to | 289 // FIXME: According to |
| 287 // http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-cont
ent.html#the-img-element:the-img-element-55 | 290 // http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-cont
ent.html#the-img-element:the-img-element-55 |
| 288 // When "update image" is called due to environment changes and the load fai
ls, onerror should not be called. | 291 // When "update image" is called due to environment changes and the load fai
ls, onerror should not be called. |
| 289 // That is currently not the case. | 292 // That is currently not the case. |
| 290 // | 293 // |
| 291 // We don't need to call clearLoader here: Either we were called from the | 294 // We don't need to call clearLoader here: Either we were called from the |
| 292 // task, or our caller updateFromElement cleared the task's loader (and set | 295 // task, or our caller updateFromElement cleared the task's loader (and set |
| 293 // m_pendingTask to null). | 296 // m_pendingTask to null). |
| 294 m_pendingTask.clear(); | 297 m_pendingTask.clear(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 307 if (!url.isNull()) { | 310 if (!url.isNull()) { |
| 308 // Unlike raw <img>, we block mixed content inside of <picture> or <img
srcset>. | 311 // Unlike raw <img>, we block mixed content inside of <picture> or <img
srcset>. |
| 309 ResourceLoaderOptions resourceLoaderOptions = ResourceFetcher::defaultRe
sourceOptions(); | 312 ResourceLoaderOptions resourceLoaderOptions = ResourceFetcher::defaultRe
sourceOptions(); |
| 310 ResourceRequest resourceRequest(url); | 313 ResourceRequest resourceRequest(url); |
| 311 resourceRequest.setFetchCredentialsMode(WebURLRequest::FetchCredentialsM
odeSameOrigin); | 314 resourceRequest.setFetchCredentialsMode(WebURLRequest::FetchCredentialsM
odeSameOrigin); |
| 312 if (updateBehavior == UpdateForcedReload) { | 315 if (updateBehavior == UpdateForcedReload) { |
| 313 resourceRequest.setCachePolicy(ResourceRequestCachePolicy::ReloadByp
assingCache); | 316 resourceRequest.setCachePolicy(ResourceRequestCachePolicy::ReloadByp
assingCache); |
| 314 // ImageLoader defers the load of images when in an ImageDocument. D
on't defer this load on a forced reload. | 317 // ImageLoader defers the load of images when in an ImageDocument. D
on't defer this load on a forced reload. |
| 315 m_loadingImageDocument = false; | 318 m_loadingImageDocument = false; |
| 316 } | 319 } |
| 320 |
| 321 if (referrerPolicy != ReferrerPolicyDefault) |
| 322 resourceRequest.setHTTPReferrer(SecurityPolicy::generateReferrer(ref
errerPolicy, url, document.outgoingReferrer())); |
| 323 |
| 317 if (isHTMLPictureElement(element()->parentNode()) || !element()->fastGet
Attribute(HTMLNames::srcsetAttr).isNull()) | 324 if (isHTMLPictureElement(element()->parentNode()) || !element()->fastGet
Attribute(HTMLNames::srcsetAttr).isNull()) |
| 318 resourceRequest.setRequestContext(WebURLRequest::RequestContextImage
Set); | 325 resourceRequest.setRequestContext(WebURLRequest::RequestContextImage
Set); |
| 319 FetchRequest request(resourceRequest, element()->localName(), resourceLo
aderOptions); | 326 FetchRequest request(resourceRequest, element()->localName(), resourceLo
aderOptions); |
| 320 configureRequest(request, bypassBehavior, *m_element, document.clientHin
tsPreferences()); | 327 configureRequest(request, bypassBehavior, *m_element, document.clientHin
tsPreferences()); |
| 321 | 328 |
| 322 // Prevent the immediate creation of a ResourceLoader (and therefore a n
etwork | 329 // Prevent the immediate creation of a ResourceLoader (and therefore a n
etwork |
| 323 // request) for ImageDocument loads. In this case, the image contents ha
ve already | 330 // request) for ImageDocument loads. In this case, the image contents ha
ve already |
| 324 // been requested as a main resource and ImageDocumentParser will take c
are of | 331 // been requested as a main resource and ImageDocumentParser will take c
are of |
| 325 // funneling the main resource bytes into the ImageResource. | 332 // funneling the main resource bytes into the ImageResource. |
| 326 if (m_loadingImageDocument) { | 333 if (m_loadingImageDocument) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 } | 389 } |
| 383 | 390 |
| 384 if (LayoutImageResource* imageResource = layoutImageResource()) | 391 if (LayoutImageResource* imageResource = layoutImageResource()) |
| 385 imageResource->resetAnimation(); | 392 imageResource->resetAnimation(); |
| 386 | 393 |
| 387 // Only consider updating the protection ref-count of the Element immediatel
y before returning | 394 // Only consider updating the protection ref-count of the Element immediatel
y before returning |
| 388 // from this function as doing so might result in the destruction of this Im
ageLoader. | 395 // from this function as doing so might result in the destruction of this Im
ageLoader. |
| 389 updatedHasPendingEvent(); | 396 updatedHasPendingEvent(); |
| 390 } | 397 } |
| 391 | 398 |
| 392 void ImageLoader::updateFromElement(UpdateFromElementBehavior updateBehavior) | 399 void ImageLoader::updateFromElement(UpdateFromElementBehavior updateBehavior, Re
ferrerPolicy referrerPolicy) |
| 393 { | 400 { |
| 394 AtomicString imageSourceURL = m_element->imageSourceURL(); | 401 AtomicString imageSourceURL = m_element->imageSourceURL(); |
| 395 m_suppressErrorEvents = (updateBehavior == UpdateSizeChanged); | 402 m_suppressErrorEvents = (updateBehavior == UpdateSizeChanged); |
| 396 | 403 |
| 397 if (updateBehavior == UpdateIgnorePreviousError) | 404 if (updateBehavior == UpdateIgnorePreviousError) |
| 398 clearFailedLoadURL(); | 405 clearFailedLoadURL(); |
| 399 | 406 |
| 400 if (!m_failedLoadURL.isEmpty() && imageSourceURL == m_failedLoadURL) | 407 if (!m_failedLoadURL.isEmpty() && imageSourceURL == m_failedLoadURL) |
| 401 return; | 408 return; |
| 402 | 409 |
| 403 // If we have a pending task, we have to clear it -- either we're | 410 // If we have a pending task, we have to clear it -- either we're |
| 404 // now loading immediately, or we need to reset the task's state. | 411 // now loading immediately, or we need to reset the task's state. |
| 405 if (m_pendingTask) { | 412 if (m_pendingTask) { |
| 406 m_pendingTask->clearLoader(); | 413 m_pendingTask->clearLoader(); |
| 407 m_pendingTask.clear(); | 414 m_pendingTask.clear(); |
| 408 } | 415 } |
| 409 | 416 |
| 410 KURL url = imageSourceToKURL(imageSourceURL); | 417 KURL url = imageSourceToKURL(imageSourceURL); |
| 411 if (shouldLoadImmediately(url)) { | 418 if (shouldLoadImmediately(url)) { |
| 412 doUpdateFromElement(DoNotBypassMainWorldCSP, updateBehavior); | 419 doUpdateFromElement(DoNotBypassMainWorldCSP, updateBehavior, referrerPol
icy); |
| 413 return; | 420 return; |
| 414 } | 421 } |
| 415 // Allow the idiom "img.src=''; img.src='.." to clear down the image before | 422 // Allow the idiom "img.src=''; img.src='.." to clear down the image before |
| 416 // an asynchronous load completes. | 423 // an asynchronous load completes. |
| 417 if (imageSourceURL.isEmpty()) { | 424 if (imageSourceURL.isEmpty()) { |
| 418 ImageResource* image = m_image.get(); | 425 ImageResource* image = m_image.get(); |
| 419 if (image) | 426 if (image) |
| 420 image->removeClient(this); | 427 image->removeClient(this); |
| 421 m_image = nullptr; | 428 m_image = nullptr; |
| 422 } | 429 } |
| 423 | 430 |
| 424 // Don't load images for inactive documents. We don't want to slow down the | 431 // Don't load images for inactive documents. We don't want to slow down the |
| 425 // raw HTML parsing case by loading images we don't intend to display. | 432 // raw HTML parsing case by loading images we don't intend to display. |
| 426 Document& document = m_element->document(); | 433 Document& document = m_element->document(); |
| 427 if (document.isActive()) | 434 if (document.isActive()) |
| 428 enqueueImageLoadingMicroTask(updateBehavior); | 435 enqueueImageLoadingMicroTask(updateBehavior, referrerPolicy); |
| 429 } | 436 } |
| 430 | 437 |
| 431 KURL ImageLoader::imageSourceToKURL(AtomicString imageSourceURL) const | 438 KURL ImageLoader::imageSourceToKURL(AtomicString imageSourceURL) const |
| 432 { | 439 { |
| 433 KURL url; | 440 KURL url; |
| 434 | 441 |
| 435 // Don't load images for inactive documents. We don't want to slow down the | 442 // Don't load images for inactive documents. We don't want to slow down the |
| 436 // raw HTML parsing case by loading images we don't intend to display. | 443 // raw HTML parsing case by loading images we don't intend to display. |
| 437 Document& document = m_element->document(); | 444 Document& document = m_element->document(); |
| 438 if (!document.isActive()) | 445 if (!document.isActive()) |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 | 673 |
| 667 void ImageLoader::sourceImageChanged() | 674 void ImageLoader::sourceImageChanged() |
| 668 { | 675 { |
| 669 for (auto& client : m_clients) { | 676 for (auto& client : m_clients) { |
| 670 ImageLoaderClient* handle = client; | 677 ImageLoaderClient* handle = client; |
| 671 handle->notifyImageSourceChanged(); | 678 handle->notifyImageSourceChanged(); |
| 672 } | 679 } |
| 673 } | 680 } |
| 674 | 681 |
| 675 } // namespace blink | 682 } // namespace blink |
| OLD | NEW |