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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 } | 137 } |
138 | 138 |
139 if (RenderImageResource* imageResource = renderImageResource()) | 139 if (RenderImageResource* imageResource = renderImageResource()) |
140 imageResource->resetAnimation(); | 140 imageResource->resetAnimation(); |
141 } | 141 } |
142 | 142 |
143 void ImageLoader::updateFromElement() | 143 void ImageLoader::updateFromElement() |
144 { | 144 { |
145 // If we're not making renderers for the page, then don't load images. We d
on't want to slow | 145 // If we're not making renderers for the page, then don't load images. We d
on't want to slow |
146 // down the raw HTML parsing case by loading images we don't intend to displ
ay. | 146 // down the raw HTML parsing case by loading images we don't intend to displ
ay. |
147 Document* document = m_element->document(); | 147 Document& document = m_element->document(); |
148 if (!document->renderer()) | 148 if (!document.renderer()) |
149 return; | 149 return; |
150 | 150 |
151 AtomicString attr = m_element->imageSourceURL(); | 151 AtomicString attr = m_element->imageSourceURL(); |
152 | 152 |
153 if (!m_failedLoadURL.isEmpty() && attr == m_failedLoadURL) | 153 if (!m_failedLoadURL.isEmpty() && attr == m_failedLoadURL) |
154 return; | 154 return; |
155 | 155 |
156 // Do not load any image if the 'src' attribute is missing or if it is | 156 // Do not load any image if the 'src' attribute is missing or if it is |
157 // an empty string. | 157 // an empty string. |
158 ResourcePtr<ImageResource> newImage = 0; | 158 ResourcePtr<ImageResource> newImage = 0; |
159 if (!attr.isNull() && !stripLeadingAndTrailingHTMLSpaces(attr).isEmpty()) { | 159 if (!attr.isNull() && !stripLeadingAndTrailingHTMLSpaces(attr).isEmpty()) { |
160 FetchRequest request(ResourceRequest(document->completeURL(sourceURI(att
r))), element()->localName()); | 160 FetchRequest request(ResourceRequest(document.completeURL(sourceURI(attr
))), element()->localName()); |
161 | 161 |
162 String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossori
ginAttr); | 162 String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossori
ginAttr); |
163 if (!crossOriginMode.isNull()) { | 163 if (!crossOriginMode.isNull()) { |
164 StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMo
de, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials; | 164 StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMo
de, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials; |
165 updateRequestForAccessControl(request.mutableResourceRequest(), docu
ment->securityOrigin(), allowCredentials); | 165 updateRequestForAccessControl(request.mutableResourceRequest(), docu
ment.securityOrigin(), allowCredentials); |
166 } | 166 } |
167 | 167 |
168 if (m_loadManually) { | 168 if (m_loadManually) { |
169 bool autoLoadOtherImages = document->fetcher()->autoLoadImages(); | 169 bool autoLoadOtherImages = document.fetcher()->autoLoadImages(); |
170 document->fetcher()->setAutoLoadImages(false); | 170 document.fetcher()->setAutoLoadImages(false); |
171 newImage = new ImageResource(request.resourceRequest()); | 171 newImage = new ImageResource(request.resourceRequest()); |
172 newImage->setLoading(true); | 172 newImage->setLoading(true); |
173 document->fetcher()->m_documentResources.set(newImage->url(), newIma
ge.get()); | 173 document.fetcher()->m_documentResources.set(newImage->url(), newImag
e.get()); |
174 document->fetcher()->setAutoLoadImages(autoLoadOtherImages); | 174 document.fetcher()->setAutoLoadImages(autoLoadOtherImages); |
175 } else { | 175 } else { |
176 newImage = document->fetcher()->fetchImage(request); | 176 newImage = document.fetcher()->fetchImage(request); |
177 } | 177 } |
178 | 178 |
179 // If we do not have an image here, it means that a cross-site | 179 // If we do not have an image here, it means that a cross-site |
180 // violation occurred, or that the image was blocked via Content | 180 // violation occurred, or that the image was blocked via Content |
181 // Security Policy, or the page is being dismissed. Trigger an | 181 // Security Policy, or the page is being dismissed. Trigger an |
182 // error event if the page is not being dismissed. | 182 // error event if the page is not being dismissed. |
183 if (!newImage && !pageIsBeingDismissed(document)) { | 183 if (!newImage && !pageIsBeingDismissed(&document)) { |
184 m_failedLoadURL = attr; | 184 m_failedLoadURL = attr; |
185 m_hasPendingErrorEvent = true; | 185 m_hasPendingErrorEvent = true; |
186 errorEventSender().dispatchEventSoon(this); | 186 errorEventSender().dispatchEventSoon(this); |
187 } else | 187 } else |
188 clearFailedLoadURL(); | 188 clearFailedLoadURL(); |
189 } else if (!attr.isNull()) { | 189 } else if (!attr.isNull()) { |
190 // Fire an error event if the url is empty. | 190 // Fire an error event if the url is empty. |
191 m_hasPendingErrorEvent = true; | 191 m_hasPendingErrorEvent = true; |
192 errorEventSender().dispatchEventSoon(this); | 192 errorEventSender().dispatchEventSoon(this); |
193 } | 193 } |
(...skipping 14 matching lines...) Expand all Loading... |
208 // Cancel error events that belong to the previous load, which is now ca
ncelled by changing the src attribute. | 208 // Cancel error events that belong to the previous load, which is now ca
ncelled by changing the src attribute. |
209 // If newImage is null and m_hasPendingErrorEvent is true, we know the e
rror event has been just posted by | 209 // If newImage is null and m_hasPendingErrorEvent is true, we know the e
rror event has been just posted by |
210 // this load and we should not cancel the event. | 210 // this load and we should not cancel the event. |
211 // FIXME: If both previous load and this one got blocked with an error,
we can receive one error event instead of two. | 211 // FIXME: If both previous load and this one got blocked with an error,
we can receive one error event instead of two. |
212 if (m_hasPendingErrorEvent && newImage) { | 212 if (m_hasPendingErrorEvent && newImage) { |
213 errorEventSender().cancelEvent(this); | 213 errorEventSender().cancelEvent(this); |
214 m_hasPendingErrorEvent = false; | 214 m_hasPendingErrorEvent = false; |
215 } | 215 } |
216 | 216 |
217 m_image = newImage; | 217 m_image = newImage; |
218 m_hasPendingBeforeLoadEvent = !m_element->document()->isImageDocument()
&& newImage; | 218 m_hasPendingBeforeLoadEvent = !m_element->document().isImageDocument() &
& newImage; |
219 m_hasPendingLoadEvent = newImage; | 219 m_hasPendingLoadEvent = newImage; |
220 m_imageComplete = !newImage; | 220 m_imageComplete = !newImage; |
221 | 221 |
222 if (newImage) { | 222 if (newImage) { |
223 if (!m_element->document()->isImageDocument()) { | 223 if (!m_element->document().isImageDocument()) { |
224 if (!m_element->document()->hasListenerType(Document::BEFORELOAD
_LISTENER)) | 224 if (!m_element->document().hasListenerType(Document::BEFORELOAD_
LISTENER)) |
225 dispatchPendingBeforeLoadEvent(); | 225 dispatchPendingBeforeLoadEvent(); |
226 else | 226 else |
227 beforeLoadEventSender().dispatchEventSoon(this); | 227 beforeLoadEventSender().dispatchEventSoon(this); |
228 } else | 228 } else |
229 updateRenderer(); | 229 updateRenderer(); |
230 | 230 |
231 // If newImage is cached, addClient() will result in the load event | 231 // If newImage is cached, addClient() will result in the load event |
232 // being queued to fire. Ensure this happens after beforeload is | 232 // being queued to fire. Ensure this happens after beforeload is |
233 // dispatched. | 233 // dispatched. |
234 newImage->addClient(this); | 234 newImage->addClient(this); |
(...skipping 25 matching lines...) Expand all Loading... |
260 ASSERT(resource == m_image.get()); | 260 ASSERT(resource == m_image.get()); |
261 | 261 |
262 m_imageComplete = true; | 262 m_imageComplete = true; |
263 if (!hasPendingBeforeLoadEvent()) | 263 if (!hasPendingBeforeLoadEvent()) |
264 updateRenderer(); | 264 updateRenderer(); |
265 | 265 |
266 if (!m_hasPendingLoadEvent) | 266 if (!m_hasPendingLoadEvent) |
267 return; | 267 return; |
268 | 268 |
269 if (m_element->fastHasAttribute(HTMLNames::crossoriginAttr) | 269 if (m_element->fastHasAttribute(HTMLNames::crossoriginAttr) |
270 && !m_element->document()->securityOrigin()->canRequest(image()->respons
e().url()) | 270 && !m_element->document().securityOrigin()->canRequest(image()->response
().url()) |
271 && !resource->passesAccessControlCheck(m_element->document()->securityOr
igin())) { | 271 && !resource->passesAccessControlCheck(m_element->document().securityOri
gin())) { |
272 | 272 |
273 setImageWithoutConsideringPendingLoadEvent(0); | 273 setImageWithoutConsideringPendingLoadEvent(0); |
274 | 274 |
275 m_hasPendingErrorEvent = true; | 275 m_hasPendingErrorEvent = true; |
276 errorEventSender().dispatchEventSoon(this); | 276 errorEventSender().dispatchEventSoon(this); |
277 | 277 |
278 DEFINE_STATIC_LOCAL(String, consoleMessage, ("Cross-origin image load de
nied by Cross-Origin Resource Sharing policy.")); | 278 DEFINE_STATIC_LOCAL(String, consoleMessage, ("Cross-origin image load de
nied by Cross-Origin Resource Sharing policy.")); |
279 m_element->document()->addConsoleMessage(SecurityMessageSource, ErrorMes
sageLevel, consoleMessage); | 279 m_element->document().addConsoleMessage(SecurityMessageSource, ErrorMess
ageLevel, consoleMessage); |
280 | 280 |
281 ASSERT(!m_hasPendingLoadEvent); | 281 ASSERT(!m_hasPendingLoadEvent); |
282 | 282 |
283 // Only consider updating the protection ref-count of the Element immedi
ately before returning | 283 // Only consider updating the protection ref-count of the Element immedi
ately before returning |
284 // from this function as doing so might result in the destruction of thi
s ImageLoader. | 284 // from this function as doing so might result in the destruction of thi
s ImageLoader. |
285 updatedHasPendingEvent(); | 285 updatedHasPendingEvent(); |
286 return; | 286 return; |
287 } | 287 } |
288 | 288 |
289 if (resource->wasCanceled()) { | 289 if (resource->wasCanceled()) { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 if (eventType == eventNames().errorEvent) | 371 if (eventType == eventNames().errorEvent) |
372 dispatchPendingErrorEvent(); | 372 dispatchPendingErrorEvent(); |
373 } | 373 } |
374 | 374 |
375 void ImageLoader::dispatchPendingBeforeLoadEvent() | 375 void ImageLoader::dispatchPendingBeforeLoadEvent() |
376 { | 376 { |
377 if (!m_hasPendingBeforeLoadEvent) | 377 if (!m_hasPendingBeforeLoadEvent) |
378 return; | 378 return; |
379 if (!m_image) | 379 if (!m_image) |
380 return; | 380 return; |
381 if (!m_element->document()->attached()) | 381 if (!m_element->document().attached()) |
382 return; | 382 return; |
383 m_hasPendingBeforeLoadEvent = false; | 383 m_hasPendingBeforeLoadEvent = false; |
384 if (m_element->dispatchBeforeLoadEvent(m_image->url().string())) { | 384 if (m_element->dispatchBeforeLoadEvent(m_image->url().string())) { |
385 updateRenderer(); | 385 updateRenderer(); |
386 return; | 386 return; |
387 } | 387 } |
388 if (m_image) { | 388 if (m_image) { |
389 m_image->removeClient(this); | 389 m_image->removeClient(this); |
390 m_image = 0; | 390 m_image = 0; |
391 } | 391 } |
392 | 392 |
393 loadEventSender().cancelEvent(this); | 393 loadEventSender().cancelEvent(this); |
394 m_hasPendingLoadEvent = false; | 394 m_hasPendingLoadEvent = false; |
395 | 395 |
396 if (m_element->hasTagName(HTMLNames::objectTag)) | 396 if (m_element->hasTagName(HTMLNames::objectTag)) |
397 toHTMLObjectElement(m_element)->renderFallbackContent(); | 397 toHTMLObjectElement(m_element)->renderFallbackContent(); |
398 | 398 |
399 // Only consider updating the protection ref-count of the Element immediatel
y before returning | 399 // Only consider updating the protection ref-count of the Element immediatel
y before returning |
400 // from this function as doing so might result in the destruction of this Im
ageLoader. | 400 // from this function as doing so might result in the destruction of this Im
ageLoader. |
401 updatedHasPendingEvent(); | 401 updatedHasPendingEvent(); |
402 } | 402 } |
403 | 403 |
404 void ImageLoader::dispatchPendingLoadEvent() | 404 void ImageLoader::dispatchPendingLoadEvent() |
405 { | 405 { |
406 if (!m_hasPendingLoadEvent) | 406 if (!m_hasPendingLoadEvent) |
407 return; | 407 return; |
408 if (!m_image) | 408 if (!m_image) |
409 return; | 409 return; |
410 m_hasPendingLoadEvent = false; | 410 m_hasPendingLoadEvent = false; |
411 if (element()->document()->attached()) | 411 if (element()->document().attached()) |
412 dispatchLoadEvent(); | 412 dispatchLoadEvent(); |
413 | 413 |
414 // Only consider updating the protection ref-count of the Element immediatel
y before returning | 414 // Only consider updating the protection ref-count of the Element immediatel
y before returning |
415 // from this function as doing so might result in the destruction of this Im
ageLoader. | 415 // from this function as doing so might result in the destruction of this Im
ageLoader. |
416 updatedHasPendingEvent(); | 416 updatedHasPendingEvent(); |
417 } | 417 } |
418 | 418 |
419 void ImageLoader::dispatchPendingErrorEvent() | 419 void ImageLoader::dispatchPendingErrorEvent() |
420 { | 420 { |
421 if (!m_hasPendingErrorEvent) | 421 if (!m_hasPendingErrorEvent) |
422 return; | 422 return; |
423 m_hasPendingErrorEvent = false; | 423 m_hasPendingErrorEvent = false; |
424 if (element()->document()->attached()) | 424 if (element()->document().attached()) |
425 element()->dispatchEvent(Event::create(eventNames().errorEvent)); | 425 element()->dispatchEvent(Event::create(eventNames().errorEvent)); |
426 | 426 |
427 // Only consider updating the protection ref-count of the Element immediatel
y before returning | 427 // Only consider updating the protection ref-count of the Element immediatel
y before returning |
428 // from this function as doing so might result in the destruction of this Im
ageLoader. | 428 // from this function as doing so might result in the destruction of this Im
ageLoader. |
429 updatedHasPendingEvent(); | 429 updatedHasPendingEvent(); |
430 } | 430 } |
431 | 431 |
432 void ImageLoader::addClient(ImageLoaderClient* client) | 432 void ImageLoader::addClient(ImageLoaderClient* client) |
433 { | 433 { |
434 if (client->requestsHighLiveResourceCachePriority()) { | 434 if (client->requestsHighLiveResourceCachePriority()) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 handle->notifyImageSourceChanged(); | 477 handle->notifyImageSourceChanged(); |
478 } | 478 } |
479 } | 479 } |
480 | 480 |
481 inline void ImageLoader::clearFailedLoadURL() | 481 inline void ImageLoader::clearFailedLoadURL() |
482 { | 482 { |
483 m_failedLoadURL = AtomicString(); | 483 m_failedLoadURL = AtomicString(); |
484 } | 484 } |
485 | 485 |
486 } | 486 } |
OLD | NEW |