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) { | |
Yoav Weiss
2015/08/18 21:09:21
nit: braces are not required here, and since the r
estark
2015/08/19 02:53:22
Done.
| |
322 resourceRequest.setHTTPReferrer(SecurityPolicy::generateReferrer(ref errerPolicy, url, document.outgoingReferrer())); | |
323 } | |
324 | |
317 if (isHTMLPictureElement(element()->parentNode()) || !element()->fastGet Attribute(HTMLNames::srcsetAttr).isNull()) | 325 if (isHTMLPictureElement(element()->parentNode()) || !element()->fastGet Attribute(HTMLNames::srcsetAttr).isNull()) |
318 resourceRequest.setRequestContext(WebURLRequest::RequestContextImage Set); | 326 resourceRequest.setRequestContext(WebURLRequest::RequestContextImage Set); |
319 FetchRequest request(resourceRequest, element()->localName(), resourceLo aderOptions); | 327 FetchRequest request(resourceRequest, element()->localName(), resourceLo aderOptions); |
320 configureRequest(request, bypassBehavior, *m_element, document.clientHin tsPreferences()); | 328 configureRequest(request, bypassBehavior, *m_element, document.clientHin tsPreferences()); |
321 | 329 |
322 // Prevent the immediate creation of a ResourceLoader (and therefore a n etwork | 330 // 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 | 331 // 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 | 332 // been requested as a main resource and ImageDocumentParser will take c are of |
325 // funneling the main resource bytes into the ImageResource. | 333 // funneling the main resource bytes into the ImageResource. |
326 if (m_loadingImageDocument) { | 334 if (m_loadingImageDocument) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
382 } | 390 } |
383 | 391 |
384 if (LayoutImageResource* imageResource = layoutImageResource()) | 392 if (LayoutImageResource* imageResource = layoutImageResource()) |
385 imageResource->resetAnimation(); | 393 imageResource->resetAnimation(); |
386 | 394 |
387 // Only consider updating the protection ref-count of the Element immediatel y before returning | 395 // 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. | 396 // from this function as doing so might result in the destruction of this Im ageLoader. |
389 updatedHasPendingEvent(); | 397 updatedHasPendingEvent(); |
390 } | 398 } |
391 | 399 |
392 void ImageLoader::updateFromElement(UpdateFromElementBehavior updateBehavior) | 400 void ImageLoader::updateFromElement(UpdateFromElementBehavior updateBehavior, Re ferrerPolicy referrerPolicy) |
393 { | 401 { |
394 AtomicString imageSourceURL = m_element->imageSourceURL(); | 402 AtomicString imageSourceURL = m_element->imageSourceURL(); |
395 m_suppressErrorEvents = (updateBehavior == UpdateSizeChanged); | 403 m_suppressErrorEvents = (updateBehavior == UpdateSizeChanged); |
396 | 404 |
397 if (updateBehavior == UpdateIgnorePreviousError) | 405 if (updateBehavior == UpdateIgnorePreviousError) |
398 clearFailedLoadURL(); | 406 clearFailedLoadURL(); |
399 | 407 |
400 if (!m_failedLoadURL.isEmpty() && imageSourceURL == m_failedLoadURL) | 408 if (!m_failedLoadURL.isEmpty() && imageSourceURL == m_failedLoadURL) |
401 return; | 409 return; |
402 | 410 |
403 // If we have a pending task, we have to clear it -- either we're | 411 // 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. | 412 // now loading immediately, or we need to reset the task's state. |
405 if (m_pendingTask) { | 413 if (m_pendingTask) { |
406 m_pendingTask->clearLoader(); | 414 m_pendingTask->clearLoader(); |
407 m_pendingTask.clear(); | 415 m_pendingTask.clear(); |
408 } | 416 } |
409 | 417 |
410 KURL url = imageSourceToKURL(imageSourceURL); | 418 KURL url = imageSourceToKURL(imageSourceURL); |
411 if (shouldLoadImmediately(url)) { | 419 if (shouldLoadImmediately(url)) { |
412 doUpdateFromElement(DoNotBypassMainWorldCSP, updateBehavior); | 420 doUpdateFromElement(DoNotBypassMainWorldCSP, updateBehavior, referrerPol icy); |
413 return; | 421 return; |
414 } | 422 } |
415 // Allow the idiom "img.src=''; img.src='.." to clear down the image before | 423 // Allow the idiom "img.src=''; img.src='.." to clear down the image before |
416 // an asynchronous load completes. | 424 // an asynchronous load completes. |
417 if (imageSourceURL.isEmpty()) { | 425 if (imageSourceURL.isEmpty()) { |
418 ImageResource* image = m_image.get(); | 426 ImageResource* image = m_image.get(); |
419 if (image) | 427 if (image) |
420 image->removeClient(this); | 428 image->removeClient(this); |
421 m_image = nullptr; | 429 m_image = nullptr; |
422 } | 430 } |
423 | 431 |
424 // Don't load images for inactive documents. We don't want to slow down the | 432 // 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. | 433 // raw HTML parsing case by loading images we don't intend to display. |
426 Document& document = m_element->document(); | 434 Document& document = m_element->document(); |
427 if (document.isActive()) | 435 if (document.isActive()) |
428 enqueueImageLoadingMicroTask(updateBehavior); | 436 enqueueImageLoadingMicroTask(updateBehavior, referrerPolicy); |
429 } | 437 } |
430 | 438 |
431 KURL ImageLoader::imageSourceToKURL(AtomicString imageSourceURL) const | 439 KURL ImageLoader::imageSourceToKURL(AtomicString imageSourceURL) const |
432 { | 440 { |
433 KURL url; | 441 KURL url; |
434 | 442 |
435 // Don't load images for inactive documents. We don't want to slow down the | 443 // 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. | 444 // raw HTML parsing case by loading images we don't intend to display. |
437 Document& document = m_element->document(); | 445 Document& document = m_element->document(); |
438 if (!document.isActive()) | 446 if (!document.isActive()) |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
666 | 674 |
667 void ImageLoader::sourceImageChanged() | 675 void ImageLoader::sourceImageChanged() |
668 { | 676 { |
669 for (auto& client : m_clients) { | 677 for (auto& client : m_clients) { |
670 ImageLoaderClient* handle = client; | 678 ImageLoaderClient* handle = client; |
671 handle->notifyImageSourceChanged(); | 679 handle->notifyImageSourceChanged(); |
672 } | 680 } |
673 } | 681 } |
674 | 682 |
675 } // namespace blink | 683 } // namespace blink |
OLD | NEW |