From 31e9ef66cd8aceac5e646a8c1c191c4b90856520 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 12 Oct 2012 12:11:22 -0400 Subject: [PATCH] Bug 505385 - Part 11: Create a new imgINotificationObserver interface to replace all uses of imgIContainerObserver and imgIDecoderObserver outside of image/. r=joe --- content/base/public/nsContentUtils.h | 4 +- .../base/public/nsIImageLoadingContent.idl | 10 +- content/base/src/nsContentUtils.cpp | 6 +- content/base/src/nsGenConImageContent.cpp | 5 +- content/base/src/nsImageLoadingContent.cpp | 148 ++++----------- content/base/src/nsImageLoadingContent.h | 13 +- content/base/src/nsObjectLoadingContent.h | 7 - .../html/content/src/nsHTMLImageElement.cpp | 9 +- .../html/content/src/nsHTMLInputElement.cpp | 5 +- .../html/content/src/nsHTMLObjectElement.cpp | 3 +- .../content/src/nsHTMLSharedObjectElement.cpp | 3 +- content/html/content/test/test_bug389797.html | 6 +- content/html/document/src/ImageDocument.cpp | 87 +++++---- content/svg/content/src/nsSVGFilters.cpp | 48 ++--- content/svg/content/src/nsSVGFilters.h | 11 +- content/svg/content/src/nsSVGImageElement.cpp | 4 +- image/public/Makefile.in | 2 + image/public/imgILoader.idl | 6 +- image/public/imgINotificationObserver.idl | 34 ++++ image/public/imgIRequest.idl | 8 +- .../imgIScriptedNotificationObserver.idl | 26 +++ image/public/imgITools.idl | 12 +- image/src/Makefile.in | 1 + image/src/ScriptedNotificationObserver.cpp | 59 ++++++ image/src/ScriptedNotificationObserver.h | 30 +++ image/src/imgLoader.cpp | 14 +- image/src/imgLoader.h | 8 +- image/src/imgRequestProxy.cpp | 66 ++++--- image/src/imgRequestProxy.h | 6 +- image/src/imgTools.cpp | 9 + image/test/mochitest/imgutils.js | 22 ++- image/test/mochitest/test_animSVGImage.html | 10 +- image/test/unit/async_load_tests.js | 36 +++- image/test/unit/image_load_helpers.js | 19 +- image/test/unit/test_private_channel.js | 10 +- layout/generic/nsBulletFrame.cpp | 133 ++++--------- layout/generic/nsBulletFrame.h | 33 +--- layout/generic/nsImageFrame.cpp | 175 +++++------------- layout/generic/nsImageFrame.h | 34 ++-- layout/style/ImageLoader.cpp | 47 +++-- layout/style/ImageLoader.h | 26 ++- layout/svg/nsSVGImageFrame.cpp | 66 +++---- layout/xul/base/src/nsImageBoxFrame.cpp | 97 +++++----- layout/xul/base/src/nsImageBoxFrame.h | 36 ++-- .../xul/base/src/tree/src/nsTreeBodyFrame.cpp | 12 +- .../xul/base/src/tree/src/nsTreeBodyFrame.h | 6 +- .../base/src/tree/src/nsTreeImageListener.cpp | 45 ++--- .../base/src/tree/src/nsTreeImageListener.h | 13 +- toolkit/system/gnome/nsAlertsIconListener.cpp | 91 ++------- toolkit/system/gnome/nsAlertsIconListener.h | 10 +- widget/cocoa/nsMenuItemIconX.h | 9 +- widget/cocoa/nsMenuItemIconX.mm | 99 ++-------- 52 files changed, 707 insertions(+), 972 deletions(-) create mode 100644 image/public/imgINotificationObserver.idl create mode 100644 image/public/imgIScriptedNotificationObserver.idl create mode 100644 image/src/ScriptedNotificationObserver.cpp create mode 100644 image/src/ScriptedNotificationObserver.h diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index e25713060fd..476903ddf3c 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -64,7 +64,7 @@ class nsIParserService; class nsIIOService; class nsIURI; class imgIContainer; -class imgIDecoderObserver; +class imgINotificationObserver; class imgIRequest; class imgILoader; class imgICache; @@ -661,7 +661,7 @@ public: nsIDocument* aLoadingDocument, nsIPrincipal* aLoadingPrincipal, nsIURI* aReferrer, - imgIDecoderObserver* aObserver, + imgINotificationObserver* aObserver, int32_t aLoadFlags, imgIRequest** aRequest); diff --git a/content/base/public/nsIImageLoadingContent.idl b/content/base/public/nsIImageLoadingContent.idl index 9a08f47c76f..417dae5f7e2 100644 --- a/content/base/public/nsIImageLoadingContent.idl +++ b/content/base/public/nsIImageLoadingContent.idl @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "imgIDecoderObserver.idl" +#include "imgINotificationObserver.idl" interface imgIRequest; interface nsIChannel; @@ -34,8 +34,8 @@ interface nsIFrame; * sufficient, when combined with the imageBlockingStatus information.) */ -[scriptable, uuid(4bf1a7c5-6edb-4191-a257-e31a90f6aa85)] -interface nsIImageLoadingContent : imgIDecoderObserver +[scriptable, builtinclass, uuid(497bfb9b-d996-4d1e-a647-8137b0cfc876)] +interface nsIImageLoadingContent : imgINotificationObserver { /** * Request types. Image loading content nodes attempt to do atomic @@ -75,14 +75,14 @@ interface nsIImageLoadingContent : imgIDecoderObserver * * @throws NS_ERROR_OUT_OF_MEMORY */ - void addObserver(in imgIDecoderObserver aObserver); + void addObserver(in imgINotificationObserver aObserver); /** * Used to unregister an image decoder observer. * * @param aObserver the observer to unregister */ - void removeObserver(in imgIDecoderObserver aObserver); + void removeObserver(in imgINotificationObserver aObserver); /** * Accessor to get the image requests diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index cd0aacf908f..1cf173223bf 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -51,7 +51,7 @@ #include "nsIForm.h" #include "nsIFormControl.h" #include "nsGkAtoms.h" -#include "imgIDecoderObserver.h" +#include "imgINotificationObserver.h" #include "imgIRequest.h" #include "imgIContainer.h" #include "imgILoader.h" @@ -2734,7 +2734,7 @@ nsContentUtils::IsImageInCache(nsIURI* aURI, nsIDocument* aDocument) nsresult nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument, nsIPrincipal* aLoadingPrincipal, nsIURI* aReferrer, - imgIDecoderObserver* aObserver, int32_t aLoadFlags, + imgINotificationObserver* aObserver, int32_t aLoadFlags, imgIRequest** aRequest) { NS_PRECONDITION(aURI, "Must have a URI"); @@ -2777,7 +2777,7 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument, aReferrer, /* referrer */ aLoadingPrincipal, /* loading principal */ loadGroup, /* loadgroup */ - aObserver, /* imgIDecoderObserver */ + aObserver, /* imgINotificationObserver */ aLoadingDocument, /* uniquification key */ aLoadFlags, /* load flags */ nullptr, /* cache key */ diff --git a/content/base/src/nsGenConImageContent.cpp b/content/base/src/nsGenConImageContent.cpp index 49ffc4a232d..27b8bca1b24 100644 --- a/content/base/src/nsGenConImageContent.cpp +++ b/content/base/src/nsGenConImageContent.cpp @@ -48,11 +48,10 @@ public: NS_DECL_ISUPPORTS_INHERITED }; -NS_IMPL_ISUPPORTS_INHERITED4(nsGenConImageContent, +NS_IMPL_ISUPPORTS_INHERITED3(nsGenConImageContent, nsXMLElement, nsIImageLoadingContent, - imgIContainerObserver, - imgIDecoderObserver, + imgINotificationObserver, imgIOnloadBlocker) nsresult diff --git a/content/base/src/nsImageLoadingContent.cpp b/content/base/src/nsImageLoadingContent.cpp index 92aebf6a56e..cfc3b6a02a6 100644 --- a/content/base/src/nsImageLoadingContent.cpp +++ b/content/base/src/nsImageLoadingContent.cpp @@ -122,112 +122,56 @@ nsImageLoadingContent::~nsImageLoadingContent() } \ PR_END_MACRO - /* - * imgIContainerObserver impl + * imgINotificationObserver impl */ NS_IMETHODIMP -nsImageLoadingContent::FrameChanged(imgIRequest* aRequest, - imgIContainer* aContainer, - const nsIntRect* aDirtyRect) -{ - LOOP_OVER_OBSERVERS(FrameChanged(aRequest, aContainer, aDirtyRect)); - return NS_OK; -} - -/* - * imgIDecoderObserver impl - */ -NS_IMETHODIMP -nsImageLoadingContent::OnStartRequest(imgIRequest* aRequest) +nsImageLoadingContent::Notify(imgIRequest* aRequest, + int32_t aType, + const nsIntRect* aData) { + if (aType == imgINotificationObserver::IS_ANIMATED) { + return OnImageIsAnimated(aRequest); + } + + if (aType == imgINotificationObserver::STOP_DECODE) { + // We should definitely have a request here + NS_ABORT_IF_FALSE(aRequest, "no request?"); + + NS_PRECONDITION(aRequest == mCurrentRequest || aRequest == mPendingRequest, + "Unknown request"); + } + NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); - LOOP_OVER_OBSERVERS(OnStartRequest(aRequest)); - return NS_OK; -} + if (aType != imgINotificationObserver::FRAME_CHANGED) { + LOOP_OVER_OBSERVERS(Notify(aRequest, aType, aData)); + } -NS_IMETHODIMP -nsImageLoadingContent::OnStartDecode(imgIRequest* aRequest) -{ - NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); + if (aType == imgINotificationObserver::START_CONTAINER) { + // Have to check for state changes here, since we might have been in + // the LOADING state before. + UpdateImageState(true); + } - LOOP_OVER_OBSERVERS(OnStartDecode(aRequest)); - return NS_OK; -} + if (aType == imgINotificationObserver::STOP_DECODE) { + uint32_t reqStatus; + aRequest->GetImageStatus(&reqStatus); + nsresult status = + reqStatus & imgIRequest::STATUS_ERROR ? NS_ERROR_FAILURE : NS_OK; + return OnStopDecode(aRequest, status); + } -NS_IMETHODIMP -nsImageLoadingContent::OnStartContainer(imgIRequest* aRequest, - imgIContainer* aContainer) -{ - NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); - - LOOP_OVER_OBSERVERS(OnStartContainer(aRequest, aContainer)); - - // Have to check for state changes here, since we might have been in - // the LOADING state before. - UpdateImageState(true); - return NS_OK; -} - -NS_IMETHODIMP -nsImageLoadingContent::OnStartFrame(imgIRequest* aRequest, - uint32_t aFrame) -{ - NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); - - LOOP_OVER_OBSERVERS(OnStartFrame(aRequest, aFrame)); - return NS_OK; -} - -NS_IMETHODIMP -nsImageLoadingContent::OnDataAvailable(imgIRequest* aRequest, - bool aCurrentFrame, - const nsIntRect* aRect) -{ - NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); - - LOOP_OVER_OBSERVERS(OnDataAvailable(aRequest, aCurrentFrame, aRect)); - return NS_OK; -} - -NS_IMETHODIMP -nsImageLoadingContent::OnStopFrame(imgIRequest* aRequest, - uint32_t aFrame) -{ - NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); - - LOOP_OVER_OBSERVERS(OnStopFrame(aRequest, aFrame)); - return NS_OK; -} - -NS_IMETHODIMP -nsImageLoadingContent::OnStopContainer(imgIRequest* aRequest, - imgIContainer* aContainer) -{ - NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); - - LOOP_OVER_OBSERVERS(OnStopContainer(aRequest, aContainer)); return NS_OK; } // Warning - This isn't actually fired when decode is complete. Rather, it's // fired when load is complete. See bug 505385, and in the mean time use // OnStopContainer. -NS_IMETHODIMP +nsresult nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest, - nsresult aStatus, - const PRUnichar* aStatusArg) + nsresult aStatus) { - NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); - - // We should definitely have a request here - NS_ABORT_IF_FALSE(aRequest, "no request?"); - - NS_PRECONDITION(aRequest == mCurrentRequest || aRequest == mPendingRequest, - "Unknown request"); - LOOP_OVER_OBSERVERS(OnStopDecode(aRequest, aStatus, aStatusArg)); - // XXXbholley - When we fix bug 505385, everything here should go in // OnStopRequest. @@ -284,17 +228,7 @@ nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest, return NS_OK; } -NS_IMETHODIMP -nsImageLoadingContent::OnStopRequest(imgIRequest* aRequest, bool aLastPart) -{ - NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); - - LOOP_OVER_OBSERVERS(OnStopRequest(aRequest, aLastPart)); - - return NS_OK; -} - -NS_IMETHODIMP +nsresult nsImageLoadingContent::OnImageIsAnimated(imgIRequest *aRequest) { bool* requestFlag = GetRegisteredFlagForRequest(aRequest); @@ -306,16 +240,6 @@ nsImageLoadingContent::OnImageIsAnimated(imgIRequest *aRequest) return NS_OK; } -NS_IMETHODIMP -nsImageLoadingContent::OnDiscard(imgIRequest *aRequest) -{ - NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); - - LOOP_OVER_OBSERVERS(OnDiscard(aRequest)); - - return NS_OK; -} - /* * nsIImageLoadingContent impl */ @@ -351,7 +275,7 @@ nsImageLoadingContent::GetImageBlockingStatus(int16_t* aStatus) } NS_IMETHODIMP -nsImageLoadingContent::AddObserver(imgIDecoderObserver* aObserver) +nsImageLoadingContent::AddObserver(imgINotificationObserver* aObserver) { NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); @@ -379,7 +303,7 @@ nsImageLoadingContent::AddObserver(imgIDecoderObserver* aObserver) } NS_IMETHODIMP -nsImageLoadingContent::RemoveObserver(imgIDecoderObserver* aObserver) +nsImageLoadingContent::RemoveObserver(imgINotificationObserver* aObserver) { NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); diff --git a/content/base/src/nsImageLoadingContent.h b/content/base/src/nsImageLoadingContent.h index 07996b55c86..89a2b1e8ec7 100644 --- a/content/base/src/nsImageLoadingContent.h +++ b/content/base/src/nsImageLoadingContent.h @@ -13,8 +13,7 @@ #ifndef nsImageLoadingContent_h__ #define nsImageLoadingContent_h__ -#include "imgIContainerObserver.h" -#include "imgIDecoderObserver.h" +#include "imgINotificationObserver.h" #include "imgIOnloadBlocker.h" #include "mozilla/CORSMode.h" #include "nsCOMPtr.h" @@ -36,8 +35,7 @@ public: nsImageLoadingContent(); virtual ~nsImageLoadingContent(); - NS_DECL_IMGICONTAINEROBSERVER - NS_DECL_IMGIDECODEROBSERVER + NS_DECL_IMGINOTIFICATIONOBSERVER NS_DECL_NSIIMAGELOADINGCONTENT NS_DECL_IMGIONLOADBLOCKER @@ -161,12 +159,15 @@ protected: nsIContent* aBindingParent, bool aCompileEventHandlers); void UnbindFromTree(bool aDeep, bool aNullParent); + nsresult OnStopDecode(imgIRequest* aRequest, nsresult aStatus); + nsresult OnImageIsAnimated(imgIRequest *aRequest); + private: /** * Struct used to manage the image observers. */ struct ImageObserver { - ImageObserver(imgIDecoderObserver* aObserver) : + ImageObserver(imgINotificationObserver* aObserver) : mObserver(aObserver), mNext(nullptr) { @@ -178,7 +179,7 @@ private: NS_CONTENT_DELETE_LIST_MEMBER(ImageObserver, this, mNext); } - nsCOMPtr mObserver; + nsCOMPtr mObserver; ImageObserver* mNext; }; diff --git a/content/base/src/nsObjectLoadingContent.h b/content/base/src/nsObjectLoadingContent.h index 0ae8125acef..d5ee66b090d 100644 --- a/content/base/src/nsObjectLoadingContent.h +++ b/content/base/src/nsObjectLoadingContent.h @@ -98,13 +98,6 @@ class nsObjectLoadingContent : public nsImageLoadingContent NS_DECL_NSIINTERFACEREQUESTOR NS_DECL_NSICHANNELEVENTSINK -#ifdef HAVE_CPP_AMBIGUITY_RESOLVING_USING - // Fix gcc compile warnings - using nsImageLoadingContent::OnStartRequest; - using nsImageLoadingContent::OnDataAvailable; - using nsImageLoadingContent::OnStopRequest; -#endif - /** * Object state. This is a bitmask of NS_EVENT_STATEs epresenting the * current state of the object. diff --git a/content/html/content/src/nsHTMLImageElement.cpp b/content/html/content/src/nsHTMLImageElement.cpp index 6938d099a83..feb5f5fd075 100644 --- a/content/html/content/src/nsHTMLImageElement.cpp +++ b/content/html/content/src/nsHTMLImageElement.cpp @@ -29,7 +29,7 @@ #include "imgIContainer.h" #include "imgILoader.h" #include "imgIRequest.h" -#include "imgIDecoderObserver.h" +#include "imgINotificationObserver.h" #include "nsILoadGroup.h" @@ -89,13 +89,12 @@ DOMCI_NODE_DATA(HTMLImageElement, nsHTMLImageElement) // QueryInterface implementation for nsHTMLImageElement NS_INTERFACE_TABLE_HEAD(nsHTMLImageElement) - NS_HTML_CONTENT_INTERFACE_TABLE6(nsHTMLImageElement, + NS_HTML_CONTENT_INTERFACE_TABLE5(nsHTMLImageElement, nsIDOMHTMLImageElement, nsIJSNativeInitializer, - imgIDecoderObserver, nsIImageLoadingContent, - imgIContainerObserver, - imgIOnloadBlocker) + imgIOnloadBlocker, + imgINotificationObserver) NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLImageElement, nsGenericHTMLElement) NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLImageElement) diff --git a/content/html/content/src/nsHTMLInputElement.cpp b/content/html/content/src/nsHTMLInputElement.cpp index 87c813f8c27..1d2928577d3 100644 --- a/content/html/content/src/nsHTMLInputElement.cpp +++ b/content/html/content/src/nsHTMLInputElement.cpp @@ -642,13 +642,12 @@ DOMCI_NODE_DATA(HTMLInputElement, nsHTMLInputElement) // QueryInterface implementation for nsHTMLInputElement NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLInputElement) - NS_HTML_CONTENT_INTERFACE_TABLE9(nsHTMLInputElement, + NS_HTML_CONTENT_INTERFACE_TABLE8(nsHTMLInputElement, nsIDOMHTMLInputElement, nsITextControlElement, nsIPhonetic, - imgIDecoderObserver, + imgINotificationObserver, nsIImageLoadingContent, - imgIContainerObserver, imgIOnloadBlocker, nsIDOMNSEditableElement, nsIConstraintValidation) diff --git a/content/html/content/src/nsHTMLObjectElement.cpp b/content/html/content/src/nsHTMLObjectElement.cpp index 8fa058b4b6c..b79030dd753 100644 --- a/content/html/content/src/nsHTMLObjectElement.cpp +++ b/content/html/content/src/nsHTMLObjectElement.cpp @@ -185,14 +185,13 @@ DOMCI_NODE_DATA(HTMLObjectElement, nsHTMLObjectElement) NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLObjectElement) NS_HTML_CONTENT_INTERFACE_TABLE_BEGIN(nsHTMLObjectElement) NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIDOMHTMLObjectElement) - NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, imgIDecoderObserver) + NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, imgINotificationObserver) NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIRequestObserver) NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIStreamListener) NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIFrameLoaderOwner) NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIObjectLoadingContent) NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIImageLoadingContent) NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, imgIOnloadBlocker) - NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, imgIContainerObserver) NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIInterfaceRequestor) NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIChannelEventSink) NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIConstraintValidation) diff --git a/content/html/content/src/nsHTMLSharedObjectElement.cpp b/content/html/content/src/nsHTMLSharedObjectElement.cpp index 079b846006a..56a8b4a27e4 100644 --- a/content/html/content/src/nsHTMLSharedObjectElement.cpp +++ b/content/html/content/src/nsHTMLSharedObjectElement.cpp @@ -234,9 +234,8 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLSharedObjectElement) NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIRequestObserver) NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIStreamListener) NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIFrameLoaderOwner) - NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, imgIContainerObserver) NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIObjectLoadingContent) - NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, imgIDecoderObserver) + NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, imgINotificationObserver) NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIImageLoadingContent) NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, imgIOnloadBlocker) NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIInterfaceRequestor) diff --git a/content/html/content/test/test_bug389797.html b/content/html/content/test/test_bug389797.html index 0e7c7b8bc5c..862499aee62 100644 --- a/content/html/content/test/test_bug389797.html +++ b/content/html/content/test/test_bug389797.html @@ -72,7 +72,7 @@ function HTML_TAG(aTagName, aImplClass) { } const objectIfaces = [ - "imgIDecoderObserver", "nsIRequestObserver", "nsIStreamListener", + "imgINotificationObserver", "nsIRequestObserver", "nsIStreamListener", "nsIFrameLoaderOwner", "nsIObjectLoadingContent", "nsIInterfaceRequestor", "nsIChannelEventSink" ]; @@ -160,9 +160,9 @@ HTML_TAG("i", ""); HTML_TAG("iframe", "IFrame", [ "nsIDOMGetSVGDocument", "nsIDOMMozBrowserFrame" ], [ "nsIFrameLoaderOwner" ]); HTML_TAG("image", "Span"); -HTML_TAG("img", "Image", [], [ "imgIDecoderObserver", +HTML_TAG("img", "Image", [], [ "imgINotificationObserver", "nsIImageLoadingContent" ]); -HTML_TAG("input", "Input", [], [ "imgIDecoderObserver", +HTML_TAG("input", "Input", [], [ "imgINotificationObserver", "nsIImageLoadingContent", "nsIDOMNSEditableElement" ]); HTML_TAG("ins", "Mod"); diff --git a/content/html/document/src/ImageDocument.cpp b/content/html/document/src/ImageDocument.cpp index 3bb0d5a62e7..fd4cf87ff30 100644 --- a/content/html/document/src/ImageDocument.cpp +++ b/content/html/document/src/ImageDocument.cpp @@ -18,7 +18,7 @@ #include "imgIRequest.h" #include "imgILoader.h" #include "imgIContainer.h" -#include "nsStubImageDecoderObserver.h" +#include "imgINotificationObserver.h" #include "nsIPresShell.h" #include "nsPresContext.h" #include "nsStyleContext.h" @@ -64,7 +64,7 @@ public: class ImageDocument : public MediaDocument , public nsIImageDocument - , public nsStubImageDecoderObserver + , public imgINotificationObserver , public nsIDOMEventListener { public: @@ -89,12 +89,7 @@ public: nsIDOMEventTarget* aDispatchStartTarget); NS_DECL_NSIIMAGEDOCUMENT - - // imgIDecoderObserver (override nsStubImageDecoderObserver) - NS_IMETHOD OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage); - NS_IMETHOD OnStopContainer(imgIRequest* aRequest, imgIContainer* aImage); - NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult aStatus, const PRUnichar *aStatusArg); - NS_IMETHOD OnDiscard(imgIRequest *aRequest); + NS_DECL_IMGINOTIFICATIONOBSERVER // nsIDOMEventListener NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent); @@ -123,6 +118,9 @@ protected: void ResetZoomLevel(); float GetZoomLevel(); + nsresult OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage); + nsresult OnStopDecode(imgIRequest *aRequest, nsresult aStatus); + nsCOMPtr mImageContent; int32_t mVisibleWidth; @@ -238,8 +236,7 @@ DOMCI_NODE_DATA(ImageDocument, ImageDocument) NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(ImageDocument) NS_HTML_DOCUMENT_INTERFACE_TABLE_BEGIN(ImageDocument) NS_INTERFACE_TABLE_ENTRY(ImageDocument, nsIImageDocument) - NS_INTERFACE_TABLE_ENTRY(ImageDocument, imgIDecoderObserver) - NS_INTERFACE_TABLE_ENTRY(ImageDocument, imgIContainerObserver) + NS_INTERFACE_TABLE_ENTRY(ImageDocument, imgINotificationObserver) NS_INTERFACE_TABLE_ENTRY(ImageDocument, nsIDOMEventListener) NS_OFFSET_AND_INTERFACE_TABLE_END NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE @@ -509,6 +506,45 @@ ImageDocument::ToggleImageSize() } NS_IMETHODIMP +ImageDocument::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* aData) +{ + if (aType == imgINotificationObserver::START_CONTAINER) { + nsCOMPtr image; + aRequest->GetImage(getter_AddRefs(image)); + return OnStartContainer(aRequest, image); + } + + if (aType == imgINotificationObserver::STOP_CONTAINER) { + if (mImageContent) { + // Update the background-color of the image only after the + // image has been decoded to prevent flashes of just the + // background-color. + mImageContent->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, + NS_LITERAL_STRING("decoded"), true); + } + } + + if (aType == imgINotificationObserver::DISCARD) { + // mImageContent can be null if the document is already destroyed + if (mImageContent) { + // Remove any decoded-related styling when the image is unloaded. + mImageContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::_class, + true); + } + } + + if (aType == imgINotificationObserver::STOP_DECODE) { + uint32_t reqStatus; + aRequest->GetImageStatus(&reqStatus); + nsresult status = + reqStatus & imgIRequest::STATUS_ERROR ? NS_ERROR_FAILURE : NS_OK; + return OnStopDecode(aRequest, status); + } + + return NS_OK; +} + +nsresult ImageDocument::OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage) { aImage->GetWidth(&mImageWidth); @@ -521,24 +557,9 @@ ImageDocument::OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage) return NS_OK; } -NS_IMETHODIMP -ImageDocument::OnStopContainer(imgIRequest* aRequest, imgIContainer* aImage) -{ - if (mImageContent) { - // Update the background-color of the image only after the - // image has been decoded to prevent flashes of just the - // background-color. - mImageContent->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, - NS_LITERAL_STRING("decoded"), true); - } - - return NS_OK; -} - -NS_IMETHODIMP +nsresult ImageDocument::OnStopDecode(imgIRequest *aRequest, - nsresult aStatus, - const PRUnichar *aStatusArg) + nsresult aStatus) { UpdateTitleAndCharset(); @@ -559,18 +580,6 @@ ImageDocument::OnStopDecode(imgIRequest *aRequest, return NS_OK; } -NS_IMETHODIMP -ImageDocument::OnDiscard(imgIRequest *aRequest) -{ - // mImageContent can be null if the document is already destroyed - if (mImageContent) { - // Remove any decoded-related styling when the image is unloaded. - mImageContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::_class, - true); - } - return NS_OK; -} - NS_IMETHODIMP ImageDocument::HandleEvent(nsIDOMEvent* aEvent) { diff --git a/content/svg/content/src/nsSVGFilters.cpp b/content/svg/content/src/nsSVGFilters.cpp index fd205b4f997..6a88100265e 100644 --- a/content/svg/content/src/nsSVGFilters.cpp +++ b/content/svg/content/src/nsSVGFilters.cpp @@ -5505,7 +5505,7 @@ NS_INTERFACE_TABLE_HEAD(nsSVGFEImageElement) nsIDOMSVGElement, nsIDOMSVGFilterPrimitiveStandardAttributes, nsIDOMSVGFEImageElement, nsIDOMSVGURIReference, - imgIDecoderObserver, nsIImageLoadingContent, + imgINotificationObserver, nsIImageLoadingContent, imgIOnloadBlocker) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFEImageElement) NS_INTERFACE_MAP_END_INHERITING(nsSVGFEImageElementBase) @@ -5756,43 +5756,27 @@ nsSVGFEImageElement::GetStringInfo() } //---------------------------------------------------------------------- -// imgIDecoderObserver methods +// imgINotificationObserver methods NS_IMETHODIMP -nsSVGFEImageElement::OnStopDecode(imgIRequest *aRequest, - nsresult status, - const PRUnichar *statusArg) +nsSVGFEImageElement::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* aData) { - nsresult rv = - nsImageLoadingContent::OnStopDecode(aRequest, status, statusArg); - Invalidate(); - return rv; -} + nsresult rv = nsImageLoadingContent::Notify(aRequest, aType, aData); -NS_IMETHODIMP -nsSVGFEImageElement::FrameChanged(imgIRequest* aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect) -{ - nsresult rv = - nsImageLoadingContent::FrameChanged(aRequest, aContainer, aDirtyRect); - Invalidate(); - return rv; -} + if (aType == imgINotificationObserver::START_CONTAINER) { + // Request a decode + nsCOMPtr container; + aRequest->GetImage(getter_AddRefs(container)); + NS_ABORT_IF_FALSE(container, "who sent the notification then?"); + container->StartDecoding(); + } -NS_IMETHODIMP -nsSVGFEImageElement::OnStartContainer(imgIRequest *aRequest, - imgIContainer *aContainer) -{ - nsresult rv = - nsImageLoadingContent::OnStartContainer(aRequest, aContainer); + if (aType == imgINotificationObserver::STOP_DECODE || + aType == imgINotificationObserver::FRAME_CHANGED || + aType == imgINotificationObserver::START_CONTAINER) { + Invalidate(); + } - // Request a decode - NS_ABORT_IF_FALSE(aContainer, "who sent the notification then?"); - aContainer->StartDecoding(); - - // We have a size - invalidate - Invalidate(); return rv; } diff --git a/content/svg/content/src/nsSVGFilters.h b/content/svg/content/src/nsSVGFilters.h index d14253a463c..15b3df1f137 100644 --- a/content/svg/content/src/nsSVGFilters.h +++ b/content/svg/content/src/nsSVGFilters.h @@ -267,16 +267,7 @@ public: virtual void UnbindFromTree(bool aDeep, bool aNullParent); virtual nsEventStates IntrinsicState() const; - // imgIDecoderObserver - NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status, - const PRUnichar *statusArg); - // imgIContainerObserver - NS_IMETHOD FrameChanged(imgIRequest* aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect); - // imgIContainerObserver - NS_IMETHOD OnStartContainer(imgIRequest *aRequest, - imgIContainer *aContainer); + NS_IMETHODIMP Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData); void MaybeLoadSVGImage(); diff --git a/content/svg/content/src/nsSVGImageElement.cpp b/content/svg/content/src/nsSVGImageElement.cpp index 6031cf90068..86e7bdc23f9 100644 --- a/content/svg/content/src/nsSVGImageElement.cpp +++ b/content/svg/content/src/nsSVGImageElement.cpp @@ -10,7 +10,7 @@ #include "nsIURI.h" #include "nsNetUtil.h" #include "imgIContainer.h" -#include "imgIDecoderObserver.h" +#include "imgINotificationObserver.h" #include "gfxContext.h" using namespace mozilla; @@ -42,7 +42,7 @@ NS_INTERFACE_TABLE_HEAD(nsSVGImageElement) NS_NODE_INTERFACE_TABLE9(nsSVGImageElement, nsIDOMNode, nsIDOMElement, nsIDOMSVGElement, nsIDOMSVGTests, nsIDOMSVGImageElement, - nsIDOMSVGURIReference, imgIDecoderObserver, + nsIDOMSVGURIReference, imgINotificationObserver, nsIImageLoadingContent, imgIOnloadBlocker) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGImageElement) NS_INTERFACE_MAP_END_INHERITING(nsSVGImageElementBase) diff --git a/image/public/Makefile.in b/image/public/Makefile.in index 603ee85568f..b98f0cf2295 100644 --- a/image/public/Makefile.in +++ b/image/public/Makefile.in @@ -23,8 +23,10 @@ XPIDLSRCS = \ imgIDecoderObserver.idl \ imgIEncoder.idl \ imgILoader.idl \ + imgINotificationObserver.idl \ imgIOnloadBlocker.idl \ imgIRequest.idl \ + imgIScriptedNotificationObserver.idl \ imgITools.idl \ $(NULL) diff --git a/image/public/imgILoader.idl b/image/public/imgILoader.idl index e578b8587ee..9018fe5d89c 100644 --- a/image/public/imgILoader.idl +++ b/image/public/imgILoader.idl @@ -6,7 +6,7 @@ #include "nsISupports.idl" -interface imgIDecoderObserver; +interface imgINotificationObserver; interface imgIRequest; interface nsIChannel; @@ -61,7 +61,7 @@ interface imgILoader : nsISupports in nsIURI aReferrerURI, in nsIPrincipal aLoadingPrincipal, in nsILoadGroup aLoadGroup, - in imgIDecoderObserver aObserver, + in imgINotificationObserver aObserver, in nsISupports aCX, in nsLoadFlags aLoadFlags, in nsISupports cacheKey, @@ -86,7 +86,7 @@ interface imgILoader : nsISupports * make sure to Cancel() the resulting request before the observer goes away. */ imgIRequest loadImageWithChannel(in nsIChannel aChannel, - in imgIDecoderObserver aObserver, + in imgINotificationObserver aObserver, in nsISupports cx, out nsIStreamListener aListener); }; diff --git a/image/public/imgINotificationObserver.idl b/image/public/imgINotificationObserver.idl new file mode 100644 index 00000000000..30ac807ef27 --- /dev/null +++ b/image/public/imgINotificationObserver.idl @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +interface imgIRequest; + +%{C++ +#include "nsRect.h" +%} + +[ptr] native nsIntRect(nsIntRect); + +[scriptable, builtinclass, uuid(bf9ed307-02a5-4732-b3eb-659bde5de84f)] +interface imgINotificationObserver : nsISupports +{ + const long START_REQUEST = 1; + const long START_CONTAINER = 2; + const long START_FRAME = 3; + const long DATA_AVAILABLE = 4; + const long STOP_FRAME = 5; + const long STOP_CONTAINER = 6; + const long STOP_DECODE = 7; + const long DISCARD = 8; + const long IS_ANIMATED = 9; + const long FRAME_CHANGED = 10; + const long STOP_REQUEST = 11; + const long START_DECODE = 12; + + [noscript] void notify(in imgIRequest aProxy, in long aType, [const] in nsIntRect aRect); +}; diff --git a/image/public/imgIRequest.idl b/image/public/imgIRequest.idl index 8ac1bb1ddc1..6318f41fa08 100644 --- a/image/public/imgIRequest.idl +++ b/image/public/imgIRequest.idl @@ -8,7 +8,7 @@ #include "nsIRequest.idl" interface imgIContainer; -interface imgIDecoderObserver; +interface imgINotificationObserver; interface nsIURI; interface nsIPrincipal; @@ -19,7 +19,7 @@ interface nsIPrincipal; * @version 0.1 * @see imagelib2 */ -[scriptable, uuid(a5a785a8-9881-11e1-aaff-001fbc092072)] +[scriptable, uuid(3ea9fc87-2e97-45bf-b373-d1dd253a0b5e)] interface imgIRequest : nsIRequest { /** @@ -82,7 +82,7 @@ interface imgIRequest : nsIRequest */ readonly attribute nsIURI URI; - readonly attribute imgIDecoderObserver decoderObserver; + readonly attribute imgINotificationObserver notificationObserver; readonly attribute string mimeType; @@ -92,7 +92,7 @@ interface imgIRequest : nsIRequest * call returns) with all the notifications that have already been dispatched * for this image load. */ - imgIRequest clone(in imgIDecoderObserver aObserver); + imgIRequest clone(in imgINotificationObserver aObserver); /** * The principal gotten from the channel the image was loaded from. diff --git a/image/public/imgIScriptedNotificationObserver.idl b/image/public/imgIScriptedNotificationObserver.idl new file mode 100644 index 00000000000..f683acec8bf --- /dev/null +++ b/image/public/imgIScriptedNotificationObserver.idl @@ -0,0 +1,26 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +interface imgIRequest; + +[scriptable, uuid(1296bf6c-6067-424b-ba8e-389ec89ee48b)] +interface imgIScriptedNotificationObserver : nsISupports +{ + void startRequest(in imgIRequest aRequest); + void startContainer(in imgIRequest aRequest); + void startFrame(in imgIRequest aRequest); + void startDecode(in imgIRequest aRequest); + void dataAvailable(in imgIRequest aRequest); + void stopFrame(in imgIRequest aRequest); + void stopContainer(in imgIRequest aRequest); + void stopDecode(in imgIRequest aRequest); + void stopRequest(in imgIRequest aRequest); + void discard(in imgIRequest aRequest); + void isAnimated(in imgIRequest aRequest); + void frameChanged(in imgIRequest aRequest); +}; diff --git a/image/public/imgITools.idl b/image/public/imgITools.idl index c0754d66555..b1e442074c2 100644 --- a/image/public/imgITools.idl +++ b/image/public/imgITools.idl @@ -11,8 +11,10 @@ interface imgIContainer; interface imgILoader; interface imgICache; interface nsIDOMDocument; +interface imgIScriptedNotificationObserver; +interface imgINotificationObserver; -[scriptable, uuid(53dd1cbe-cb9f-4d9e-8104-1ab72851c88e)] +[scriptable, uuid(98bd5bf9-87eb-4d92-81b1-4cd10c64f7b2)] interface imgITools : nsISupports { /** @@ -123,4 +125,12 @@ interface imgITools : nsISupports in long aWidth, in long aHeight, [optional] in AString outputOptions); + + /** + * Create a wrapper around a scripted notification observer (ordinarily + * imgINotificationObserver cannot be implemented from scripts). + * + * @param aObserver The scripted observer to wrap + */ + imgINotificationObserver createScriptedObserver(in imgIScriptedNotificationObserver aObserver); }; diff --git a/image/src/Makefile.in b/image/src/Makefile.in index 93ff99c6485..92ed93a6c9f 100644 --- a/image/src/Makefile.in +++ b/image/src/Makefile.in @@ -27,6 +27,7 @@ CPPSRCS = \ Decoder.cpp \ DiscardTracker.cpp \ RasterImage.cpp \ + ScriptedNotificationObserver.cpp \ SVGDocumentWrapper.cpp \ VectorImage.cpp \ imgFrame.cpp \ diff --git a/image/src/ScriptedNotificationObserver.cpp b/image/src/ScriptedNotificationObserver.cpp new file mode 100644 index 00000000000..058e47460a9 --- /dev/null +++ b/image/src/ScriptedNotificationObserver.cpp @@ -0,0 +1,59 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ScriptedNotificationObserver.h" +#include "imgIScriptedNotificationObserver.h" +#include "nsCycleCollectionParticipant.h" + +using namespace mozilla::image; + +NS_IMPL_CYCLE_COLLECTION_1(ScriptedNotificationObserver, mInner) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ScriptedNotificationObserver) + NS_INTERFACE_MAP_ENTRY(imgINotificationObserver) + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTING_ADDREF(ScriptedNotificationObserver) +NS_IMPL_CYCLE_COLLECTING_RELEASE(ScriptedNotificationObserver) + +ScriptedNotificationObserver::ScriptedNotificationObserver( + imgIScriptedNotificationObserver* aInner) +: mInner(aInner) +{ +} + +NS_IMETHODIMP +ScriptedNotificationObserver::Notify(imgIRequest* aRequest, + int32_t aType, + const nsIntRect* /*aUnused*/) +{ + if (aType == imgINotificationObserver::START_REQUEST) + return mInner->StartRequest(aRequest); + if (aType == imgINotificationObserver::START_CONTAINER) + return mInner->StartContainer(aRequest); + if (aType == imgINotificationObserver::START_FRAME) + return mInner->StartFrame(aRequest); + if (aType == imgINotificationObserver::START_DECODE) + return mInner->StartDecode(aRequest); + if (aType == imgINotificationObserver::DATA_AVAILABLE) + return mInner->DataAvailable(aRequest); + if (aType == imgINotificationObserver::STOP_FRAME) + return mInner->StopFrame(aRequest); + if (aType == imgINotificationObserver::STOP_CONTAINER) + return mInner->StopContainer(aRequest); + if (aType == imgINotificationObserver::STOP_DECODE) + return mInner->StopDecode(aRequest); + if (aType == imgINotificationObserver::STOP_REQUEST) + return mInner->StopRequest(aRequest); + if (aType == imgINotificationObserver::DISCARD) + return mInner->StopRequest(aRequest); + if (aType == imgINotificationObserver::IS_ANIMATED) + return mInner->IsAnimated(aRequest); + if (aType == imgINotificationObserver::FRAME_CHANGED) + return mInner->FrameChanged(aRequest); + return NS_OK; +} diff --git a/image/src/ScriptedNotificationObserver.h b/image/src/ScriptedNotificationObserver.h new file mode 100644 index 00000000000..3907ef89c7d --- /dev/null +++ b/image/src/ScriptedNotificationObserver.h @@ -0,0 +1,30 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "imgINotificationObserver.h" +#include "nsCOMPtr.h" +#include "nsCycleCollectionParticipant.h" + +class imgIScriptedNotificationObserver; + +namespace mozilla { +namespace image { + +class ScriptedNotificationObserver : public imgINotificationObserver +{ +public: + ScriptedNotificationObserver(imgIScriptedNotificationObserver* aInner); + virtual ~ScriptedNotificationObserver() {} + + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_IMGINOTIFICATIONOBSERVER + NS_DECL_CYCLE_COLLECTION_CLASS(ScriptedNotificationObserver) + +private: + nsCOMPtr mInner; +}; + +}} diff --git a/image/src/imgLoader.cpp b/image/src/imgLoader.cpp index 509328bdbc9..49211280cb9 100644 --- a/image/src/imgLoader.cpp +++ b/image/src/imgLoader.cpp @@ -680,7 +680,7 @@ imgCacheQueue::const_iterator imgCacheQueue::end() const } nsresult imgLoader::CreateNewProxyForRequest(imgRequest *aRequest, nsILoadGroup *aLoadGroup, - imgIDecoderObserver *aObserver, + imgINotificationObserver *aObserver, nsLoadFlags aLoadFlags, imgIRequest *aProxyRequest, imgIRequest **_retval) { @@ -1162,7 +1162,7 @@ bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request, nsIURI *aInitialDocumentURI, nsIURI *aReferrerURI, nsILoadGroup *aLoadGroup, - imgIDecoderObserver *aObserver, + imgINotificationObserver *aObserver, nsISupports *aCX, nsLoadFlags aLoadFlags, imgIRequest *aExistingRequest, @@ -1284,7 +1284,7 @@ bool imgLoader::ValidateEntry(imgCacheEntry *aEntry, nsIURI *aInitialDocumentURI, nsIURI *aReferrerURI, nsILoadGroup *aLoadGroup, - imgIDecoderObserver *aObserver, + imgINotificationObserver *aObserver, nsISupports *aCX, nsLoadFlags aLoadFlags, bool aCanMakeNewChannel, @@ -1521,14 +1521,14 @@ nsresult imgLoader::EvictEntries(imgCacheQueue &aQueueToClear) nsIRequest::VALIDATE_ONCE_PER_SESSION) -/* imgIRequest loadImage (in nsIURI aURI, in nsIURI initialDocumentURI, in nsIPrincipal loadingPrincipal, in nsILoadGroup aLoadGroup, in imgIDecoderObserver aObserver, in nsISupports aCX, in nsLoadFlags aLoadFlags, in nsISupports cacheKey, in imgIRequest aRequest); */ +/* imgIRequest loadImage (in nsIURI aURI, in nsIURI initialDocumentURI, in nsIPrincipal loadingPrincipal, in nsILoadGroup aLoadGroup, in imgINotificationObserver aObserver, in nsISupports aCX, in nsLoadFlags aLoadFlags, in nsISupports cacheKey, in imgIRequest aRequest); */ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI, nsIURI *aInitialDocumentURI, nsIURI *aReferrerURI, nsIPrincipal* aLoadingPrincipal, nsILoadGroup *aLoadGroup, - imgIDecoderObserver *aObserver, + imgINotificationObserver *aObserver, nsISupports *aCX, nsLoadFlags aLoadFlags, nsISupports *aCacheKey, @@ -1784,8 +1784,8 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI, return NS_OK; } -/* imgIRequest loadImageWithChannel(in nsIChannel channel, in imgIDecoderObserver aObserver, in nsISupports cx, out nsIStreamListener); */ -NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderObserver *aObserver, nsISupports *aCX, nsIStreamListener **listener, imgIRequest **_retval) +/* imgIRequest loadImageWithChannel(in nsIChannel channel, in imgINotificationObserver aObserver, in nsISupports cx, out nsIStreamListener); */ +NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgINotificationObserver *aObserver, nsISupports *aCX, nsIStreamListener **listener, imgIRequest **_retval) { NS_ASSERTION(channel, "imgLoader::LoadImageWithChannel -- NULL channel pointer"); diff --git a/image/src/imgLoader.h b/image/src/imgLoader.h index f58cadc865a..318b7c0d3d5 100644 --- a/image/src/imgLoader.h +++ b/image/src/imgLoader.h @@ -30,7 +30,7 @@ class imgLoader; class imgRequest; class imgRequestProxy; class imgIRequest; -class imgIDecoderObserver; +class imgINotificationObserver; class nsILoadGroup; class imgCacheExpirationTracker; class imgMemoryReporter; @@ -289,7 +289,7 @@ private: // methods bool ValidateEntry(imgCacheEntry *aEntry, nsIURI *aKey, nsIURI *aInitialDocumentURI, nsIURI *aReferrerURI, nsILoadGroup *aLoadGroup, - imgIDecoderObserver *aObserver, nsISupports *aCX, + imgINotificationObserver *aObserver, nsISupports *aCX, nsLoadFlags aLoadFlags, bool aCanMakeNewChannel, imgIRequest *aExistingRequest, imgIRequest **aProxyRequest, @@ -300,7 +300,7 @@ private: // methods nsIURI *aInitialDocumentURI, nsIURI *aReferrerURI, nsILoadGroup *aLoadGroup, - imgIDecoderObserver *aObserver, + imgINotificationObserver *aObserver, nsISupports *aCX, nsLoadFlags aLoadFlags, imgIRequest *aExistingRequest, imgIRequest **aProxyRequest, @@ -309,7 +309,7 @@ private: // methods int32_t aCORSMode); nsresult CreateNewProxyForRequest(imgRequest *aRequest, nsILoadGroup *aLoadGroup, - imgIDecoderObserver *aObserver, + imgINotificationObserver *aObserver, nsLoadFlags aLoadFlags, imgIRequest *aRequestProxy, imgIRequest **_retval); diff --git a/image/src/imgRequestProxy.cpp b/image/src/imgRequestProxy.cpp index d07eaf93fd6..ac98162561b 100644 --- a/image/src/imgRequestProxy.cpp +++ b/image/src/imgRequestProxy.cpp @@ -90,7 +90,7 @@ imgRequestProxy::~imgRequestProxy() nsresult imgRequestProxy::Init(imgStatusTracker* aStatusTracker, nsILoadGroup* aLoadGroup, - nsIURI* aURI, imgIDecoderObserver* aObserver) + nsIURI* aURI, imgINotificationObserver* aObserver) { NS_PRECONDITION(!mOwner && !mListener, "imgRequestProxy is already initialized"); @@ -458,11 +458,11 @@ NS_IMETHODIMP imgRequestProxy::GetURI(nsIURI **aURI) return NS_OK; } -/* readonly attribute imgIDecoderObserver decoderObserver; */ -NS_IMETHODIMP imgRequestProxy::GetDecoderObserver(imgIDecoderObserver **aDecoderObserver) +/* readonly attribute imgINotificationObserver notificationObserver; */ +NS_IMETHODIMP imgRequestProxy::GetNotificationObserver(imgINotificationObserver **aObserver) { - *aDecoderObserver = mListener; - NS_IF_ADDREF(*aDecoderObserver); + *aObserver = mListener; + NS_IF_ADDREF(*aObserver); return NS_OK; } @@ -481,7 +481,7 @@ NS_IMETHODIMP imgRequestProxy::GetMimeType(char **aMimeType) return NS_OK; } -NS_IMETHODIMP imgRequestProxy::Clone(imgIDecoderObserver* aObserver, +NS_IMETHODIMP imgRequestProxy::Clone(imgINotificationObserver* aObserver, imgIRequest** aClone) { NS_PRECONDITION(aClone, "Null out param"); @@ -591,8 +591,6 @@ NS_IMETHODIMP imgRequestProxy::GetHasTransferredData(bool* hasData) return NS_OK; } -/** imgIContainerObserver methods **/ - void imgRequestProxy::FrameChanged(imgIContainer *container, const nsIntRect *dirtyRect) { @@ -600,8 +598,8 @@ void imgRequestProxy::FrameChanged(imgIContainer *container, if (mListener && !mCanceled) { // Hold a ref to the listener while we call it, just in case. - nsCOMPtr kungFuDeathGrip(mListener); - mListener->FrameChanged(this, container, dirtyRect); + nsCOMPtr kungFuDeathGrip(mListener); + mListener->Notify(this, imgINotificationObserver::FRAME_CHANGED, dirtyRect); } } @@ -613,8 +611,8 @@ void imgRequestProxy::OnStartDecode() if (mListener && !mCanceled) { // Hold a ref to the listener while we call it, just in case. - nsCOMPtr kungFuDeathGrip(mListener); - mListener->OnStartDecode(this); + nsCOMPtr kungFuDeathGrip(mListener); + mListener->Notify(this, imgINotificationObserver::START_DECODE, nullptr); } } @@ -624,8 +622,8 @@ void imgRequestProxy::OnStartContainer(imgIContainer *image) if (mListener && !mCanceled && !mSentStartContainer) { // Hold a ref to the listener while we call it, just in case. - nsCOMPtr kungFuDeathGrip(mListener); - mListener->OnStartContainer(this, image); + nsCOMPtr kungFuDeathGrip(mListener); + mListener->Notify(this, imgINotificationObserver::START_CONTAINER, nullptr); mSentStartContainer = true; } } @@ -636,8 +634,8 @@ void imgRequestProxy::OnStartFrame(uint32_t frame) if (mListener && !mCanceled) { // Hold a ref to the listener while we call it, just in case. - nsCOMPtr kungFuDeathGrip(mListener); - mListener->OnStartFrame(this, frame); + nsCOMPtr kungFuDeathGrip(mListener); + mListener->Notify(this, imgINotificationObserver::START_FRAME, nullptr); } } @@ -647,8 +645,8 @@ void imgRequestProxy::OnDataAvailable(bool aCurrentFrame, const nsIntRect * rect if (mListener && !mCanceled) { // Hold a ref to the listener while we call it, just in case. - nsCOMPtr kungFuDeathGrip(mListener); - mListener->OnDataAvailable(this, aCurrentFrame, rect); + nsCOMPtr kungFuDeathGrip(mListener); + mListener->Notify(this, imgINotificationObserver::DATA_AVAILABLE, rect); } } @@ -658,8 +656,8 @@ void imgRequestProxy::OnStopFrame(uint32_t frame) if (mListener && !mCanceled) { // Hold a ref to the listener while we call it, just in case. - nsCOMPtr kungFuDeathGrip(mListener); - mListener->OnStopFrame(this, frame); + nsCOMPtr kungFuDeathGrip(mListener); + mListener->Notify(this, imgINotificationObserver::STOP_FRAME, nullptr); } } @@ -669,8 +667,8 @@ void imgRequestProxy::OnStopContainer(imgIContainer *image) if (mListener && !mCanceled) { // Hold a ref to the listener while we call it, just in case. - nsCOMPtr kungFuDeathGrip(mListener); - mListener->OnStopContainer(this, image); + nsCOMPtr kungFuDeathGrip(mListener); + mListener->Notify(this, imgINotificationObserver::STOP_CONTAINER, nullptr); } // Multipart needs reset for next OnStartContainer @@ -684,8 +682,8 @@ void imgRequestProxy::OnStopDecode(nsresult status, const PRUnichar *statusArg) if (mListener && !mCanceled) { // Hold a ref to the listener while we call it, just in case. - nsCOMPtr kungFuDeathGrip(mListener); - mListener->OnStopDecode(this, status, statusArg); + nsCOMPtr kungFuDeathGrip(mListener); + mListener->Notify(this, imgINotificationObserver::STOP_DECODE, nullptr); } } @@ -695,8 +693,8 @@ void imgRequestProxy::OnDiscard() if (mListener && !mCanceled) { // Hold a ref to the listener while we call it, just in case. - nsCOMPtr kungFuDeathGrip(mListener); - mListener->OnDiscard(this); + nsCOMPtr kungFuDeathGrip(mListener); + mListener->Notify(this, imgINotificationObserver::DISCARD, nullptr); } } @@ -705,8 +703,8 @@ void imgRequestProxy::OnImageIsAnimated() LOG_FUNC(gImgLog, "imgRequestProxy::OnImageIsAnimated"); if (mListener && !mCanceled) { // Hold a ref to the listener while we call it, just in case. - nsCOMPtr kungFuDeathGrip(mListener); - mListener->OnImageIsAnimated(this); + nsCOMPtr kungFuDeathGrip(mListener); + mListener->Notify(this, imgINotificationObserver::IS_ANIMATED, nullptr); } } @@ -722,8 +720,8 @@ void imgRequestProxy::OnStartRequest() // nsIStreamListener contract so it makes sense to do the same here. if (mListener) { // Hold a ref to the listener while we call it, just in case. - nsCOMPtr kungFuDeathGrip(mListener); - mListener->OnStartRequest(this); + nsCOMPtr kungFuDeathGrip(mListener); + mListener->Notify(this, imgINotificationObserver::START_REQUEST, nullptr); } } @@ -741,8 +739,8 @@ void imgRequestProxy::OnStopRequest(bool lastPart) if (mListener) { // Hold a ref to the listener while we call it, just in case. - nsCOMPtr kungFuDeathGrip(mListener); - mListener->OnStopRequest(this, lastPart); + nsCOMPtr kungFuDeathGrip(mListener); + mListener->Notify(this, imgINotificationObserver::STOP_REQUEST, nullptr); } // If we're expecting more data from a multipart channel, re-add ourself @@ -764,7 +762,7 @@ void imgRequestProxy::OnStopRequest(bool lastPart) // Drop our strong ref to the listener now that we're done with // everything. Note that this can cancel us and other fun things // like that. Don't add anything in this method after this point. - imgIDecoderObserver* obs = mListener; + imgINotificationObserver* obs = mListener; mListenerIsStrongRef = false; NS_RELEASE(obs); } @@ -806,7 +804,7 @@ void imgRequestProxy::NullOutListener() if (mListenerIsStrongRef) { // Releasing could do weird reentery stuff, so just play it super-safe - nsCOMPtr obs; + nsCOMPtr obs; obs.swap(mListener); mListenerIsStrongRef = false; } else { diff --git a/image/src/imgRequestProxy.h b/image/src/imgRequestProxy.h index 363e1ee0df3..6e1c9f4fed4 100644 --- a/image/src/imgRequestProxy.h +++ b/image/src/imgRequestProxy.h @@ -8,7 +8,7 @@ #define imgRequestProxy_h__ #include "imgIRequest.h" -#include "imgIDecoderObserver.h" +#include "imgINotificationObserver.h" #include "nsISecurityInfoProvider.h" #include "nsIRequestObserver.h" @@ -59,7 +59,7 @@ public: // (although not immediately after) doing so. nsresult Init(imgStatusTracker* aStatusTracker, nsILoadGroup *aLoadGroup, - nsIURI* aURI, imgIDecoderObserver *aObserver); + nsIURI* aURI, imgINotificationObserver *aObserver); nsresult ChangeOwner(imgRequest *aNewOwner); // this will change mOwner. Do not call this if the previous // owner has already sent notifications out! @@ -199,7 +199,7 @@ private: // mListener is only promised to be a weak ref (see imgILoader.idl), // but we actually keep a strong ref to it until we've seen our // first OnStopRequest. - imgIDecoderObserver* mListener; + imgINotificationObserver* mListener; nsCOMPtr mLoadGroup; nsLoadFlags mLoadFlags; diff --git a/image/src/imgTools.cpp b/image/src/imgTools.cpp index 1cb12fb67c7..7a8bbba600f 100644 --- a/image/src/imgTools.cpp +++ b/image/src/imgTools.cpp @@ -23,6 +23,8 @@ #include "nsNetUtil.h" #include "nsContentUtils.h" #include "RasterImage.h" +#include "ScriptedNotificationObserver.h" +#include "imgIScriptedNotificationObserver.h" using namespace mozilla::image; @@ -276,6 +278,13 @@ NS_IMETHODIMP imgTools::GetFirstImageFrame(imgIContainer *aContainer, return NS_OK; } +NS_IMETHODIMP imgTools::CreateScriptedObserver(imgIScriptedNotificationObserver* aInner, + imgINotificationObserver** aObserver) +{ + NS_ADDREF(*aObserver = new ScriptedNotificationObserver(aInner)); + return NS_OK; +} + NS_IMETHODIMP imgTools::GetImgLoaderForDocument(nsIDOMDocument* aDoc, imgILoader** aLoader) { diff --git a/image/test/mochitest/imgutils.js b/image/test/mochitest/imgutils.js index f81c527305e..1d27a6089b4 100644 --- a/image/test/mochitest/imgutils.js +++ b/image/test/mochitest/imgutils.js @@ -121,15 +121,19 @@ function getImagePref(pref) return null; } -// JS implementation of imgIDecoderObserver with stubs for all of its methods. +// JS implementation of imgIScriptedNotificationObserver with stubs for all of its methods. function ImageDecoderObserverStub() { - this.onStartRequest = function onStartRequest(aRequest) {} - this.onStartDecode = function onStartDecode(aRequest) {} - this.onStartContainer = function onStartContainer(aRequest, aContainer) {} - this.onStartFrame = function onStartFrame(aRequest, aFrame) {} - this.onStopFrame = function onStopFrame(aRequest, aFrame) {} - this.onStopContainer = function onStopContainer(aRequest, aContainer) {} - this.onStopDecode = function onStopDecode(aRequest, status, statusArg) {} - this.onStopRequest = function onStopRequest(aRequest, aIsLastPart) {} + this.startRequest = function startRequest(aRequest) {} + this.startDecode = function startDecode(aRequest) {} + this.startContainer = function startContainer(aRequest) {} + this.startFrame = function startFrame(aRequest) {} + this.stopFrame = function stopFrame(aRequest) {} + this.stopContainer = function stopContainer(aRequest) {} + this.stopDecode = function stopDecode(aRequest) {} + this.stopRequest = function stopRequest(aRequest) {} + this.dataAvailable = function dataAvailable(aRequest) {} + this.discard = function discard(aRequest) {} + this.isAnimated = function isAnimated(aRequest) {} + this.frameChanged = function frameChanged(aRequest) {} } diff --git a/image/test/mochitest/test_animSVGImage.html b/image/test/mochitest/test_animSVGImage.html index e1941689174..a1799b3f87e 100644 --- a/image/test/mochitest/test_animSVGImage.html +++ b/image/test/mochitest/test_animSVGImage.html @@ -26,6 +26,7 @@ SimpleTest.waitForExplicitFinish(); const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes) +const Cc = Components.classes; const Ci = Components.interfaces; const gImg = document.getElementsByTagName("img")[0]; @@ -53,7 +54,7 @@ function takeReferenceSnapshot() { "reference div should disappear when it becomes display:none"); } -function myOnStopFrame(aRequest, aFrame) { +function myOnStopFrame(aRequest) { gOnStopFrameCounter++; ok(true, "myOnStopFrame called"); let currentSnapshot = snapshotWindow(window, false); @@ -89,8 +90,11 @@ function main() { takeReferenceSnapshot(); // Create, customize & attach decoder observer - gMyDecoderObserver = new ImageDecoderObserverStub(); - gMyDecoderObserver.onStopFrame = myOnStopFrame; + observer = new ImageDecoderObserverStub(); + observer.stopFrame = myOnStopFrame; + gMyDecoderObserver = + Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) + .createScriptedObserver(observer); let imgLoadingContent = gImg.QueryInterface(Ci.nsIImageLoadingContent); imgLoadingContent.addObserver(gMyDecoderObserver); diff --git a/image/test/unit/async_load_tests.js b/image/test/unit/async_load_tests.js index f2346f79fb0..54b5ce1fc11 100644 --- a/image/test/unit/async_load_tests.js +++ b/image/test/unit/async_load_tests.js @@ -45,12 +45,22 @@ function checkClone(other_listener, aRequest) // For as long as clone notification is synchronous, we can't test the clone state reliably. var listener = new ImageListener(null, function(foo, bar) { do_test_finished(); } /*getCloneStopCallback(other_listener)*/); listener.synchronous = false; - var clone = aRequest.clone(listener); + var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) + .createScriptedObserver(listener); + var clone = aRequest.clone(outer); } // Ensure that all the callbacks were called on aRequest. function checkAllCallbacks(listener, aRequest) { + do_check_neq(listener.state & START_REQUEST, 0); + do_check_neq(listener.state & START_DECODE, 0); + do_check_neq(listener.state & START_CONTAINER, 0); + do_check_neq(listener.state & START_FRAME, 0); + do_check_neq(listener.state & STOP_FRAME, 0); + do_check_neq(listener.state & STOP_CONTAINER, 0); + do_check_neq(listener.state & STOP_DECODE, 0); + do_check_neq(listener.state & STOP_REQUEST, 0); do_check_eq(listener.state, ALL_BITS); do_test_finished(); @@ -67,7 +77,9 @@ function secondLoadDone(oldlistener, aRequest) // clone state reliably. var listener = new ImageListener(null, checkAllCallbacks); listener.synchronous = false; - var staticrequestclone = staticrequest.clone(listener); + var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) + .createScriptedObserver(listener); + var staticrequestclone = staticrequest.clone(outer); } catch(e) { // We can't create a static request. Most likely the request we started // with didn't load successfully. @@ -86,7 +98,9 @@ function checkSecondLoad() do_test_pending(); var listener = new ImageListener(checkClone, secondLoadDone); - requests.push(gCurrentLoader.loadImage(uri, null, null, null, null, listener, null, 0, null, null, null)); + var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) + .createScriptedObserver(listener); + requests.push(gCurrentLoader.loadImage(uri, null, null, null, null, outer, null, 0, null, null, null)); listener.synchronous = false; } @@ -141,8 +155,10 @@ function checkSecondChannelLoad() var listener = new ImageListener(getChannelLoadImageStartCallback(channellistener), getChannelLoadImageStopCallback(channellistener, all_done_callback)); + var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) + .createScriptedObserver(listener); var outlistener = {}; - requests.push(gCurrentLoader.loadImageWithChannel(channel, listener, null, outlistener)); + requests.push(gCurrentLoader.loadImageWithChannel(channel, outer, null, outlistener)); channellistener.outputListener = outlistener.value; listener.synchronous = false; @@ -163,8 +179,10 @@ function run_loadImageWithChannel_tests() var listener = new ImageListener(getChannelLoadImageStartCallback(channellistener), getChannelLoadImageStopCallback(channellistener, checkSecondChannelLoad)); + var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) + .createScriptedObserver(listener); var outlistener = {}; - requests.push(gCurrentLoader.loadImageWithChannel(channel, listener, null, outlistener)); + requests.push(gCurrentLoader.loadImageWithChannel(channel, outer, null, outlistener)); channellistener.outputListener = outlistener.value; listener.synchronous = false; @@ -182,7 +200,9 @@ function startImageCallback(otherCb) // Make sure we can load the same image immediately out of the cache. do_test_pending(); var listener2 = new ImageListener(null, function(foo, bar) { do_test_finished(); }); - requests.push(gCurrentLoader.loadImage(uri, null, null, null, null, listener2, null, 0, null, null, null)); + var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) + .createScriptedObserver(listener2); + requests.push(gCurrentLoader.loadImage(uri, null, null, null, null, outer, null, 0, null, null, null)); listener2.synchronous = false; // Now that we've started another load, chain to the callback. @@ -198,7 +218,9 @@ function run_test() do_test_pending(); var listener = new ImageListener(startImageCallback(checkClone), firstLoadDone); - var req = gCurrentLoader.loadImage(uri, null, null, null, null, listener, null, 0, null, null, null); + var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) + .createScriptedObserver(listener); + var req = gCurrentLoader.loadImage(uri, null, null, null, null, outer, null, 0, null, null, null); requests.push(req); // Ensure that we don't cause any mayhem when we lock an image. diff --git a/image/test/unit/image_load_helpers.js b/image/test/unit/image_load_helpers.js index 44a02b1a12c..932b5f73c25 100644 --- a/image/test/unit/image_load_helpers.js +++ b/image/test/unit/image_load_helpers.js @@ -20,7 +20,7 @@ const ALL_BITS = 0xFF; // functions on onStartRequest and onStopRequest. function ImageListener(start_callback, stop_callback) { - this.onStartRequest = function onStartRequest(aRequest) + this.startRequest = function onStartRequest(aRequest) { do_check_false(this.synchronous); @@ -29,43 +29,43 @@ function ImageListener(start_callback, stop_callback) if (this.start_callback) this.start_callback(this, aRequest); } - this.onStartDecode = function onStartDecode(aRequest) + this.startDecode = function onStartDecode(aRequest) { do_check_false(this.synchronous); this.state |= START_DECODE; } - this.onStartContainer = function onStartContainer(aRequest, aContainer) + this.startContainer = function onStartContainer(aRequest) { do_check_false(this.synchronous); this.state |= START_CONTAINER; } - this.onStartFrame = function onStartFrame(aRequest, aFrame) + this.startFrame = function onStartFrame(aRequest) { do_check_false(this.synchronous); this.state |= START_FRAME; } - this.onStopFrame = function onStopFrame(aRequest, aFrame) + this.stopFrame = function onStopFrame(aRequest) { do_check_false(this.synchronous); this.state |= STOP_FRAME; } - this.onStopContainer = function onStopContainer(aRequest, aContainer) + this.stopContainer = function onStopContainer(aRequest) { do_check_false(this.synchronous); this.state |= STOP_CONTAINER; } - this.onStopDecode = function onStopDecode(aRequest, status, statusArg) + this.stopDecode = function onStopDecode(aRequest) { do_check_false(this.synchronous); this.state |= STOP_DECODE; } - this.onStopRequest = function onStopRequest(aRequest, aIsLastPart) + this.stopRequest = function onStopRequest(aRequest) { do_check_false(this.synchronous); @@ -82,6 +82,9 @@ function ImageListener(start_callback, stop_callback) if (this.stop_callback) this.stop_callback(this, aRequest); } + this.dataAvailable = function onDataAvailable(aRequest) + { + } // Initialize the synchronous flag to true to start. This must be set to // false before exiting to the event loop! diff --git a/image/test/unit/test_private_channel.js b/image/test/unit/test_private_channel.js index d15eb4613c8..6682f3ce3a5 100644 --- a/image/test/unit/test_private_channel.js +++ b/image/test/unit/test_private_channel.js @@ -55,21 +55,25 @@ function setup_chan(path, isPrivate, callback) { chan.asyncOpen(channelListener, null); var listener = new ImageListener(null, callback); - listeners.push(listener); var outlistener = {}; var loader = isPrivate ? gPrivateLoader : gPublicLoader; - requests.push(loader.loadImageWithChannel(chan, listener, null, outlistener)); + var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) + .createScriptedObserver(listener); + listeners.push(outer); + requests.push(loader.loadImageWithChannel(chan, outer, null, outlistener)); channelListener.outputListener = outlistener.value; listener.synchronous = false; } function loadImage(isPrivate, callback) { var listener = new ImageListener(null, callback); + var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) + .createScriptedObserver(listener); var uri = gIoService.newURI(gImgPath, null, null); var loadGroup = Cc["@mozilla.org/network/load-group;1"].createInstance(Ci.nsILoadGroup); loadGroup.notificationCallbacks = new NotificationCallbacks(isPrivate); var loader = isPrivate ? gPrivateLoader : gPublicLoader; - requests.push(loader.loadImage(uri, null, null, null, loadGroup, listener, null, 0, null, null, null)); + requests.push(loader.loadImage(uri, null, null, null, loadGroup, outer, null, 0, null, null, null)); listener.synchronous = false; } diff --git a/layout/generic/nsBulletFrame.cpp b/layout/generic/nsBulletFrame.cpp index 68b2dafbfc0..b9f54682435 100644 --- a/layout/generic/nsBulletFrame.cpp +++ b/layout/generic/nsBulletFrame.cpp @@ -1431,9 +1431,37 @@ nsBulletFrame::GetPrefWidth(nsRenderingContext *aRenderingContext) return metrics.width; } +NS_IMETHODIMP +nsBulletFrame::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) +{ + if (aType == imgINotificationObserver::START_CONTAINER) { + nsCOMPtr image; + aRequest->GetImage(getter_AddRefs(image)); + return OnStartContainer(aRequest, image); + } -NS_IMETHODIMP nsBulletFrame::OnStartContainer(imgIRequest *aRequest, - imgIContainer *aImage) + if (aType == imgINotificationObserver::DATA_AVAILABLE || + aType == imgINotificationObserver::FRAME_CHANGED) { + // The image has changed. + // Invalidate the entire content area. Maybe it's not optimal but it's simple and + // always correct, and I'll be a stunned mullet if it ever matters for performance + InvalidateFrame(); + } + + if (aType == imgINotificationObserver::IS_ANIMATED) { + // Register the image request with the refresh driver now that we know it's + // animated. + if (aRequest == mImageRequest) { + nsLayoutUtils::RegisterImageRequest(PresContext(), mImageRequest, + &mRequestRegistered); + } + } + + return NS_OK; +} + +nsresult nsBulletFrame::OnStartContainer(imgIRequest *aRequest, + imgIContainer *aImage) { if (!aImage) return NS_ERROR_INVALID_ARG; if (!aRequest) return NS_ERROR_INVALID_ARG; @@ -1475,60 +1503,6 @@ NS_IMETHODIMP nsBulletFrame::OnStartContainer(imgIRequest *aRequest, return NS_OK; } -NS_IMETHODIMP nsBulletFrame::OnDataAvailable(imgIRequest *aRequest, - bool aCurrentFrame, - const nsIntRect *aRect) -{ - // The image has changed. - // Invalidate the entire content area. Maybe it's not optimal but it's simple and - // always correct, and I'll be a stunned mullet if it ever matters for performance - InvalidateFrame(); - - return NS_OK; -} - -NS_IMETHODIMP nsBulletFrame::OnStopDecode(imgIRequest *aRequest, - nsresult aStatus, - const PRUnichar *aStatusArg) -{ - // XXX should the bulletframe do anything if the image failed to load? - // it didn't in the old code... - -#if 0 - if (NS_FAILED(aStatus)) { - // We failed to load the image. Notify the pres shell - if (NS_FAILED(aStatus) && (mImageRequest == aRequest || !mImageRequest)) { - imageFailed = true; - } - } -#endif - - return NS_OK; -} - -NS_IMETHODIMP nsBulletFrame::OnImageIsAnimated(imgIRequest* aRequest) -{ - // Register the image request with the refresh driver now that we know it's - // animated. - if (aRequest == mImageRequest) { - nsLayoutUtils::RegisterImageRequest(PresContext(), mImageRequest, - &mRequestRegistered); - } - - return NS_OK; -} - -NS_IMETHODIMP nsBulletFrame::FrameChanged(imgIRequest *aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect) -{ - // Invalidate the entire content area. Maybe it's not optimal but it's simple and - // always correct. - InvalidateFrame(); - - return NS_OK; -} - void nsBulletFrame::GetLoadGroup(nsPresContext *aPresContext, nsILoadGroup **aLoadGroup) { @@ -1624,7 +1598,7 @@ nsBulletFrame::GetBaseline() const -NS_IMPL_ISUPPORTS2(nsBulletListener, imgIDecoderObserver, imgIContainerObserver) +NS_IMPL_ISUPPORTS1(nsBulletListener, imgINotificationObserver) nsBulletListener::nsBulletListener() : mFrame(nullptr) @@ -1635,49 +1609,10 @@ nsBulletListener::~nsBulletListener() { } -NS_IMETHODIMP nsBulletListener::OnStartContainer(imgIRequest *aRequest, - imgIContainer *aImage) +NS_IMETHODIMP +nsBulletListener::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) { if (!mFrame) return NS_ERROR_FAILURE; - - return mFrame->OnStartContainer(aRequest, aImage); -} - -NS_IMETHODIMP nsBulletListener::OnDataAvailable(imgIRequest *aRequest, - bool aCurrentFrame, - const nsIntRect *aRect) -{ - if (!mFrame) - return NS_OK; - - return mFrame->OnDataAvailable(aRequest, aCurrentFrame, aRect); -} - -NS_IMETHODIMP nsBulletListener::OnStopDecode(imgIRequest *aRequest, - nsresult status, - const PRUnichar *statusArg) -{ - if (!mFrame) - return NS_OK; - - return mFrame->OnStopDecode(aRequest, status, statusArg); -} - -NS_IMETHODIMP nsBulletListener::OnImageIsAnimated(imgIRequest *aRequest) -{ - if (!mFrame) - return NS_OK; - - return mFrame->OnImageIsAnimated(aRequest); -} - -NS_IMETHODIMP nsBulletListener::FrameChanged(imgIRequest *aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect) -{ - if (!mFrame) - return NS_OK; - - return mFrame->FrameChanged(aRequest, aContainer, aDirtyRect); + return mFrame->Notify(aRequest, aType, aData); } diff --git a/layout/generic/nsBulletFrame.h b/layout/generic/nsBulletFrame.h index 96df3cceffd..c51a8e94c90 100644 --- a/layout/generic/nsBulletFrame.h +++ b/layout/generic/nsBulletFrame.h @@ -14,32 +14,21 @@ #include "imgIRequest.h" #include "imgIDecoderObserver.h" -#include "nsStubImageDecoderObserver.h" +#include "imgINotificationObserver.h" #define BULLET_FRAME_IMAGE_LOADING NS_FRAME_STATE_BIT(63) #define BULLET_FRAME_HAS_FONT_INFLATION NS_FRAME_STATE_BIT(62) class nsBulletFrame; -class nsBulletListener : public nsStubImageDecoderObserver +class nsBulletListener : public imgINotificationObserver { public: nsBulletListener(); virtual ~nsBulletListener(); NS_DECL_ISUPPORTS - // imgIDecoderObserver (override nsStubImageDecoderObserver) - NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage); - NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, bool aCurrentFrame, - const nsIntRect *aRect); - NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status, - const PRUnichar *statusArg); - NS_IMETHOD OnImageIsAnimated(imgIRequest *aRequest); - - // imgIContainerObserver (override nsStubImageDecoderObserver) - NS_IMETHOD FrameChanged(imgIRequest *aRequest, - imgIContainer *aContainer, - const nsIntRect *dirtyRect); + NS_DECL_IMGINOTIFICATIONOBSERVER void SetFrame(nsBulletFrame *frame) { mFrame = frame; } @@ -61,6 +50,8 @@ public: } virtual ~nsBulletFrame(); + NS_IMETHOD Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData); + // nsIFrame virtual void DestroyFrom(nsIFrame* aDestructRoot); NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, @@ -85,18 +76,6 @@ public: int32_t aIncrement); - NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage); - NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, - bool aCurrentFrame, - const nsIntRect *aRect); - NS_IMETHOD OnStopDecode(imgIRequest *aRequest, - nsresult aStatus, - const PRUnichar *aStatusArg); - NS_IMETHOD OnImageIsAnimated(imgIRequest *aRequest); - NS_IMETHOD FrameChanged(imgIRequest *aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect); - /* get list item text, without '.' */ static bool AppendCounterText(int32_t aListStyleType, int32_t aOrdinal, @@ -120,6 +99,8 @@ public: void SetFontSizeInflation(float aInflation); protected: + nsresult OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage); + void GetDesiredSize(nsPresContext* aPresContext, nsRenderingContext *aRenderingContext, nsHTMLReflowMetrics& aMetrics, diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index 890783c2e2d..a84f6406b52 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -525,6 +525,36 @@ nsImageFrame::ShouldCreateImageFrameFor(Element* aElement, return useSizedBox; } +nsresult +nsImageFrame::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* aData) +{ + if (aType == imgINotificationObserver::START_CONTAINER) { + nsCOMPtr image; + aRequest->GetImage(getter_AddRefs(image)); + return OnStartContainer(aRequest, image); + } + + if (aType == imgINotificationObserver::DATA_AVAILABLE) { + return OnDataAvailable(aRequest, aData); + } + + if (aType == imgINotificationObserver::STOP_DECODE) { + uint32_t imgStatus; + aRequest->GetImageStatus(&imgStatus); + nsresult status = + imgStatus & imgIRequest::STATUS_ERROR ? NS_ERROR_FAILURE : NS_OK; + return OnStopDecode(aRequest, status); + } + + if (aType == imgINotificationObserver::FRAME_CHANGED) { + nsCOMPtr image; + aRequest->GetImage(getter_AddRefs(image)); + return FrameChanged(aRequest, image); + } + + return NS_OK; +} + nsresult nsImageFrame::OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage) { @@ -564,7 +594,6 @@ nsImageFrame::OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage) nsresult nsImageFrame::OnDataAvailable(imgIRequest *aRequest, - bool aCurrentFrame, const nsIntRect *aRect) { // XXX do we need to make sure that the reflow from the @@ -583,11 +612,6 @@ nsImageFrame::OnDataAvailable(imgIRequest *aRequest, return NS_OK; } - // Don't invalidate if the current visible frame isn't the one the data is - // from - if (!aCurrentFrame) - return NS_OK; - #ifdef DEBUG_decode printf("Source rect (%d,%d,%d,%d)\n", aRect->x, aRect->y, aRect->width, aRect->height); @@ -607,8 +631,7 @@ nsImageFrame::OnDataAvailable(imgIRequest *aRequest, nsresult nsImageFrame::OnStopDecode(imgIRequest *aRequest, - nsresult aStatus, - const PRUnichar *aStatusArg) + nsresult aStatus) { // Check what request type we're dealing with nsCOMPtr imageLoader = do_QueryInterface(mContent); @@ -667,8 +690,7 @@ nsImageFrame::NotifyNewCurrentRequest(imgIRequest *aRequest, nsresult nsImageFrame::FrameChanged(imgIRequest *aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect) + imgIContainer *aContainer) { if (!GetStyleVisibility()->IsVisible()) { return NS_OK; @@ -1894,7 +1916,7 @@ nsresult nsImageFrame::LoadIcons(nsPresContext *aPresContext) } NS_IMPL_ISUPPORTS2(nsImageFrame::IconLoad, nsIObserver, - imgIDecoderObserver) + imgINotificationObserver) static const char* kIconLoadPrefs[] = { "browser.display.force_inline_alttext", @@ -1951,74 +1973,14 @@ void nsImageFrame::IconLoad::GetPrefs() Preferences::GetBool("browser.display.show_image_placeholders", true); } - - NS_IMETHODIMP -nsImageFrame::IconLoad::OnStartRequest(imgIRequest *aRequest) +nsImageFrame::IconLoad::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) { - return NS_OK; -} + if (aType != imgINotificationObserver::STOP_REQUEST && + aType != imgINotificationObserver::FRAME_CHANGED) { + return NS_OK; + } -NS_IMETHODIMP -nsImageFrame::IconLoad::OnStartDecode(imgIRequest *aRequest) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsImageFrame::IconLoad::OnStartContainer(imgIRequest *aRequest, - imgIContainer *aContainer) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsImageFrame::IconLoad::OnStartFrame(imgIRequest *aRequest, - uint32_t aFrame) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsImageFrame::IconLoad::OnDataAvailable(imgIRequest *aRequest, - bool aCurrentFrame, - const nsIntRect * aRect) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsImageFrame::IconLoad::OnStopFrame(imgIRequest *aRequest, - uint32_t aFrame) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsImageFrame::IconLoad::OnStopContainer(imgIRequest *aRequest, - imgIContainer *aContainer) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsImageFrame::IconLoad::OnStopDecode(imgIRequest *aRequest, - nsresult status, - const PRUnichar *statusArg) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsImageFrame::IconLoad::OnImageIsAnimated(imgIRequest *aRequest) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsImageFrame::IconLoad::OnStopRequest(imgIRequest *aRequest, - bool aIsLastPart) -{ nsTObserverArray::ForwardIterator iter(mIconObservers); nsImageFrame *frame; while (iter.HasMore()) { @@ -2029,30 +1991,7 @@ nsImageFrame::IconLoad::OnStopRequest(imgIRequest *aRequest, return NS_OK; } -NS_IMETHODIMP -nsImageFrame::IconLoad::OnDiscard(imgIRequest *aRequest) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsImageFrame::IconLoad::FrameChanged(imgIRequest *aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect) -{ - nsTObserverArray::ForwardIterator iter(mIconObservers); - nsImageFrame *frame; - while (iter.HasMore()) { - frame = iter.GetNext(); - frame->InvalidateFrame(); - } - - return NS_OK; -} - - - -NS_IMPL_ISUPPORTS2(nsImageListener, imgIDecoderObserver, imgIContainerObserver) +NS_IMPL_ISUPPORTS1(nsImageListener, imgINotificationObserver) nsImageListener::nsImageListener(nsImageFrame *aFrame) : mFrame(aFrame) @@ -2063,43 +2002,13 @@ nsImageListener::~nsImageListener() { } -NS_IMETHODIMP nsImageListener::OnStartContainer(imgIRequest *aRequest, - imgIContainer *aImage) +NS_IMETHODIMP +nsImageListener::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) { if (!mFrame) return NS_ERROR_FAILURE; - return mFrame->OnStartContainer(aRequest, aImage); -} - -NS_IMETHODIMP nsImageListener::OnDataAvailable(imgIRequest *aRequest, - bool aCurrentFrame, - const nsIntRect *aRect) -{ - if (!mFrame) - return NS_ERROR_FAILURE; - - return mFrame->OnDataAvailable(aRequest, aCurrentFrame, aRect); -} - -NS_IMETHODIMP nsImageListener::OnStopDecode(imgIRequest *aRequest, - nsresult status, - const PRUnichar *statusArg) -{ - if (!mFrame) - return NS_ERROR_FAILURE; - - return mFrame->OnStopDecode(aRequest, status, statusArg); -} - -NS_IMETHODIMP nsImageListener::FrameChanged(imgIRequest *aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect) -{ - if (!mFrame) - return NS_ERROR_FAILURE; - - return mFrame->FrameChanged(aRequest, aContainer, aDirtyRect); + return mFrame->Notify(aRequest, aType, aData); } static bool diff --git a/layout/generic/nsImageFrame.h b/layout/generic/nsImageFrame.h index dbb68ae5b3e..994ee3eb44d 100644 --- a/layout/generic/nsImageFrame.h +++ b/layout/generic/nsImageFrame.h @@ -12,8 +12,7 @@ #include "nsIIOService.h" #include "nsIObserver.h" -#include "nsStubImageDecoderObserver.h" -#include "imgIDecoderObserver.h" +#include "imgINotificationObserver.h" #include "nsDisplayList.h" #include "imgIContainer.h" @@ -40,23 +39,14 @@ namespace layers { } } -class nsImageListener : public nsStubImageDecoderObserver +class nsImageListener : public imgINotificationObserver { public: nsImageListener(nsImageFrame *aFrame); virtual ~nsImageListener(); NS_DECL_ISUPPORTS - // imgIDecoderObserver (override nsStubImageDecoderObserver) - NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage); - NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, bool aCurrentFrame, - const nsIntRect *aRect); - NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status, - const PRUnichar *statusArg); - // imgIContainerObserver (override nsStubImageDecoderObserver) - NS_IMETHOD FrameChanged(imgIRequest *aRequest, - imgIContainer *aContainer, - const nsIntRect *dirtyRect); + NS_DECL_IMGINOTIFICATIONOBSERVER void SetFrame(nsImageFrame *frame) { mFrame = frame; } @@ -137,6 +127,8 @@ public: NS_IF_RELEASE(sIOService); } + nsresult Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData); + /** * Function to test whether aContent, which has aStyleContext as its style, * should get an image frame. Note that this method is only used by the @@ -221,14 +213,11 @@ protected: friend class nsImageListener; friend class nsImageLoadingContent; nsresult OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage); - nsresult OnDataAvailable(imgIRequest *aRequest, bool aCurrentFrame, - const nsIntRect *rect); + nsresult OnDataAvailable(imgIRequest *aRequest, const nsIntRect *rect); nsresult OnStopDecode(imgIRequest *aRequest, - nsresult aStatus, - const PRUnichar *aStatusArg); + nsresult aStatus); nsresult FrameChanged(imgIRequest *aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect); + imgIContainer *aContainer); /** * Notification that aRequest will now be the current request. */ @@ -288,7 +277,7 @@ private: nsImageMap* mImageMap; - nsCOMPtr mListener; + nsCOMPtr mListener; nsSize mComputedSize; nsIFrame::IntrinsicSize mIntrinsicSize; @@ -311,7 +300,7 @@ private: imgIRequest **aRequest); class IconLoad MOZ_FINAL : public nsIObserver, - public imgIDecoderObserver { + public imgINotificationObserver { // private class that wraps the data and logic needed for // broken image and loading image icons public: @@ -321,8 +310,7 @@ private: NS_DECL_ISUPPORTS NS_DECL_NSIOBSERVER - NS_DECL_IMGICONTAINEROBSERVER - NS_DECL_IMGIDECODEROBSERVER + NS_DECL_IMGINOTIFICATIONOBSERVER void AddIconObserver(nsImageFrame *frame) { NS_ABORT_IF_FALSE(!mIconObservers.Contains(frame), diff --git a/layout/style/ImageLoader.cpp b/layout/style/ImageLoader.cpp index 2adf0a0a016..d3f2ae21683 100644 --- a/layout/style/ImageLoader.cpp +++ b/layout/style/ImageLoader.cpp @@ -56,8 +56,8 @@ ImageLoader::AssociateRequestToFrame(imgIRequest* aRequest, mFrameToRequestMap.IsInitialized() && mImages.IsInitialized()); - nsCOMPtr observer; - aRequest->GetDecoderObserver(getter_AddRefs(observer)); + nsCOMPtr observer; + aRequest->GetNotificationObserver(getter_AddRefs(observer)); if (!observer) { // The request has already been canceled, so ignore it. This is ok because // we're not going to get any more notifications from a canceled request. @@ -157,8 +157,8 @@ ImageLoader::DisassociateRequestFromFrame(imgIRequest* aRequest, #ifdef DEBUG { - nsCOMPtr observer; - aRequest->GetDecoderObserver(getter_AddRefs(observer)); + nsCOMPtr observer; + aRequest->GetNotificationObserver(getter_AddRefs(observer)); MOZ_ASSERT(!observer || observer == this); } #endif @@ -334,12 +334,35 @@ NS_IMPL_ADDREF(ImageLoader) NS_IMPL_RELEASE(ImageLoader) NS_INTERFACE_MAP_BEGIN(ImageLoader) - NS_INTERFACE_MAP_ENTRY(imgIDecoderObserver) - NS_INTERFACE_MAP_ENTRY(imgIContainerObserver) + NS_INTERFACE_MAP_ENTRY(imgINotificationObserver) NS_INTERFACE_MAP_ENTRY(imgIOnloadBlocker) NS_INTERFACE_MAP_END NS_IMETHODIMP +ImageLoader::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) +{ + if (aType == imgINotificationObserver::START_CONTAINER) { + nsCOMPtr image; + aRequest->GetImage(getter_AddRefs(image)); + return OnStartContainer(aRequest, image); + } + + if (aType == imgINotificationObserver::IS_ANIMATED) { + return OnImageIsAnimated(aRequest); + } + + if (aType == imgINotificationObserver::STOP_FRAME) { + return OnStopFrame(aRequest); + } + + if (aType == imgINotificationObserver::FRAME_CHANGED) { + return FrameChanged(aRequest); + } + + return NS_OK; +} + +nsresult ImageLoader::OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage) { nsPresContext* presContext = GetPresContext(); @@ -352,7 +375,7 @@ ImageLoader::OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage) return NS_OK; } -NS_IMETHODIMP +nsresult ImageLoader::OnImageIsAnimated(imgIRequest* aRequest) { if (!mDocument) { @@ -376,8 +399,8 @@ ImageLoader::OnImageIsAnimated(imgIRequest* aRequest) return NS_OK; } -NS_IMETHODIMP -ImageLoader::OnStopFrame(imgIRequest *aRequest, uint32_t aFrame) +nsresult +ImageLoader::OnStopFrame(imgIRequest *aRequest) { if (!mDocument || mInClone) { return NS_OK; @@ -395,10 +418,8 @@ ImageLoader::OnStopFrame(imgIRequest *aRequest, uint32_t aFrame) return NS_OK; } -NS_IMETHODIMP -ImageLoader::FrameChanged(imgIRequest *aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect) +nsresult +ImageLoader::FrameChanged(imgIRequest *aRequest) { if (!mDocument || mInClone) { return NS_OK; diff --git a/layout/style/ImageLoader.h b/layout/style/ImageLoader.h index 86d770be798..73d630cf5f1 100644 --- a/layout/style/ImageLoader.h +++ b/layout/style/ImageLoader.h @@ -12,7 +12,7 @@ #include "nsCSSValue.h" #include "imgIRequest.h" #include "imgIOnloadBlocker.h" -#include "nsStubImageDecoderObserver.h" +#include "imgINotificationObserver.h" #include "mozilla/Attributes.h" class nsIFrame; @@ -24,7 +24,7 @@ class nsIPrincipal; namespace mozilla { namespace css { -class ImageLoader MOZ_FINAL : public nsStubImageDecoderObserver, +class ImageLoader MOZ_FINAL : public imgINotificationObserver, public imgIOnloadBlocker { public: typedef mozilla::css::ImageValue Image; @@ -42,19 +42,7 @@ public: NS_DECL_ISUPPORTS NS_DECL_IMGIONLOADBLOCKER - - // imgIDecoderObserver (override nsStubImageDecoderObserver) - NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage); - NS_IMETHOD OnStopFrame(imgIRequest *aRequest, uint32_t aFrame); - NS_IMETHOD OnImageIsAnimated(imgIRequest *aRequest); - // Do not override OnDataAvailable since background images are not - // displayed incrementally; they are displayed after the entire image - // has been loaded. - - // imgIContainerObserver (override nsStubImageDecoderObserver) - NS_IMETHOD FrameChanged(imgIRequest* aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect); + NS_DECL_IMGINOTIFICATIONOBSERVER void DropDocumentReference(); @@ -103,6 +91,14 @@ private: SetAnimationModeEnumerator(nsISupports* aKey, FrameSet* aValue, void* aClosure); + nsresult OnStartContainer(imgIRequest *aRequest, imgIContainer* aImage); + nsresult OnStopFrame(imgIRequest *aRequest); + nsresult OnImageIsAnimated(imgIRequest *aRequest); + nsresult FrameChanged(imgIRequest* aRequest); + // Do not override OnDataAvailable since background images are not + // displayed incrementally; they are displayed after the entire image + // has been loaded. + // A map of imgIRequests to the nsIFrames that are using them. RequestToFrameMap mRequestToFrameMap; diff --git a/layout/svg/nsSVGImageFrame.cpp b/layout/svg/nsSVGImageFrame.cpp index 7615802bc35..6f2d3d24f75 100644 --- a/layout/svg/nsSVGImageFrame.cpp +++ b/layout/svg/nsSVGImageFrame.cpp @@ -11,7 +11,7 @@ #include "nsIDOMSVGImageElement.h" #include "nsLayoutUtils.h" #include "nsRenderingContext.h" -#include "nsStubImageDecoderObserver.h" +#include "imgINotificationObserver.h" #include "nsSVGEffects.h" #include "nsSVGImageElement.h" #include "nsSVGPathGeometryFrame.h" @@ -23,22 +23,13 @@ using namespace mozilla; class nsSVGImageFrame; -class nsSVGImageListener MOZ_FINAL : public nsStubImageDecoderObserver +class nsSVGImageListener MOZ_FINAL : public imgINotificationObserver { public: nsSVGImageListener(nsSVGImageFrame *aFrame); NS_DECL_ISUPPORTS - // imgIDecoderObserver (override nsStubImageDecoderObserver) - NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status, - const PRUnichar *statusArg); - // imgIContainerObserver (override nsStubImageDecoderObserver) - NS_IMETHOD FrameChanged(imgIRequest *aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect); - // imgIContainerObserver (override nsStubImageDecoderObserver) - NS_IMETHOD OnStartContainer(imgIRequest *aRequest, - imgIContainer *aContainer); + NS_DECL_IMGINOTIFICATIONOBSERVER void SetFrame(nsSVGImageFrame *frame) { mFrame = frame; } @@ -98,7 +89,7 @@ private: gfxMatrix GetVectorImageTransform(uint32_t aFor); bool TransformContextForPainting(gfxContext* aGfxContext); - nsCOMPtr mListener; + nsCOMPtr mListener; nsCOMPtr mImageContainer; @@ -560,49 +551,34 @@ nsSVGImageFrame::GetHitTestFlags() //---------------------------------------------------------------------- // nsSVGImageListener implementation -NS_IMPL_ISUPPORTS2(nsSVGImageListener, - imgIDecoderObserver, - imgIContainerObserver) +NS_IMPL_ISUPPORTS1(nsSVGImageListener, imgINotificationObserver) nsSVGImageListener::nsSVGImageListener(nsSVGImageFrame *aFrame) : mFrame(aFrame) { } -NS_IMETHODIMP nsSVGImageListener::OnStopDecode(imgIRequest *aRequest, - nsresult status, - const PRUnichar *statusArg) +NS_IMETHODIMP +nsSVGImageListener::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) { if (!mFrame) return NS_ERROR_FAILURE; - nsSVGUtils::InvalidateAndScheduleReflowSVG(mFrame); - return NS_OK; -} + if (aType == imgINotificationObserver::STOP_DECODE) { + nsSVGUtils::InvalidateAndScheduleReflowSVG(mFrame); + } -NS_IMETHODIMP nsSVGImageListener::FrameChanged(imgIRequest *aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect) -{ - if (!mFrame) - return NS_ERROR_FAILURE; + if (aType == imgINotificationObserver::FRAME_CHANGED) { + // No new dimensions, so we don't need to call + // nsSVGUtils::InvalidateAndScheduleBoundsUpdate. + nsSVGEffects::InvalidateRenderingObservers(mFrame); + nsSVGUtils::InvalidateBounds(mFrame); + } - // No new dimensions, so we don't need to call - // nsSVGUtils::InvalidateAndScheduleBoundsUpdate. - nsSVGEffects::InvalidateRenderingObservers(mFrame); - nsSVGUtils::InvalidateBounds(mFrame); - return NS_OK; -} - -NS_IMETHODIMP nsSVGImageListener::OnStartContainer(imgIRequest *aRequest, - imgIContainer *aContainer) -{ - // Called once the resource's dimensions have been obtained. - - if (!mFrame) - return NS_ERROR_FAILURE; - - mFrame->mImageContainer = aContainer; - nsSVGUtils::InvalidateAndScheduleReflowSVG(mFrame); + if (aType == imgINotificationObserver::START_CONTAINER) { + // Called once the resource's dimensions have been obtained. + aRequest->GetImage(getter_AddRefs(mFrame->mImageContainer)); + nsSVGUtils::InvalidateAndScheduleReflowSVG(mFrame); + } return NS_OK; } diff --git a/layout/xul/base/src/nsImageBoxFrame.cpp b/layout/xul/base/src/nsImageBoxFrame.cpp index a5033ea4007..94a8361c9a6 100644 --- a/layout/xul/base/src/nsImageBoxFrame.cpp +++ b/layout/xul/base/src/nsImageBoxFrame.cpp @@ -188,7 +188,7 @@ nsImageBoxFrame::Init(nsIContent* aContent, nsImageBoxListener *listener = new nsImageBoxListener(); NS_ADDREF(listener); listener->SetFrame(this); - listener->QueryInterface(NS_GET_IID(imgIDecoderObserver), getter_AddRefs(mListener)); + listener->QueryInterface(NS_GET_IID(imgINotificationObserver), getter_AddRefs(mListener)); NS_RELEASE(listener); } @@ -577,9 +577,40 @@ nsImageBoxFrame::GetFrameName(nsAString& aResult) const } #endif +nsresult +nsImageBoxFrame::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) +{ + if (aType == imgINotificationObserver::START_CONTAINER) { + nsCOMPtr image; + aRequest->GetImage(getter_AddRefs(image)); + return OnStartContainer(aRequest, image); + } -NS_IMETHODIMP nsImageBoxFrame::OnStartContainer(imgIRequest *request, - imgIContainer *image) + if (aType == imgINotificationObserver::STOP_CONTAINER) { + return OnStopContainer(aRequest); + } + + if (aType == imgINotificationObserver::STOP_DECODE) { + uint32_t imgStatus; + aRequest->GetImageStatus(&imgStatus); + nsresult status = + imgStatus & imgIRequest::STATUS_ERROR ? NS_ERROR_FAILURE : NS_OK; + return OnStopDecode(aRequest, status); + } + + if (aType == imgINotificationObserver::IS_ANIMATED) { + return OnImageIsAnimated(aRequest); + } + + if (aType == imgINotificationObserver::FRAME_CHANGED) { + return FrameChanged(aRequest); + } + + return NS_OK; +} + +nsresult nsImageBoxFrame::OnStartContainer(imgIRequest *request, + imgIContainer *image) { NS_ENSURE_ARG_POINTER(image); @@ -603,8 +634,7 @@ NS_IMETHODIMP nsImageBoxFrame::OnStartContainer(imgIRequest *request, return NS_OK; } -NS_IMETHODIMP nsImageBoxFrame::OnStopContainer(imgIRequest *request, - imgIContainer *image) +nsresult nsImageBoxFrame::OnStopContainer(imgIRequest *request) { nsBoxLayoutState state(PresContext()); this->Redraw(state); @@ -612,9 +642,8 @@ NS_IMETHODIMP nsImageBoxFrame::OnStopContainer(imgIRequest *request, return NS_OK; } -NS_IMETHODIMP nsImageBoxFrame::OnStopDecode(imgIRequest *request, - nsresult aStatus, - const PRUnichar *statusArg) +nsresult nsImageBoxFrame::OnStopDecode(imgIRequest *request, + nsresult aStatus) { if (NS_SUCCEEDED(aStatus)) // Fire an onload DOM event. @@ -630,7 +659,7 @@ NS_IMETHODIMP nsImageBoxFrame::OnStopDecode(imgIRequest *request, return NS_OK; } -NS_IMETHODIMP nsImageBoxFrame::OnImageIsAnimated(imgIRequest *aRequest) +nsresult nsImageBoxFrame::OnImageIsAnimated(imgIRequest *aRequest) { // Register with our refresh driver, if we're animated. nsLayoutUtils::RegisterImageRequest(PresContext(), aRequest, @@ -639,9 +668,7 @@ NS_IMETHODIMP nsImageBoxFrame::OnImageIsAnimated(imgIRequest *aRequest) return NS_OK; } -NS_IMETHODIMP nsImageBoxFrame::FrameChanged(imgIRequest *aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect) +nsresult nsImageBoxFrame::FrameChanged(imgIRequest *aRequest) { if ((0 == mRect.width) || (0 == mRect.height)) { return NS_OK; @@ -652,7 +679,7 @@ NS_IMETHODIMP nsImageBoxFrame::FrameChanged(imgIRequest *aRequest, return NS_OK; } -NS_IMPL_ISUPPORTS2(nsImageBoxListener, imgIDecoderObserver, imgIContainerObserver) +NS_IMPL_ISUPPORTS1(nsImageBoxListener, imgINotificationObserver) nsImageBoxListener::nsImageBoxListener() { @@ -662,49 +689,11 @@ nsImageBoxListener::~nsImageBoxListener() { } -NS_IMETHODIMP nsImageBoxListener::OnStartContainer(imgIRequest *request, - imgIContainer *image) +NS_IMETHODIMP +nsImageBoxListener::Notify(imgIRequest *request, int32_t aType, const nsIntRect* aData) { if (!mFrame) return NS_OK; - return mFrame->OnStartContainer(request, image); + return mFrame->Notify(request, aType, aData); } - -NS_IMETHODIMP nsImageBoxListener::OnStopContainer(imgIRequest *request, - imgIContainer *image) -{ - if (!mFrame) - return NS_OK; - - return mFrame->OnStopContainer(request, image); -} - -NS_IMETHODIMP nsImageBoxListener::OnStopDecode(imgIRequest *request, - nsresult status, - const PRUnichar *statusArg) -{ - if (!mFrame) - return NS_OK; - - return mFrame->OnStopDecode(request, status, statusArg); -} - -NS_IMETHODIMP nsImageBoxListener::OnImageIsAnimated(imgIRequest* aRequest) -{ - if (!mFrame) - return NS_OK; - - return mFrame->OnImageIsAnimated(aRequest); -} - -NS_IMETHODIMP nsImageBoxListener::FrameChanged(imgIRequest *aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect) -{ - if (!mFrame) - return NS_ERROR_FAILURE; - - return mFrame->FrameChanged(aRequest, aContainer, aDirtyRect); -} - diff --git a/layout/xul/base/src/nsImageBoxFrame.h b/layout/xul/base/src/nsImageBoxFrame.h index a06f41fbb61..70272692be6 100644 --- a/layout/xul/base/src/nsImageBoxFrame.h +++ b/layout/xul/base/src/nsImageBoxFrame.h @@ -11,30 +11,20 @@ #include "imgILoader.h" #include "imgIRequest.h" #include "imgIContainer.h" -#include "nsStubImageDecoderObserver.h" +#include "imgINotificationObserver.h" class nsImageBoxFrame; class nsDisplayXULImage; -class nsImageBoxListener : public nsStubImageDecoderObserver +class nsImageBoxListener : public imgINotificationObserver { public: nsImageBoxListener(); virtual ~nsImageBoxListener(); NS_DECL_ISUPPORTS - // imgIDecoderObserver (override nsStubImageDecoderObserver) - NS_IMETHOD OnStartContainer(imgIRequest *request, imgIContainer *image); - NS_IMETHOD OnStopContainer(imgIRequest *request, imgIContainer *image); - NS_IMETHOD OnStopDecode(imgIRequest *request, nsresult status, - const PRUnichar *statusArg); - NS_IMETHOD OnImageIsAnimated(imgIRequest* aRequest); - - // imgIContainerObserver (override nsStubImageDecoderObserver) - NS_IMETHOD FrameChanged(imgIRequest *aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect); + NS_DECL_IMGINOTIFICATIONOBSERVER void SetFrame(nsImageBoxFrame *frame) { mFrame = frame; } @@ -53,6 +43,8 @@ public: virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE; + nsresult Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData); + friend nsIFrame* NS_NewImageBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); NS_IMETHOD Init(nsIContent* aContent, @@ -89,17 +81,6 @@ public: const nsRect& aDirtyRect, const nsDisplayListSet& aLists) MOZ_OVERRIDE; - NS_IMETHOD OnStartContainer(imgIRequest *request, imgIContainer *image); - NS_IMETHOD OnStopContainer(imgIRequest *request, imgIContainer *image); - NS_IMETHOD OnStopDecode(imgIRequest *request, - nsresult status, - const PRUnichar *statusArg); - NS_IMETHOD OnImageIsAnimated(imgIRequest* aRequest); - - NS_IMETHOD FrameChanged(imgIRequest *aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect); - virtual ~nsImageBoxFrame(); void PaintImage(nsRenderingContext& aRenderingContext, @@ -113,6 +94,11 @@ protected: virtual void GetImageSize(); private: + nsresult OnStartContainer(imgIRequest *request, imgIContainer *image); + nsresult OnStopContainer(imgIRequest *request); + nsresult OnStopDecode(imgIRequest *request, nsresult status); + nsresult OnImageIsAnimated(imgIRequest* aRequest); + nsresult FrameChanged(imgIRequest *aRequest); nsRect mSubRect; ///< If set, indicates that only the portion of the image specified by the rect should be used. nsSize mIntrinsicSize; @@ -123,7 +109,7 @@ private: bool mRequestRegistered; nsCOMPtr mImageRequest; - nsCOMPtr mListener; + nsCOMPtr mListener; int32_t mLoadFlags; diff --git a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp index 5033c1f7105..bb9ec8be464 100644 --- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp +++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp @@ -2117,8 +2117,8 @@ nsTreeBodyFrame::GetImage(int32_t aRowIndex, nsTreeColumn* aCol, bool aUseContex if ((!(status & imgIRequest::STATUS_LOAD_COMPLETE)) || animated) { // We either aren't done loading, or we're animating. Add our row as a listener for invalidations. - nsCOMPtr obs; - imgReq->GetDecoderObserver(getter_AddRefs(obs)); + nsCOMPtr obs; + imgReq->GetNotificationObserver(getter_AddRefs(obs)); if (obs) { static_cast (obs.get())->AddCell(aRowIndex, aCol); @@ -2140,11 +2140,11 @@ nsTreeBodyFrame::GetImage(int32_t aRowIndex, nsTreeColumn* aCol, bool aUseContex } listener->AddCell(aRowIndex, aCol); - nsCOMPtr imgDecoderObserver = listener; + nsCOMPtr imgNotificationObserver = listener; nsCOMPtr imageRequest; if (styleRequest) { - styleRequest->Clone(imgDecoderObserver, getter_AddRefs(imageRequest)); + styleRequest->Clone(imgNotificationObserver, getter_AddRefs(imageRequest)); } else { nsIDocument* doc = mContent->GetDocument(); if (!doc) @@ -2169,7 +2169,7 @@ nsTreeBodyFrame::GetImage(int32_t aRowIndex, nsTreeColumn* aCol, bool aUseContex doc, mContent->NodePrincipal(), doc->GetDocumentURI(), - imgDecoderObserver, + imgNotificationObserver, nsIRequest::LOAD_NORMAL, getter_AddRefs(imageRequest)); NS_ENSURE_SUCCESS(rv, rv); @@ -2187,7 +2187,7 @@ nsTreeBodyFrame::GetImage(int32_t aRowIndex, nsTreeColumn* aCol, bool aUseContex // In a case it was already cached. imageRequest->GetImage(aResult); - nsTreeImageCacheEntry cacheEntry(imageRequest, imgDecoderObserver); + nsTreeImageCacheEntry cacheEntry(imageRequest, imgNotificationObserver); mImageCache.Put(imageSrc, cacheEntry); } return NS_OK; diff --git a/layout/xul/base/src/tree/src/nsTreeBodyFrame.h b/layout/xul/base/src/tree/src/nsTreeBodyFrame.h index 2446394fa63..41bc2644f1d 100644 --- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.h +++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.h @@ -20,7 +20,7 @@ #include "nsAutoPtr.h" #include "nsDataHashtable.h" #include "imgIRequest.h" -#include "imgIDecoderObserver.h" +#include "imgINotificationObserver.h" #include "nsScrollbarFrame.h" #include "nsThreadUtils.h" #include "mozilla/LookAndFeel.h" @@ -32,11 +32,11 @@ class nsTreeImageListener; struct nsTreeImageCacheEntry { nsTreeImageCacheEntry() {} - nsTreeImageCacheEntry(imgIRequest *aRequest, imgIDecoderObserver *aListener) + nsTreeImageCacheEntry(imgIRequest *aRequest, imgINotificationObserver *aListener) : request(aRequest), listener(aListener) {} nsCOMPtr request; - nsCOMPtr listener; + nsCOMPtr listener; }; // The actual frame that paints the cells and rows. diff --git a/layout/xul/base/src/tree/src/nsTreeImageListener.cpp b/layout/xul/base/src/tree/src/nsTreeImageListener.cpp index f025be9fd47..c8ccf4b3a82 100644 --- a/layout/xul/base/src/tree/src/nsTreeImageListener.cpp +++ b/layout/xul/base/src/tree/src/nsTreeImageListener.cpp @@ -8,7 +8,7 @@ #include "imgIRequest.h" #include "imgIContainer.h" -NS_IMPL_ISUPPORTS2(nsTreeImageListener, imgIDecoderObserver, imgIContainerObserver) +NS_IMPL_ISUPPORTS1(nsTreeImageListener, imgINotificationObserver) nsTreeImageListener::nsTreeImageListener(nsTreeBodyFrame* aTreeFrame) : mTreeFrame(aTreeFrame), @@ -23,42 +23,27 @@ nsTreeImageListener::~nsTreeImageListener() } NS_IMETHODIMP -nsTreeImageListener::OnImageIsAnimated(imgIRequest *aRequest) +nsTreeImageListener::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) { - if (!mTreeFrame) { - return NS_OK; + if (aType == imgINotificationObserver::IS_ANIMATED) { + return mTreeFrame ? mTreeFrame->OnImageIsAnimated(aRequest) : NS_OK; } - return mTreeFrame->OnImageIsAnimated(aRequest); -} + if (aType == imgINotificationObserver::START_CONTAINER) { + // Ensure the animation (if any) is started. Note: There is no + // corresponding call to Decrement for this. This Increment will be + // 'cleaned up' by the Request when it is destroyed, but only then. + aRequest->IncrementAnimationConsumers(); + } + + if (aType == imgINotificationObserver::DATA_AVAILABLE || + aType == imgINotificationObserver::FRAME_CHANGED) { + Invalidate(); + } -NS_IMETHODIMP nsTreeImageListener::OnStartContainer(imgIRequest *aRequest, - imgIContainer *aImage) -{ - // Ensure the animation (if any) is started. Note: There is no - // corresponding call to Decrement for this. This Increment will be - // 'cleaned up' by the Request when it is destroyed, but only then. - aRequest->IncrementAnimationConsumers(); return NS_OK; } -NS_IMETHODIMP nsTreeImageListener::OnDataAvailable(imgIRequest *aRequest, - bool aCurrentFrame, - const nsIntRect *aRect) -{ - Invalidate(); - return NS_OK; -} - -NS_IMETHODIMP nsTreeImageListener::FrameChanged(imgIRequest *aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect) -{ - Invalidate(); - return NS_OK; -} - - void nsTreeImageListener::AddCell(int32_t aIndex, nsITreeColumn* aCol) { diff --git a/layout/xul/base/src/tree/src/nsTreeImageListener.h b/layout/xul/base/src/tree/src/nsTreeImageListener.h index f880e4c15be..940083869e3 100644 --- a/layout/xul/base/src/tree/src/nsTreeImageListener.h +++ b/layout/xul/base/src/tree/src/nsTreeImageListener.h @@ -9,27 +9,18 @@ #include "nsString.h" #include "nsCOMPtr.h" #include "nsITreeColumns.h" -#include "nsStubImageDecoderObserver.h" #include "nsTreeBodyFrame.h" #include "mozilla/Attributes.h" // This class handles image load observation. -class nsTreeImageListener MOZ_FINAL : public nsStubImageDecoderObserver +class nsTreeImageListener MOZ_FINAL : public imgINotificationObserver { public: nsTreeImageListener(nsTreeBodyFrame *aTreeFrame); ~nsTreeImageListener(); NS_DECL_ISUPPORTS - // imgIDecoderObserver (override nsStubImageDecoderObserver) - NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage); - NS_IMETHOD OnImageIsAnimated(imgIRequest* aRequest); - NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, bool aCurrentFrame, - const nsIntRect *aRect); - // imgIContainerObserver (override nsStubImageDecoderObserver) - NS_IMETHOD FrameChanged(imgIRequest *aRequest, - imgIContainer *aContainer, - const nsIntRect *aDirtyRect); + NS_DECL_IMGINOTIFICATIONOBSERVER NS_IMETHOD ClearFrame(); diff --git a/toolkit/system/gnome/nsAlertsIconListener.cpp b/toolkit/system/gnome/nsAlertsIconListener.cpp index ea067abdca0..70bff3be5e6 100644 --- a/toolkit/system/gnome/nsAlertsIconListener.cpp +++ b/toolkit/system/gnome/nsAlertsIconListener.cpp @@ -51,8 +51,8 @@ static void notify_closed_marshal(GClosure* closure, NS_RELEASE(alert); } -NS_IMPL_ISUPPORTS4(nsAlertsIconListener, imgIContainerObserver, - imgIDecoderObserver, nsIObserver, nsISupportsWeakReference) +NS_IMPL_ISUPPORTS3(nsAlertsIconListener, imgINotificationObserver, + nsIObserver, nsISupportsWeakReference) nsAlertsIconListener::nsAlertsIconListener() : mLoadedFrame(false), @@ -90,69 +90,21 @@ nsAlertsIconListener::~nsAlertsIconListener() } NS_IMETHODIMP -nsAlertsIconListener::OnStartRequest(imgIRequest* aRequest) +nsAlertsIconListener::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) { + if (aType == imgINotificationObserver::STOP_REQUEST) { + return OnStopRequest(aRequest); + } + + if (aType == imgINotificationObserver::STOP_FRAME) { + return OnStopFrame(aRequest); + } + return NS_OK; } -NS_IMETHODIMP -nsAlertsIconListener::OnStartDecode(imgIRequest* aRequest) -{ - return NS_OK; -} - - -NS_IMETHODIMP -nsAlertsIconListener::OnStartContainer(imgIRequest* aRequest, - imgIContainer* aContainer) -{ - return NS_OK; -} - - -NS_IMETHODIMP -nsAlertsIconListener::OnStartFrame(imgIRequest* aRequest, - uint32_t aFrame) -{ - return NS_OK; -} - - -NS_IMETHODIMP -nsAlertsIconListener::OnDataAvailable(imgIRequest* aRequest, - bool aCurrentFrame, - const nsIntRect* aRect) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsAlertsIconListener::OnStopContainer(imgIRequest* aRequest, - imgIContainer* aContainer) -{ - return NS_OK; -} - - -NS_IMETHODIMP -nsAlertsIconListener::OnStopDecode(imgIRequest* aRequest, - nsresult status, - const PRUnichar* statusArg) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsAlertsIconListener::FrameChanged(imgIRequest* aRequest, - imgIContainer* aContainer, - const nsIntRect* aDirtyRect) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsAlertsIconListener::OnStopRequest(imgIRequest* aRequest, - bool aIsLastPart) +nsresult +nsAlertsIconListener::OnStopRequest(imgIRequest* aRequest) { uint32_t imgStatus = imgIRequest::STATUS_ERROR; nsresult rv = aRequest->GetImageStatus(&imgStatus); @@ -169,21 +121,8 @@ nsAlertsIconListener::OnStopRequest(imgIRequest* aRequest, return NS_OK; } -NS_IMETHODIMP -nsAlertsIconListener::OnDiscard(imgIRequest *aRequest) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsAlertsIconListener::OnImageIsAnimated(imgIRequest *aRequest) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsAlertsIconListener::OnStopFrame(imgIRequest* aRequest, - uint32_t aFrame) +nsresult +nsAlertsIconListener::OnStopFrame(imgIRequest* aRequest) { if (aRequest != mIconRequest) return NS_ERROR_FAILURE; diff --git a/toolkit/system/gnome/nsAlertsIconListener.h b/toolkit/system/gnome/nsAlertsIconListener.h index 8f0b9443e94..ca43cccf7cf 100644 --- a/toolkit/system/gnome/nsAlertsIconListener.h +++ b/toolkit/system/gnome/nsAlertsIconListener.h @@ -7,7 +7,7 @@ #define nsAlertsIconListener_h__ #include "nsCOMPtr.h" -#include "imgIDecoderObserver.h" +#include "imgINotificationObserver.h" #include "nsStringAPI.h" #include "nsIObserver.h" #include "nsWeakReference.h" @@ -18,14 +18,13 @@ class imgIRequest; struct NotifyNotification; -class nsAlertsIconListener : public imgIDecoderObserver, +class nsAlertsIconListener : public imgINotificationObserver, public nsIObserver, public nsSupportsWeakReference { public: NS_DECL_ISUPPORTS - NS_DECL_IMGICONTAINEROBSERVER - NS_DECL_IMGIDECODEROBSERVER + NS_DECL_IMGINOTIFICATIONOBSERVER NS_DECL_NSIOBSERVER nsAlertsIconListener(); @@ -42,6 +41,9 @@ public: void SendClosed(); protected: + nsresult OnStopRequest(imgIRequest* aRequest); + nsresult OnStopFrame(imgIRequest* aRequest); + /** * The only difference between libnotify.so.4 and libnotify.so.1 for these symbols * is that notify_notification_new takes three arguments in libnotify.so.4 and diff --git a/widget/cocoa/nsMenuItemIconX.h b/widget/cocoa/nsMenuItemIconX.h index 983b5d951e3..87a49ed12ef 100644 --- a/widget/cocoa/nsMenuItemIconX.h +++ b/widget/cocoa/nsMenuItemIconX.h @@ -11,7 +11,7 @@ #define nsMenuItemIconX_h_ #include "nsCOMPtr.h" -#include "imgIDecoderObserver.h" +#include "imgINotificationObserver.h" class nsIURI; class nsIContent; @@ -20,7 +20,7 @@ class nsMenuObjectX; #import -class nsMenuItemIconX : public imgIDecoderObserver +class nsMenuItemIconX : public imgINotificationObserver { public: nsMenuItemIconX(nsMenuObjectX* aMenuItem, @@ -31,8 +31,7 @@ private: public: NS_DECL_ISUPPORTS - NS_DECL_IMGICONTAINEROBSERVER - NS_DECL_IMGIDECODEROBSERVER + NS_DECL_IMGINOTIFICATIONOBSERVER // SetupIcon succeeds if it was able to set up the icon, or if there should // be no icon, in which case it clears any existing icon but still succeeds. @@ -52,6 +51,8 @@ public: void Destroy(); protected: + nsresult OnStopFrame(imgIRequest* aRequest); + nsCOMPtr mContent; nsCOMPtr mIconRequest; nsMenuObjectX* mMenuObject; // [weak] diff --git a/widget/cocoa/nsMenuItemIconX.mm b/widget/cocoa/nsMenuItemIconX.mm index e3bcae1e689..470b81cf600 100644 --- a/widget/cocoa/nsMenuItemIconX.mm +++ b/widget/cocoa/nsMenuItemIconX.mm @@ -42,7 +42,7 @@ static const uint32_t kIconBytes = kIconBytesPerRow * kIconHeight; typedef NS_STDCALL_FUNCPROTO(nsresult, GetRectSideMethod, nsIDOMRect, GetBottom, (nsIDOMCSSPrimitiveValue**)); -NS_IMPL_ISUPPORTS2(nsMenuItemIconX, imgIContainerObserver, imgIDecoderObserver) +NS_IMPL_ISUPPORTS1(nsMenuItemIconX, imgINotificationObserver) nsMenuItemIconX::nsMenuItemIconX(nsMenuObjectX* aMenuItem, nsIContent* aContent, @@ -318,57 +318,28 @@ nsMenuItemIconX::LoadIcon(nsIURI* aIconURI) } // -// imgIContainerObserver +// imgINotificationObserver // NS_IMETHODIMP -nsMenuItemIconX::FrameChanged(imgIRequest* aRequest, - imgIContainer* aContainer, - const nsIntRect* aDirtyRect) +nsMenuItemIconX::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) { + if (aType == imgINotificationObserver::STOP_FRAME) { + return OnStopFrame(aRequest); + } + + if (aType == imgINotificationObserver::STOP_REQUEST) { + if (mIconRequest && mIconRequest == aRequest) { + mIconRequest->Cancel(NS_BINDING_ABORTED); + mIconRequest = nullptr; + } + } + return NS_OK; } -// -// imgIDecoderObserver -// - -NS_IMETHODIMP -nsMenuItemIconX::OnStartRequest(imgIRequest* aRequest) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsMenuItemIconX::OnStartDecode(imgIRequest* aRequest) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsMenuItemIconX::OnStartContainer(imgIRequest* aRequest, - imgIContainer* aContainer) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsMenuItemIconX::OnStartFrame(imgIRequest* aRequest, uint32_t aFrame) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsMenuItemIconX::OnDataAvailable(imgIRequest* aRequest, - bool aCurrentFrame, - const nsIntRect* aRect) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsMenuItemIconX::OnStopFrame(imgIRequest* aRequest, - uint32_t aFrame) +nsresult +nsMenuItemIconX::OnStopFrame(imgIRequest* aRequest) { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; @@ -491,41 +462,3 @@ nsMenuItemIconX::OnStopFrame(imgIRequest* aRequest, NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; } - -NS_IMETHODIMP -nsMenuItemIconX::OnStopContainer(imgIRequest* aRequest, - imgIContainer* aContainer) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsMenuItemIconX::OnStopDecode(imgIRequest* aRequest, - nsresult status, - const PRUnichar* statusArg) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsMenuItemIconX::OnStopRequest(imgIRequest* aRequest, - bool aIsLastPart) -{ - if (mIconRequest && mIconRequest == aRequest) { - mIconRequest->Cancel(NS_BINDING_ABORTED); - mIconRequest = nullptr; - } - return NS_OK; -} - -NS_IMETHODIMP -nsMenuItemIconX::OnDiscard(imgIRequest* aRequest) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsMenuItemIconX::OnImageIsAnimated(imgIRequest* aRequest) -{ - return NS_OK; -}