Back to index

lightning-sunbird  0.9+nobinonly
nsImageBoxFrame.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 //
00039 // Eric Vaughan
00040 // Netscape Communications
00041 //
00042 // See documentation in associated header file
00043 //
00044 
00045 #include "nsImageBoxFrame.h"
00046 #include "nsIDeviceContext.h"
00047 #include "nsIFontMetrics.h"
00048 #include "nsHTMLAtoms.h"
00049 #include "nsXULAtoms.h"
00050 #include "nsStyleContext.h"
00051 #include "nsStyleConsts.h"
00052 #include "nsCOMPtr.h"
00053 #include "nsPresContext.h"
00054 #include "nsBoxLayoutState.h"
00055 
00056 #include "nsHTMLParts.h"
00057 #include "nsString.h"
00058 #include "nsLeafFrame.h"
00059 #include "nsPresContext.h"
00060 #include "nsIRenderingContext.h"
00061 #include "nsIPresShell.h"
00062 #include "nsIImage.h"
00063 #include "nsIWidget.h"
00064 #include "nsHTMLAtoms.h"
00065 #include "nsLayoutAtoms.h"
00066 #include "nsIDocument.h"
00067 #include "nsIHTMLDocument.h"
00068 #include "nsStyleConsts.h"
00069 #include "nsImageMap.h"
00070 #include "nsILinkHandler.h"
00071 #include "nsIURL.h"
00072 #include "nsILoadGroup.h"
00073 #include "nsIView.h"
00074 #include "nsIViewManager.h"
00075 #include "nsHTMLContainerFrame.h"
00076 #include "prprf.h"
00077 #include "nsIFontMetrics.h"
00078 #include "nsCSSRendering.h"
00079 #include "nsIDOMHTMLImageElement.h"
00080 #include "nsIDeviceContext.h"
00081 #include "nsINameSpaceManager.h"
00082 #include "nsTextFragment.h"
00083 #include "nsIDOMHTMLMapElement.h"
00084 #include "nsBoxLayoutState.h"
00085 #include "nsIDOMDocument.h"
00086 #include "nsIEventQueueService.h"
00087 #include "nsTransform2D.h"
00088 #include "nsITheme.h"
00089 
00090 #include "nsIServiceManager.h"
00091 #include "nsIURI.h"
00092 #include "nsNetUtil.h"
00093 #include "nsGUIEvent.h"
00094 
00095 #include "nsContentUtils.h"
00096 
00097 #define ONLOAD_CALLED_TOO_EARLY 1
00098 
00099 static void PR_CALLBACK
00100 HandleImagePLEvent(nsIContent *aContent, PRUint32 aMessage, PRUint32 aFlags)
00101 {
00102   if (!aContent) {
00103     NS_ERROR("null node passed to HandleImagePLEvent!");
00104 
00105     return;
00106   }
00107 
00108   nsIDocument* doc = aContent->GetOwnerDoc();
00109 
00110   if (!doc) {
00111     return;
00112   }
00113 
00114   nsIPresShell *pres_shell = doc->GetShellAt(0);
00115   if (!pres_shell) {
00116     return;
00117   }
00118 
00119   nsCOMPtr<nsPresContext> pres_context = pres_shell->GetPresContext();
00120   if (!pres_context) {
00121     return;
00122   }
00123 
00124   nsEventStatus status = nsEventStatus_eIgnore;
00125   nsEvent event(PR_TRUE, aMessage);
00126 
00127   aContent->HandleDOMEvent(pres_context, &event, nsnull, aFlags, &status);
00128 }
00129 
00130 static void PR_CALLBACK
00131 HandleImageOnloadPLEvent(PLEvent *aEvent)
00132 {
00133   nsIContent *content = (nsIContent *)PL_GetEventOwner(aEvent);
00134 
00135   HandleImagePLEvent(content, NS_IMAGE_LOAD,
00136                      NS_EVENT_FLAG_INIT | NS_EVENT_FLAG_CANT_BUBBLE);
00137 
00138   NS_RELEASE(content);
00139 }
00140 
00141 static void PR_CALLBACK
00142 HandleImageOnerrorPLEvent(PLEvent *aEvent)
00143 {
00144   nsIContent *content = (nsIContent *)PL_GetEventOwner(aEvent);
00145 
00146   HandleImagePLEvent(content, NS_IMAGE_ERROR, NS_EVENT_FLAG_INIT);
00147 
00148   NS_RELEASE(content);
00149 }
00150 
00151 static void PR_CALLBACK
00152 DestroyImagePLEvent(PLEvent* aEvent)
00153 {
00154   delete aEvent;
00155 }
00156 
00157 // Fire off a PLEvent that'll asynchronously call the image elements
00158 // onload handler once handled. This is needed since the image library
00159 // can't decide if it wants to call it's observer methods
00160 // synchronously or asynchronously. If an image is loaded from the
00161 // cache the notifications come back synchronously, but if the image
00162 // is loaded from the netswork the notifications come back
00163 // asynchronously.
00164 
00165 void
00166 FireImageDOMEvent(nsIContent* aContent, PRUint32 aMessage)
00167 {
00168   static NS_DEFINE_CID(kEventQueueServiceCID,   NS_EVENTQUEUESERVICE_CID);
00169 
00170   nsCOMPtr<nsIEventQueueService> event_service =
00171     do_GetService(kEventQueueServiceCID);
00172 
00173   if (!event_service) {
00174     NS_WARNING("Failed to get event queue service");
00175 
00176     return;
00177   }
00178 
00179   nsCOMPtr<nsIEventQueue> event_queue;
00180 
00181   event_service->GetThreadEventQueue(NS_CURRENT_THREAD,
00182                                      getter_AddRefs(event_queue));
00183 
00184   if (!event_queue) {
00185     NS_WARNING("Failed to get event queue from service");
00186 
00187     return;
00188   }
00189 
00190   PLEvent *event = new PLEvent;
00191 
00192   if (!event) {
00193     // Out of memory, but none of our callers care, so just warn and
00194     // don't fire the event
00195 
00196     NS_WARNING("Out of memory?");
00197 
00198     return;
00199   }
00200 
00201   PLHandleEventProc f;
00202 
00203   switch (aMessage) {
00204   case NS_IMAGE_LOAD :
00205     f = (PLHandleEventProc)::HandleImageOnloadPLEvent;
00206 
00207     break;
00208   case NS_IMAGE_ERROR :
00209     f = (PLHandleEventProc)::HandleImageOnerrorPLEvent;
00210 
00211     break;
00212   default:
00213     NS_WARNING("Huh, I don't know how to fire this type of event?!");
00214 
00215     return;
00216   }
00217 
00218   PL_InitEvent(event, aContent, f, (PLDestroyEventProc)::DestroyImagePLEvent);
00219 
00220   // The event owns the content pointer now.
00221   NS_ADDREF(aContent);
00222 
00223   event_queue->PostEvent(event);
00224 }
00225 
00226 //
00227 // NS_NewImageBoxFrame
00228 //
00229 // Creates a new image frame and returns it in |aNewFrame|
00230 //
00231 nsresult
00232 NS_NewImageBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
00233 {
00234   NS_PRECONDITION(aNewFrame, "null OUT ptr");
00235   if (nsnull == aNewFrame) {
00236     return NS_ERROR_NULL_POINTER;
00237   }
00238   nsImageBoxFrame* it = new (aPresShell) nsImageBoxFrame (aPresShell);
00239   if (nsnull == it)
00240     return NS_ERROR_OUT_OF_MEMORY;
00241 
00242   *aNewFrame = it;
00243   return NS_OK;
00244   
00245 } // NS_NewTitledButtonFrame
00246 
00247 NS_IMETHODIMP
00248 nsImageBoxFrame::AttributeChanged(nsIContent* aChild,
00249                                   PRInt32 aNameSpaceID,
00250                                   nsIAtom* aAttribute,
00251                                   PRInt32 aModType)
00252 {
00253   nsresult rv = nsLeafBoxFrame::AttributeChanged(aChild, aNameSpaceID,
00254                                                aAttribute, aModType);
00255 
00256   if (aAttribute == nsHTMLAtoms::src) {
00257     UpdateImage();
00258     nsBoxLayoutState state(GetPresContext());
00259     MarkDirty(state);
00260   }
00261   else if (aAttribute == nsXULAtoms::validate)
00262     UpdateLoadFlags();
00263 
00264   return rv;
00265 }
00266 
00267 nsImageBoxFrame::nsImageBoxFrame(nsIPresShell* aShell) :
00268   nsLeafBoxFrame(aShell),
00269   mUseSrcAttr(PR_FALSE),
00270   mSuppressStyleCheck(PR_FALSE),
00271   mIntrinsicSize(0,0),
00272   mLoadFlags(nsIRequest::LOAD_NORMAL)
00273 {
00274   NeedsRecalc();
00275 }
00276 
00277 nsImageBoxFrame::~nsImageBoxFrame()
00278 {
00279 }
00280 
00281 
00282 NS_IMETHODIMP
00283 nsImageBoxFrame::NeedsRecalc()
00284 {
00285   SizeNeedsRecalc(mImageSize);
00286   return NS_OK;
00287 }
00288 
00289 NS_METHOD
00290 nsImageBoxFrame::Destroy(nsPresContext* aPresContext)
00291 {
00292   // Release image loader first so that it's refcnt can go to zero
00293   if (mImageRequest)
00294     mImageRequest->Cancel(NS_ERROR_FAILURE);
00295 
00296   if (mListener)
00297     NS_REINTERPRET_CAST(nsImageBoxListener*, mListener.get())->SetFrame(nsnull); // set the frame to null so we don't send messages to a dead object.
00298 
00299   return nsLeafBoxFrame::Destroy(aPresContext);
00300 }
00301 
00302 
00303 NS_IMETHODIMP
00304 nsImageBoxFrame::Init(nsPresContext*  aPresContext,
00305                           nsIContent*      aContent,
00306                           nsIFrame*        aParent,
00307                           nsStyleContext*  aContext,
00308                           nsIFrame*        aPrevInFlow)
00309 {
00310   if (!mListener) {
00311     nsImageBoxListener *listener;
00312     NS_NEWXPCOM(listener, nsImageBoxListener);
00313     NS_ADDREF(listener);
00314     listener->SetFrame(this);
00315     listener->QueryInterface(NS_GET_IID(imgIDecoderObserver), getter_AddRefs(mListener));
00316     NS_RELEASE(listener);
00317   }
00318 
00319   mSuppressStyleCheck = PR_TRUE;
00320   nsresult  rv = nsLeafBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
00321   mSuppressStyleCheck = PR_FALSE;
00322 
00323   UpdateLoadFlags();
00324   UpdateImage();
00325 
00326   return rv;
00327 }
00328 
00329 void
00330 nsImageBoxFrame::UpdateImage()
00331 {
00332   if (mImageRequest) {
00333     mImageRequest->Cancel(NS_ERROR_FAILURE);
00334     mImageRequest = nsnull;
00335   }
00336 
00337   // get the new image src
00338   nsAutoString src;
00339   mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::src, src);
00340   mUseSrcAttr = !src.IsEmpty();
00341   if (mUseSrcAttr) {
00342     nsIDocument* doc = mContent->GetDocument();
00343     if (!doc) {
00344       // No need to do anything here...
00345       return;
00346     }
00347     nsCOMPtr<nsIURI> baseURI = mContent->GetBaseURI();
00348     nsCOMPtr<nsIURI> uri;
00349     nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri),
00350                                               src,
00351                                               doc,
00352                                               baseURI);
00353 
00354     if (uri && nsContentUtils::CanLoadImage(uri, mContent, doc)) {
00355       nsContentUtils::LoadImage(uri, doc, doc->GetDocumentURI(),
00356                                 mListener, mLoadFlags,
00357                                 getter_AddRefs(mImageRequest));
00358     }
00359   } else {
00360     // Only get the list-style-image if we aren't being drawn
00361     // by a native theme.
00362     PRUint8 appearance = GetStyleDisplay()->mAppearance;
00363     if (!(appearance && nsBox::gTheme && 
00364           nsBox::gTheme->ThemeSupportsWidget(nsnull, this, appearance))) {
00365       // get the list-style-image
00366       imgIRequest *styleRequest = GetStyleList()->mListStyleImage;
00367       if (styleRequest) {
00368         styleRequest->Clone(mListener, getter_AddRefs(mImageRequest));
00369       }
00370     }
00371   }
00372 
00373   if (!mImageRequest) {
00374     // We have no image, so size to 0
00375     mIntrinsicSize.SizeTo(0, 0);
00376   }
00377 }
00378 
00379 void
00380 nsImageBoxFrame::UpdateLoadFlags()
00381 {
00382   nsAutoString loadPolicy;
00383   mContent->GetAttr(kNameSpaceID_None, nsXULAtoms::validate, loadPolicy);
00384   if (loadPolicy.EqualsLiteral("always"))
00385     mLoadFlags = nsIRequest::VALIDATE_ALWAYS;
00386   else if (loadPolicy.EqualsLiteral("never"))
00387     mLoadFlags = nsIRequest::VALIDATE_NEVER|nsIRequest::LOAD_FROM_CACHE; 
00388   else
00389     mLoadFlags = nsIRequest::LOAD_NORMAL;
00390 }
00391 
00392 NS_IMETHODIMP
00393 nsImageBoxFrame::Paint(nsPresContext*      aPresContext,
00394                        nsIRenderingContext& aRenderingContext,
00395                        const nsRect&        aDirtyRect,
00396                        nsFramePaintLayer    aWhichLayer,
00397                        PRUint32             aFlags)
00398 {      
00399   if (!GetStyleVisibility()->IsVisible())
00400     return NS_OK;
00401 
00402   nsresult rv = nsLeafBoxFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
00403 
00404   PaintImage(aRenderingContext, aDirtyRect, aWhichLayer);
00405 
00406   return rv;
00407 }
00408 
00409 
00410 void
00411 nsImageBoxFrame::PaintImage(nsIRenderingContext& aRenderingContext,
00412                             const nsRect& aDirtyRect,
00413                             nsFramePaintLayer aWhichLayer)
00414 {
00415   if ((0 == mRect.width) || (0 == mRect.height)) {
00416     // Do not render when given a zero area. This avoids some useless
00417     // scaling work while we wait for our image dimensions to arrive
00418     // asynchronously.
00419     return;
00420   }
00421 
00422   nsRect rect;
00423   GetClientRect(rect);
00424 
00425   if (NS_FRAME_PAINT_LAYER_FOREGROUND != aWhichLayer)
00426     return;
00427 
00428   if (!mImageRequest)
00429     return;
00430 
00431   // don't draw if the image is not dirty
00432   if (!aDirtyRect.Intersects(rect))
00433     return;
00434 
00435   nsCOMPtr<imgIContainer> imgCon;
00436   mImageRequest->GetImage(getter_AddRefs(imgCon));
00437 
00438   if (imgCon) {
00439     PRBool hasSubRect = !mUseSrcAttr && (mSubRect.width > 0 || mSubRect.height > 0);
00440     PRBool sizeMatch = hasSubRect ? 
00441                        mSubRect.width == rect.width && mSubRect.height == rect.height :
00442                        mImageSize.width == rect.width && mImageSize.height == rect.height;
00443 
00444     if (sizeMatch) {
00445       nsRect dest(rect);
00446         
00447       if (hasSubRect)
00448         rect = mSubRect;
00449       else {
00450         rect.x = 0;
00451         rect.y = 0;
00452       }
00453 
00454       // XXXdwh do dirty rect intersection like the HTML image frame does,
00455       // so that we don't always repaint the entire image!
00456       aRenderingContext.DrawImage(imgCon, rect, dest);
00457     }
00458     else {
00459       nsRect src(0, 0, mImageSize.width, mImageSize.height);
00460       if (hasSubRect)
00461         src = mSubRect;
00462       aRenderingContext.DrawImage(imgCon, src, rect);
00463     }
00464   }
00465 }
00466 
00467 
00468 //
00469 // DidSetStyleContext
00470 //
00471 // When the style context changes, make sure that all of our image is up to date.
00472 //
00473 NS_IMETHODIMP
00474 nsImageBoxFrame::DidSetStyleContext( nsPresContext* aPresContext )
00475 {
00476   // Fetch our subrect.
00477   const nsStyleList* myList = GetStyleList();
00478   mSubRect = myList->mImageRegion; // before |mSuppressStyleCheck| test!
00479 
00480   if (mUseSrcAttr || mSuppressStyleCheck)
00481     return NS_OK; // No more work required, since the image isn't specified by style.
00482 
00483   // If we're using a native theme implementation, we shouldn't draw anything.
00484   const nsStyleDisplay* disp = GetStyleDisplay();
00485   if (disp->mAppearance && nsBox::gTheme && 
00486       nsBox::gTheme->ThemeSupportsWidget(nsnull, this, disp->mAppearance))
00487     return NS_OK;
00488 
00489   // If list-style-image changes, we have a new image.
00490   nsCOMPtr<nsIURI> oldURI, newURI;
00491   if (mImageRequest)
00492     mImageRequest->GetURI(getter_AddRefs(oldURI));
00493   if (myList->mListStyleImage)
00494     myList->mListStyleImage->GetURI(getter_AddRefs(newURI));
00495   PRBool equal;
00496   if (newURI == oldURI ||   // handles null==null
00497       (newURI && oldURI &&
00498        NS_SUCCEEDED(newURI->Equals(oldURI, &equal)) && equal))
00499     return NS_OK;
00500 
00501   UpdateImage();
00502   return NS_OK;
00503 } // DidSetStyleContext
00504 
00505 void
00506 nsImageBoxFrame::GetImageSize()
00507 {
00508   if (mIntrinsicSize.width > 0 && mIntrinsicSize.height > 0) {
00509     mImageSize.width = mIntrinsicSize.width;
00510     mImageSize.height = mIntrinsicSize.height;
00511   } else {
00512     mImageSize.width = 0;
00513     mImageSize.height = 0;
00514   }
00515 }
00516 
00517 
00521 NS_IMETHODIMP
00522 nsImageBoxFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
00523 {
00524   if (DoesNeedRecalc(mImageSize)) {
00525      GetImageSize();
00526   }
00527 
00528   if (!mUseSrcAttr && (mSubRect.width > 0 || mSubRect.height > 0))
00529     aSize = nsSize(mSubRect.width, mSubRect.height);
00530   else
00531     aSize = mImageSize;
00532   AddBorderAndPadding(aSize);
00533   AddInset(aSize);
00534   nsIBox::AddCSSPrefSize(aState, this, aSize);
00535 
00536   nsSize minSize(0,0);
00537   nsSize maxSize(0,0);
00538   GetMinSize(aState, minSize);
00539   GetMaxSize(aState, maxSize);
00540 
00541   BoundsCheck(minSize, aSize, maxSize);
00542 
00543   return NS_OK;
00544 }
00545 
00546 NS_IMETHODIMP
00547 nsImageBoxFrame::GetMinSize(nsBoxLayoutState& aState, nsSize& aSize)
00548 {
00549   // An image can always scale down to (0,0).
00550   aSize.width = aSize.height = 0;
00551   AddBorderAndPadding(aSize);
00552   AddInset(aSize);
00553   nsIBox::AddCSSMinSize(aState, this, aSize);
00554   return NS_OK;
00555 }
00556 
00557 NS_IMETHODIMP
00558 nsImageBoxFrame::GetAscent(nsBoxLayoutState& aState, nscoord& aCoord)
00559 {
00560   nsSize size(0,0);
00561   GetPrefSize(aState, size);
00562   aCoord = size.height;
00563   return NS_OK;
00564 }
00565 
00566 nsIAtom*
00567 nsImageBoxFrame::GetType() const
00568 {
00569   return nsLayoutAtoms::imageBoxFrame;
00570 }
00571 
00572 #ifdef DEBUG
00573 NS_IMETHODIMP
00574 nsImageBoxFrame::GetFrameName(nsAString& aResult) const
00575 {
00576   return MakeFrameName(NS_LITERAL_STRING("ImageBox"), aResult);
00577 }
00578 #endif
00579 
00580 
00581 NS_IMETHODIMP nsImageBoxFrame::OnStartContainer(imgIRequest *request,
00582                                                 imgIContainer *image)
00583 {
00584   NS_ENSURE_ARG_POINTER(image);
00585 
00586   // Ensure the animation (if any) is started
00587   image->StartAnimation();
00588 
00589   nscoord w, h;
00590   image->GetWidth(&w);
00591   image->GetHeight(&h);
00592 
00593   nsPresContext* presContext = GetPresContext();
00594   float p2t = presContext->PixelsToTwips();
00595 
00596   mIntrinsicSize.SizeTo(NSIntPixelsToTwips(w, p2t), NSIntPixelsToTwips(h, p2t));
00597 
00598   nsBoxLayoutState state(presContext);
00599   this->MarkDirty(state);
00600 
00601   return NS_OK;
00602 }
00603 
00604 NS_IMETHODIMP nsImageBoxFrame::OnStopContainer(imgIRequest *request,
00605                                                imgIContainer *image)
00606 {
00607   nsBoxLayoutState state(GetPresContext());
00608   this->Redraw(state);
00609 
00610   return NS_OK;
00611 }
00612 
00613 NS_IMETHODIMP nsImageBoxFrame::OnStopDecode(imgIRequest *request,
00614                                             nsresult aStatus,
00615                                             const PRUnichar *statusArg)
00616 {
00617   if (NS_SUCCEEDED(aStatus))
00618     // Fire an onload DOM event.
00619     FireImageDOMEvent(mContent, NS_IMAGE_LOAD);
00620   else {
00621     // Fire an onerror DOM event.
00622     mIntrinsicSize.SizeTo(0, 0);
00623     nsBoxLayoutState state(GetPresContext());
00624     MarkDirty(state);
00625     FireImageDOMEvent(mContent, NS_IMAGE_ERROR);
00626   }
00627 
00628   return NS_OK;
00629 }
00630 
00631 NS_IMETHODIMP nsImageBoxFrame::FrameChanged(imgIContainer *container,
00632                                             gfxIImageFrame *newframe,
00633                                             nsRect * dirtyRect)
00634 {
00635   nsBoxLayoutState state(GetPresContext());
00636   this->Redraw(state);
00637 
00638   return NS_OK;
00639 }
00640 
00641 NS_IMPL_ISUPPORTS2(nsImageBoxListener, imgIDecoderObserver, imgIContainerObserver)
00642 
00643 nsImageBoxListener::nsImageBoxListener()
00644 {
00645 }
00646 
00647 nsImageBoxListener::~nsImageBoxListener()
00648 {
00649 }
00650 
00651 NS_IMETHODIMP nsImageBoxListener::OnStartDecode(imgIRequest *request)
00652 {
00653   return NS_OK;
00654 }
00655 
00656 NS_IMETHODIMP nsImageBoxListener::OnStartContainer(imgIRequest *request,
00657                                                    imgIContainer *image)
00658 {
00659   if (!mFrame)
00660     return NS_ERROR_FAILURE;
00661 
00662   return mFrame->OnStartContainer(request, image);
00663 }
00664 
00665 NS_IMETHODIMP nsImageBoxListener::OnStartFrame(imgIRequest *request,
00666                                                gfxIImageFrame *frame)
00667 {
00668   return NS_OK;
00669 }
00670 
00671 NS_IMETHODIMP nsImageBoxListener::OnDataAvailable(imgIRequest *request,
00672                                                   gfxIImageFrame *frame,
00673                                                   const nsRect * rect)
00674 {
00675   return NS_OK;
00676 }
00677 
00678 NS_IMETHODIMP nsImageBoxListener::OnStopFrame(imgIRequest *request,
00679                                               gfxIImageFrame *frame)
00680 {
00681   return NS_OK;
00682 }
00683 
00684 NS_IMETHODIMP nsImageBoxListener::OnStopContainer(imgIRequest *request,
00685                                                   imgIContainer *image)
00686 {
00687   if (!mFrame)
00688     return NS_ERROR_FAILURE;
00689 
00690   return mFrame->OnStopContainer(request, image);
00691 }
00692 
00693 NS_IMETHODIMP nsImageBoxListener::OnStopDecode(imgIRequest *request,
00694                                                nsresult status,
00695                                                const PRUnichar *statusArg)
00696 {
00697   if (!mFrame)
00698     return NS_ERROR_FAILURE;
00699 
00700   return mFrame->OnStopDecode(request, status, statusArg);
00701 }
00702 
00703 NS_IMETHODIMP nsImageBoxListener::FrameChanged(imgIContainer *container,
00704                                                gfxIImageFrame *newframe,
00705                                                nsRect * dirtyRect)
00706 {
00707   if (!mFrame)
00708     return NS_ERROR_FAILURE;
00709 
00710   return mFrame->FrameChanged(container, newframe, dirtyRect);
00711 }
00712