Changeset 87628 in webkit
- Timestamp:
- May 28, 2011 6:37:59 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r87625 r87628 1 2011-05-28 Alexey Proskuryakov <ap@apple.com> 2 3 Reviewed by Geoff Garen. 4 5 REGRESSION (r85375): Load event is sometimes lost when multiple image elements use the same URL 6 https://bugs.webkit.org/show_bug.cgi?id=61692 7 <rdar://problem/9488628> 8 9 * fast/dom/gc-image-element-2-expected.txt: Added. 10 * fast/dom/gc-image-element-2.html: Added. 11 1 12 2011-05-28 Martin Robinson <mrobinson@igalia.com> 2 13 -
trunk/Source/WebCore/ChangeLog
r87623 r87628 1 2011-05-28 Alexey Proskuryakov <ap@apple.com> 2 3 Reviewed by Geoff Garen. 4 5 REGRESSION (r85375): Load event is sometimes lost when multiple image elements use the same URL 6 https://bugs.webkit.org/show_bug.cgi?id=61692 7 <rdar://problem/9488628> 8 9 Test: fast/dom/gc-image-element-2.html 10 11 Manually verified that tests from bug 59604 and from bug 40926 still pass. 12 13 The problem here was that HTMLImageElement::hasPendingActivity() could return false when 14 a load (or error) event was still expected to fire. 15 16 * loader/cache/CachedResource.cpp: 17 (WebCore::CachedResource::setRequest): 18 * loader/cache/CachedResource.h: 19 (WebCore::CachedResource::wasCanceled): 20 (WebCore::CachedResource::errorOccurred): 21 Track whether the load was canceled. We want to always notify clients of load outcome, 22 as that's the only way they could make intelligent decisions. 23 24 * dom/ScriptElement.cpp: (WebCore::ScriptElement::execute): Cached resource clients now 25 get a notifyFinished call on cancellation. Handle this case, where we don't need the 26 execute the script, but also don't need to fire an error event. 27 28 * html/HTMLImageElement.cpp: Moved hasPendingActivity() to header, since it's just a single 29 function call now. 30 31 * html/HTMLImageElement.h: (WebCore::HTMLImageElement::hasPendingActivity): There is a large 32 window between when CachedResource::isLoading() becomes false and events are queued. 33 ImageLoader::haveFiredLoadEvent() is a much better indication of whether we are expecting 34 an event to fire. 35 36 * html/HTMLLinkElement.cpp: (WebCore::HTMLLinkElement::onloadTimerFired): Again, don't do 37 anything on cancellation. 38 39 * loader/ImageLoader.cpp: 40 (WebCore::ImageEventSender::hasPendingEvents): Made it debug-only again, and fixed to 41 give an accurate result while looping over the list of events to dispatch. 42 (WebCore::ImageLoader::notifyFinished): Don't do anything when cancelled. We don't want to 43 switch to a broken image icon, or to dispatch events. 44 (WebCore::ImageEventSender::dispatchPendingEvents): Clear the current loader from dispatching 45 list, as the event is no longer pending when it's being dispatched. 46 47 * loader/ImageLoader.h: Removed unnecessary hasPendingLoadEvent(). We don't care whether one 48 is already pending, we only care if one is expected at some time in the future, and 49 !haveFiredLoadEvent() is our best idea of that. 50 51 * dom/XMLDocumentParser.cpp: (WebCore::XMLDocumentParser::notifyFinished): Another place to 52 handle cancellation. 53 1 54 2011-05-28 Adam Barth <abarth@webkit.org> 2 55 -
trunk/Source/WebCore/dom/ScriptElement.cpp
r87239 r87628 297 297 if (cachedScript->errorOccurred()) 298 298 dispatchErrorEvent(); 299 else {299 else if (!cachedScript->wasCanceled()) { 300 300 executeScript(ScriptSourceCode(cachedScript)); 301 301 dispatchLoadEvent(); -
trunk/Source/WebCore/dom/XMLDocumentParser.cpp
r86921 r87628 326 326 ScriptSourceCode sourceCode(m_pendingScript.get()); 327 327 bool errorOccurred = m_pendingScript->errorOccurred(); 328 bool wasCanceled = m_pendingScript->wasCanceled(); 328 329 329 330 m_pendingScript->removeClient(this); … … 341 342 if (errorOccurred) 342 343 scriptElement->dispatchErrorEvent(); 343 else {344 else if (!wasCanceled) { 344 345 scriptElement->executeScript(sourceCode); 345 346 scriptElement->dispatchLoadEvent(); -
trunk/Source/WebCore/html/HTMLImageElement.cpp
r85375 r87628 386 386 } 387 387 388 bool HTMLImageElement::hasPendingActivity()389 {390 return (cachedImage() && cachedImage()->isLoading()) || m_imageLoader.hasPendingLoadEvent();391 }392 393 388 void HTMLImageElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const 394 389 { -
trunk/Source/WebCore/html/HTMLImageElement.h
r86491 r87628 74 74 75 75 bool haveFiredLoadEvent() const { return m_imageLoader.haveFiredLoadEvent(); } 76 bool hasPendingActivity() ;76 bool hasPendingActivity() const { return !m_imageLoader.haveFiredLoadEvent(); } 77 77 78 78 virtual bool canContainRangeEndPoint() const { return false; } -
trunk/Source/WebCore/html/HTMLLinkElement.cpp
r87618 r87628 449 449 if (m_cachedLinkResource->errorOccurred()) 450 450 dispatchEvent(Event::create(eventNames().errorEvent, false, false)); 451 else 451 else if (!m_cachedLinkResource->wasCanceled()) 452 452 dispatchEvent(Event::create(eventNames().loadEvent, false, false)); 453 453 -
trunk/Source/WebCore/loader/ImageLoader.cpp
r87473 r87628 69 69 void dispatchPendingEvents(); 70 70 71 bool hasPendingEvents(ImageLoader* loader) { return m_dispatchSoonList.find(loader) != notFound; } 71 #ifndef NDEBUG 72 bool hasPendingEvents(ImageLoader* loader) const 73 { 74 return m_dispatchSoonList.find(loader) != notFound || m_dispatchingList.find(loader) != notFound; 75 } 76 #endif 72 77 73 78 private: … … 218 223 } 219 224 220 void ImageLoader::notifyFinished(CachedResource* )225 void ImageLoader::notifyFinished(CachedResource* resource) 221 226 { 222 227 ASSERT(m_failedLoadURL.isEmpty()); 228 ASSERT_UNUSED(m_image, resource == m_image.get()); 223 229 224 230 m_imageComplete = true; … … 227 233 228 234 if (m_firedLoad) 235 return; 236 237 if (resource->wasCanceled()) 229 238 return; 230 239 … … 320 329 } 321 330 322 bool ImageLoader::hasPendingLoadEvent()323 {324 return loadEventSender().hasPendingEvents(this);325 }326 327 331 ImageEventSender::ImageEventSender(const AtomicString& eventType) 328 332 : m_eventType(eventType) … … 372 376 for (size_t i = 0; i < size; ++i) { 373 377 if (ImageLoader* loader = m_dispatchingList[i]) { 378 m_dispatchingList[i] = 0; 374 379 if (m_eventType == eventNames().beforeloadEvent) 375 380 loader->dispatchPendingBeforeLoadEvent(); -
trunk/Source/WebCore/loader/ImageLoader.h
r85375 r87628 59 59 bool haveFiredBeforeLoadEvent() const { return m_firedBeforeLoad; } 60 60 bool haveFiredLoadEvent() const { return m_firedLoad; } 61 bool hasPendingLoadEvent();62 61 63 62 static void dispatchPendingBeforeLoadEvents(); -
trunk/Source/WebCore/loader/cache/CachedResource.cpp
r87473 r87628 263 263 264 264 // All loads finish with data(allDataReceived = true) or error(), except for 265 // canceled loads, which silently set our request to 0. Be sure to set our 266 // loading flag to false in that case, so we don't seem to continue loading 267 // forever. 268 if (!m_request) 265 // canceled loads, which silently set our request to 0. Be sure to notify our 266 // client in that case, so we don't seem to continue loading forever. 267 if (!m_request && isLoading()) { 269 268 setLoading(false); 269 setStatus(Canceled); 270 checkNotify(); 271 } 270 272 271 273 if (canDelete() && !inCache()) -
trunk/Source/WebCore/loader/cache/CachedResource.h
r87473 r87628 78 78 Pending, // only partially loaded 79 79 Cached, // regular case 80 Canceled, 80 81 LoadError, 81 82 DecodeError … … 190 191 void setAccept(const String& accept) { m_accept = accept; } 191 192 192 bool errorOccurred() const { return (status() == LoadError || status() == DecodeError); } 193 bool wasCanceled() const { return m_status == Canceled; } 194 bool errorOccurred() const { return (m_status == LoadError || m_status == DecodeError); } 193 195 194 196 bool sendResourceLoadCallbacks() const { return m_sendResourceLoadCallbacks; }
Note: See TracChangeset
for help on using the changeset viewer.