Back out bug 666446 due to Talos regression.

This commit is contained in:
Justin Lebar 2011-11-02 20:11:01 -04:00
Родитель 24f8b943d0
Коммит 81c40942af
48 изменённых файлов: 214 добавлений и 2014 удалений

Просмотреть файл

@ -42,7 +42,6 @@ interface nsIChannel;
interface nsIStreamListener;
interface nsIURI;
interface nsIDocument;
interface nsIFrame;
/**
* This interface represents a content node that loads images. The interface
@ -66,7 +65,7 @@ interface nsIFrame;
* sufficient, when combined with the imageBlockingStatus information.)
*/
[scriptable, uuid(f7debb84-2854-4731-a57b-1bd752ad71f8)]
[scriptable, uuid(95c74255-df9a-4060-b5a0-0d111fcafe08)]
interface nsIImageLoadingContent : imgIDecoderObserver
{
/**
@ -129,18 +128,6 @@ interface nsIImageLoadingContent : imgIDecoderObserver
*/
imgIRequest getRequest(in long aRequestType);
/**
* Used to notify the image loading content node that a frame has been
* created.
*/
[notxpcom] void frameCreated(in nsIFrame aFrame);
/**
* Used to notify the image loading content node that a frame has been
* destroyed.
*/
[notxpcom] void frameDestroyed(in nsIFrame aFrame);
/**
* Used to find out what type of request one is dealing with (eg
* which request got passed through to the imgIDecoderObserver

Просмотреть файл

@ -3225,7 +3225,6 @@ nsDocument::DeleteShell()
if (IsEventHandlingEnabled()) {
RevokeAnimationFrameNotifications();
}
mPresShell = nsnull;
}

Просмотреть файл

@ -72,7 +72,6 @@
#include "nsIDOMNode.h"
#include "nsContentUtils.h"
#include "nsLayoutUtils.h"
#include "nsIContentPolicy.h"
#include "nsContentPolicyUtils.h"
#include "nsEventDispatcher.h"
@ -116,9 +115,7 @@ nsImageLoadingContent::nsImageLoadingContent()
mNewRequestsWillNeedAnimationReset(false),
mPendingRequestNeedsResetAnimation(false),
mCurrentRequestNeedsResetAnimation(false),
mStateChangerDepth(0),
mCurrentRequestRegistered(false),
mPendingRequestRegistered(false)
mStateChangerDepth(0)
{
if (!nsContentUtils::GetImgLoader()) {
mLoadingEnabled = false;
@ -199,16 +196,7 @@ nsImageLoadingContent::OnStartDecode(imgIRequest* aRequest)
SetBlockingOnload(true);
}
}
bool* requestFlag = GetRegisteredFlagForRequest(aRequest);
if (requestFlag) {
nsLayoutUtils::RegisterImageRequest(GetFramePresContext(), aRequest,
requestFlag);
} else {
NS_ERROR("Starting to decode an image other than our current/pending "
"request?");
}
LOOP_OVER_OBSERVERS(OnStartDecode(aRequest));
return NS_OK;
}
@ -341,13 +329,6 @@ nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest,
nsIPresShell* shell = doc ? doc->GetShell() : nsnull;
if (shell) {
// Make sure that our image requests are deregistered from the refresh
// driver if they aren't animated. Note that this must be mCurrentRequest,
// or we would have aborted up above.
nsLayoutUtils::DeregisterImageRequestIfNotAnimated(GetFramePresContext(),
mCurrentRequest,
&mCurrentRequestRegistered);
// We need to figure out whether to kick off decoding
bool doRequestDecode = false;
@ -520,44 +501,6 @@ nsImageLoadingContent::GetRequest(PRInt32 aRequestType,
return NS_OK;
}
NS_IMETHODIMP_(void)
nsImageLoadingContent::FrameCreated(nsIFrame* aFrame)
{
NS_ASSERTION(aFrame, "aFrame is null");
// We need to make sure that our image request is registered.
nsPresContext* presContext = aFrame->PresContext();
if (mCurrentRequest) {
nsLayoutUtils::RegisterImageRequest(presContext, mCurrentRequest,
&mCurrentRequestRegistered);
nsLayoutUtils::DeregisterImageRequestIfNotAnimated(presContext,
mCurrentRequest,
&mCurrentRequestRegistered);
} else if (mPendingRequest) {
// We don't need to do the same check for animation, because this will be
// done when decoding is finished.
nsLayoutUtils::RegisterImageRequest(presContext, mPendingRequest,
&mPendingRequestRegistered);
}
}
NS_IMETHODIMP_(void)
nsImageLoadingContent::FrameDestroyed(nsIFrame* aFrame)
{
NS_ASSERTION(aFrame, "aFrame is null");
// We need to make sure that our image request is deregistered.
if (mCurrentRequest) {
nsLayoutUtils::DeregisterImageRequest(GetFramePresContext(),
mCurrentRequest,
&mCurrentRequestRegistered);
} else if (mPendingRequest) {
nsLayoutUtils::DeregisterImageRequest(GetFramePresContext(),
mPendingRequest,
&mPendingRequestRegistered);
}
}
NS_IMETHODIMP
nsImageLoadingContent::GetRequestType(imgIRequest* aRequest,
@ -924,23 +867,6 @@ nsImageLoadingContent::GetOurDocument()
return thisContent->OwnerDoc();
}
nsIFrame*
nsImageLoadingContent::GetOurPrimaryFrame()
{
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
return thisContent->GetPrimaryFrame();
}
nsPresContext* nsImageLoadingContent::GetFramePresContext()
{
nsIFrame* frame = GetOurPrimaryFrame();
if (!frame) {
return nsnull;
}
return frame->PresContext();
}
nsresult
nsImageLoadingContent::StringToURI(const nsAString& aSpec,
nsIDocument* aDocument,
@ -1060,16 +986,6 @@ nsImageLoadingContent::ClearCurrentRequest(nsresult aReason)
NS_ABORT_IF_FALSE(!mCurrentURI,
"Shouldn't have both mCurrentRequest and mCurrentURI!");
// Deregister this image from the refresh driver so it no longer receives
// notifications.
nsLayoutUtils::DeregisterImageRequest(GetFramePresContext(), mCurrentRequest,
&mCurrentRequestRegistered);
// Deregister this image from the refresh driver so it no longer receives
// notifications.
nsLayoutUtils::DeregisterImageRequest(GetFramePresContext(), mCurrentRequest,
&mCurrentRequestRegistered);
// Clean up the request.
UntrackImage(mCurrentRequest);
mCurrentRequest->CancelAndForgetObserver(aReason);
@ -1093,29 +1009,12 @@ nsImageLoadingContent::ClearPendingRequest(nsresult aReason)
nsCxPusher pusher;
pusher.PushNull();
// Deregister this image from the refresh driver so it no longer receives
// notifications.
nsLayoutUtils::DeregisterImageRequest(GetFramePresContext(), mPendingRequest,
&mPendingRequestRegistered);
UntrackImage(mPendingRequest);
mPendingRequest->CancelAndForgetObserver(aReason);
mPendingRequest = nsnull;
mPendingRequestNeedsResetAnimation = false;
}
bool*
nsImageLoadingContent::GetRegisteredFlagForRequest(imgIRequest* aRequest)
{
if (aRequest == mCurrentRequest) {
return &mCurrentRequestRegistered;
} else if (aRequest == mPendingRequest) {
return &mPendingRequestRegistered;
} else {
return nsnull;
}
}
bool
nsImageLoadingContent::HaveSize(imgIRequest *aImage)
{

Просмотреть файл

@ -146,24 +146,6 @@ protected:
*/
nsIDocument* GetOurDocument();
/**
* Helper function to get the frame associated with this content. Not named
* GetPrimaryFrame to prevent ambiguous method names in subclasses.
*
* @return The frame which we belong to, or nsnull if it doesn't exist.
*/
nsIFrame* GetOurPrimaryFrame();
/**
* Helper function to get the PresContext associated with this content's
* frame. Not named GetPresContext to prevent ambiguous method names in
* subclasses.
*
* @return The nsPresContext associated with our frame, or nsnull if either
* the frame doesn't exist, or the frame's prescontext doesn't exist.
*/
nsPresContext* GetFramePresContext();
/**
* CancelImageRequests is called by subclasses when they want to
* cancel all image requests (for example when the subclass is
@ -320,16 +302,6 @@ protected:
void ClearCurrentRequest(nsresult aReason);
void ClearPendingRequest(nsresult aReason);
/**
* Retrieve a pointer to the 'registered with the refresh driver' flag for
* which a particular image request corresponds.
*
* @returns A pointer to the boolean flag for a given image request, or
* |nsnull| if the request is not either |mPendingRequest| or
* |mCurrentRequest|.
*/
bool* GetRegisteredFlagForRequest(imgIRequest* aRequest);
/**
* Static helper method to tell us if we have the size of a request. The
* image may be null.
@ -410,11 +382,6 @@ private:
/* The number of nested AutoStateChangers currently tracking our state. */
PRUint8 mStateChangerDepth;
// Flags to indicate whether each of the current and pending requests are
// registered with the refresh driver.
bool mCurrentRequestRegistered;
bool mPendingRequestRegistered;
};
#endif // nsImageLoadingContent_h__

Просмотреть файл

@ -56,10 +56,6 @@ interface imgIDecoderObserver;
#include "limits.h"
class nsIFrame;
namespace mozilla {
class TimeStamp;
}
%}
[ptr] native gfxImageSurface(gfxImageSurface);
@ -72,7 +68,6 @@ native gfxGraphicsFilter(gfxPattern::GraphicsFilter);
[ref] native nsIntRect(nsIntRect);
[ref] native nsIntSize(nsIntSize);
[ptr] native nsIFrame(nsIFrame);
[ref] native TimeStamp(mozilla::TimeStamp);
/**
* imgIContainer is the interface that represents an image. It allows
@ -266,13 +261,6 @@ interface imgIContainer : nsISupports
*/
void unlockImage();
/**
* Indicates that this imgIContainer has been triggered to update
* its internal animation state. Likely this should only be called
* from within nsImageFrame or objects of similar type.
*/
[notxpcom] void requestRefresh([const] in TimeStamp aTime);
/**
* Animation mode Constants
* 0 = normal

Просмотреть файл

@ -173,10 +173,10 @@ namespace mozilla {
namespace imagelib {
#ifndef DEBUG
NS_IMPL_ISUPPORTS3(RasterImage, imgIContainer, nsIProperties,
NS_IMPL_ISUPPORTS4(RasterImage, imgIContainer, nsITimerCallback, nsIProperties,
nsISupportsWeakReference)
#else
NS_IMPL_ISUPPORTS4(RasterImage, imgIContainer, nsIProperties,
NS_IMPL_ISUPPORTS5(RasterImage, imgIContainer, nsITimerCallback, nsIProperties,
imgIContainerDebug, nsISupportsWeakReference)
#endif
@ -313,169 +313,6 @@ RasterImage::Init(imgIDecoderObserver *aObserver,
return NS_OK;
}
bool
RasterImage::AdvanceFrame(TimeStamp aTime, nsIntRect* aDirtyRect)
{
NS_ASSERTION(aTime <= TimeStamp::Now(),
"Given time appears to be in the future");
imgFrame* nextFrame = nsnull;
PRUint32 currentFrameIndex = mAnim->currentAnimationFrameIndex;
PRUint32 nextFrameIndex = mAnim->currentAnimationFrameIndex + 1;
PRUint32 timeout = 0;
// Figure out if we have the next full frame. This is more complicated than
// just checking for mFrames.Length() because decoders append their frames
// before they're filled in.
NS_ABORT_IF_FALSE(mDecoder || nextFrameIndex <= mFrames.Length(),
"How did we get 2 indices too far by incrementing?");
// If we don't have a decoder, we know we've got everything we're going to
// get. If we do, we only display fully-downloaded frames; everything else
// gets delayed.
bool haveFullNextFrame = !mDecoder ||
nextFrameIndex < mDecoder->GetCompleteFrameCount();
// If we're done decoding the next frame, go ahead and display it now and
// reinit with the next frame's delay time.
if (haveFullNextFrame) {
if (mFrames.Length() == nextFrameIndex) {
// End of Animation, unless we are looping forever
// If animation mode is "loop once", it's time to stop animating
if (mAnimationMode == kLoopOnceAnimMode || mLoopCount == 0) {
mAnimationFinished = PR_TRUE;
EvaluateAnimation();
}
// We may have used compositingFrame to build a frame, and then copied
// it back into mFrames[..]. If so, delete composite to save memory
if (mAnim->compositingFrame && mAnim->lastCompositedFrameIndex == -1) {
mAnim->compositingFrame = nsnull;
}
nextFrameIndex = 0;
if (mLoopCount > 0) {
mLoopCount--;
}
if (!mAnimating) {
// break out early if we are actually done animating
return false;
}
}
if (!(nextFrame = mFrames[nextFrameIndex])) {
// something wrong with the next frame, skip it
mAnim->currentAnimationFrameIndex = nextFrameIndex;
return false;
}
timeout = nextFrame->GetTimeout();
} else {
// Uh oh, the frame we want to show is currently being decoded (partial)
// Wait until the next refresh driver tick and try again
return false;
}
if (!(timeout > 0)) {
mAnimationFinished = PR_TRUE;
EvaluateAnimation();
}
imgFrame *frameToUse = nsnull;
if (nextFrameIndex == 0) {
frameToUse = nextFrame;
*aDirtyRect = mAnim->firstFrameRefreshArea;
} else {
imgFrame *curFrame = mFrames[currentFrameIndex];
if (!curFrame) {
return false;
}
// Change frame
if (NS_FAILED(DoComposite(aDirtyRect, curFrame,
nextFrame, nextFrameIndex))) {
// something went wrong, move on to next
NS_WARNING("RasterImage::AdvanceFrame(): Compositing of frame failed");
nextFrame->SetCompositingFailed(PR_TRUE);
mAnim->currentAnimationFrameIndex = nextFrameIndex;
mAnim->currentAnimationFrameTime = aTime;
return false;
}
nextFrame->SetCompositingFailed(PR_FALSE);
}
// Set currentAnimationFrameIndex at the last possible moment
mAnim->currentAnimationFrameIndex = nextFrameIndex;
mAnim->currentAnimationFrameTime = aTime;
return true;
}
//******************************************************************************
// [notxpcom] void requestRefresh ([const] in TimeStamp aTime);
NS_IMETHODIMP_(void)
RasterImage::RequestRefresh(const mozilla::TimeStamp& aTime)
{
if (!mAnimating || !ShouldAnimate()) {
return;
}
EnsureAnimExists();
// only advance the frame if the current time is greater than or
// equal to the current frame's end time.
TimeStamp currentFrameEndTime = GetCurrentImgFrameEndTime();
bool frameAdvanced = false;
// The dirtyRect variable will contain an accumulation of the sub-rectangles
// that are dirty for each frame we advance in AdvanceFrame().
nsIntRect dirtyRect;
while (currentFrameEndTime <= aTime) {
TimeStamp oldFrameEndTime = currentFrameEndTime;
nsIntRect frameDirtyRect;
bool didAdvance = AdvanceFrame(aTime, &frameDirtyRect);
frameAdvanced = frameAdvanced || didAdvance;
currentFrameEndTime = GetCurrentImgFrameEndTime();
// Accumulate the dirty area.
dirtyRect = dirtyRect.Union(frameDirtyRect);
// if we didn't advance a frame, and our frame end time didn't change,
// then we need to break out of this loop & wait for the frame(s)
// to finish downloading
if (!frameAdvanced && (currentFrameEndTime == oldFrameEndTime)) {
break;
}
}
if (frameAdvanced) {
nsCOMPtr<imgIContainerObserver> observer(do_QueryReferent(mObserver));
if (!observer) {
NS_ERROR("Refreshing image after its imgRequest is gone");
StopAnimation();
return;
}
// Notify listeners that our frame has actually changed, but do this only
// once for all frames that we've now passed (if AdvanceFrame() was called
// more than once).
#ifdef DEBUG
mFramesNotified++;
#endif
observer->FrameChanged(this, &dirtyRect);
}
}
//******************************************************************************
/* [noscript] imgIContainer extractFrame(PRUint32 aWhichFrame,
* [const] in nsIntRect aRegion,
@ -657,27 +494,6 @@ RasterImage::GetCurrentImgFrameIndex() const
return 0;
}
TimeStamp
RasterImage::GetCurrentImgFrameEndTime() const
{
imgFrame* currentFrame = mFrames[mAnim->currentAnimationFrameIndex];
TimeStamp currentFrameTime = mAnim->currentAnimationFrameTime;
PRInt64 timeout = currentFrame->GetTimeout();
if (timeout < 0) {
// We need to return a sentinel value in this case, because our logic
// doesn't work correctly if we have a negative timeout value. The reason
// this positive infinity was chosen was because it works with the loop in
// RequestRefresh() above.
return TimeStamp() + TimeDuration::FromMilliseconds(UINT64_MAX_VAL);
}
TimeDuration durationOfTimeout = TimeDuration::FromMilliseconds(timeout);
TimeStamp currentFrameEndTime = currentFrameTime + durationOfTimeout;
return currentFrameEndTime;
}
imgFrame*
RasterImage::GetCurrentImgFrame()
{
@ -1322,18 +1138,25 @@ RasterImage::StartAnimation()
EnsureAnimExists();
imgFrame* currentFrame = GetCurrentImgFrame();
NS_ABORT_IF_FALSE(mAnim && !mAnim->timer, "Anim must exist and not have a timer yet");
// Default timeout to 100: the timer notify code will do the right
// thing, so just get that started.
PRInt32 timeout = 100;
imgFrame *currentFrame = GetCurrentImgFrame();
if (currentFrame) {
if (currentFrame->GetTimeout() < 0) { // -1 means display this frame forever
timeout = currentFrame->GetTimeout();
if (timeout < 0) { // -1 means display this frame forever
mAnimationFinished = true;
return NS_ERROR_ABORT;
}
// We need to set the time that this initial frame was first displayed, as
// this is used in AdvanceFrame().
mAnim->currentAnimationFrameTime = TimeStamp::Now();
}
mAnim->timer = do_CreateInstance("@mozilla.org/timer;1");
NS_ENSURE_TRUE(mAnim->timer, NS_ERROR_OUT_OF_MEMORY);
mAnim->timer->InitWithCallback(static_cast<nsITimerCallback*>(this),
timeout, nsITimer::TYPE_REPEATING_SLACK);
return NS_OK;
}
@ -1347,6 +1170,11 @@ RasterImage::StopAnimation()
if (mError)
return NS_ERROR_FAILURE;
if (mAnim->timer) {
mAnim->timer->Cancel();
mAnim->timer = nsnull;
}
return NS_OK;
}
@ -1602,6 +1430,127 @@ RasterImage::SetSourceSizeHint(PRUint32 sizeHint)
return NS_OK;
}
//******************************************************************************
/* void notify(in nsITimer timer); */
NS_IMETHODIMP
RasterImage::Notify(nsITimer *timer)
{
#ifdef DEBUG
mFramesNotified++;
#endif
// This should never happen since the timer is only set up in StartAnimation()
// after mAnim is checked to exist.
NS_ABORT_IF_FALSE(mAnim, "Need anim for Notify()");
NS_ABORT_IF_FALSE(timer, "Need timer for Notify()");
NS_ABORT_IF_FALSE(mAnim->timer == timer,
"RasterImage::Notify() called with incorrect timer");
if (!mAnimating || !ShouldAnimate())
return NS_OK;
nsCOMPtr<imgIContainerObserver> observer(do_QueryReferent(mObserver));
if (!observer) {
// the imgRequest that owns us is dead, we should die now too.
NS_ABORT_IF_FALSE(mAnimationConsumers == 0,
"If no observer, should have no consumers");
if (mAnimating)
StopAnimation();
return NS_OK;
}
if (mFrames.Length() == 0)
return NS_OK;
imgFrame *nextFrame = nsnull;
PRInt32 previousFrameIndex = mAnim->currentAnimationFrameIndex;
PRUint32 nextFrameIndex = mAnim->currentAnimationFrameIndex + 1;
PRInt32 timeout = 0;
// Figure out if we have the next full frame. This is more complicated than
// just checking for mFrames.Length() because decoders append their frames
// before they're filled in.
NS_ABORT_IF_FALSE(mDecoder || nextFrameIndex <= mFrames.Length(),
"How did we get 2 indicies too far by incrementing?");
// If we don't have a decoder, we know we've got everything we're going to get.
// If we do, we only display fully-downloaded frames; everything else gets delayed.
bool haveFullNextFrame = !mDecoder || nextFrameIndex < mDecoder->GetCompleteFrameCount();
// If we're done decoding the next frame, go ahead and display it now and
// reinit the timer with the next frame's delay time.
if (haveFullNextFrame) {
if (mFrames.Length() == nextFrameIndex) {
// End of Animation
// If animation mode is "loop once", it's time to stop animating
if (mAnimationMode == kLoopOnceAnimMode || mLoopCount == 0) {
mAnimationFinished = true;
EvaluateAnimation();
return NS_OK;
} else {
// We may have used compositingFrame to build a frame, and then copied
// it back into mFrames[..]. If so, delete composite to save memory
if (mAnim->compositingFrame && mAnim->lastCompositedFrameIndex == -1)
mAnim->compositingFrame = nsnull;
}
nextFrameIndex = 0;
if (mLoopCount > 0)
mLoopCount--;
}
if (!(nextFrame = mFrames[nextFrameIndex])) {
// something wrong with the next frame, skip it
mAnim->currentAnimationFrameIndex = nextFrameIndex;
mAnim->timer->SetDelay(100);
return NS_OK;
}
timeout = nextFrame->GetTimeout();
} else {
// Uh oh, the frame we want to show is currently being decoded (partial)
// Wait a bit and try again
mAnim->timer->SetDelay(100);
return NS_OK;
}
if (timeout > 0)
mAnim->timer->SetDelay(timeout);
else {
mAnimationFinished = true;
EvaluateAnimation();
}
nsIntRect dirtyRect;
if (nextFrameIndex == 0) {
dirtyRect = mAnim->firstFrameRefreshArea;
} else {
imgFrame *prevFrame = mFrames[previousFrameIndex];
if (!prevFrame)
return NS_OK;
// Change frame and announce it
if (NS_FAILED(DoComposite(&dirtyRect, prevFrame,
nextFrame, nextFrameIndex))) {
// something went wrong, move on to next
NS_WARNING("RasterImage::Notify(): Composing Frame Failed\n");
nextFrame->SetCompositingFailed(true);
mAnim->currentAnimationFrameIndex = nextFrameIndex;
return NS_OK;
} else {
nextFrame->SetCompositingFailed(false);
}
}
// Set currentAnimationFrameIndex at the last possible moment
mAnim->currentAnimationFrameIndex = nextFrameIndex;
// Refreshes the screen
observer->FrameChanged(this, &dirtyRect);
return NS_OK;
}
//******************************************************************************
// DoComposite gets called when the timer for animation get fired and we have to
// update the composited frame of the animation.

Просмотреть файл

@ -71,7 +71,6 @@
#endif
class imgIDecoder;
class imgIContainerObserver;
class nsIInputStream;
#define NS_RASTERIMAGE_CID \
@ -82,12 +81,6 @@ class nsIInputStream;
{0xb1, 0x43, 0x33, 0x40, 0xc0, 0x01, 0x12, 0xf7} \
}
/**
* It would be nice if we had a macro for this in prtypes.h.
* TODO: Place this macro in prtypes.h as PR_UINT64_MAX.
*/
#define UINT64_MAX_VAL PRUint64(-1)
/**
* Handles static and animated image containers.
*
@ -95,27 +88,15 @@ class nsIInputStream;
* @par A Quick Walk Through
* The decoder initializes this class and calls AppendFrame() to add a frame.
* Once RasterImage detects more than one frame, it starts the animation
* with StartAnimation(). Note that the invalidation events for RasterImage are
* generated automatically using nsRefreshDriver.
* with StartAnimation().
*
* @par
* StartAnimation() initializes the animation helper object and sets the time
* the first frame was displayed to the current clock time.
* StartAnimation() creates a timer. The timer calls Notify when the
* specified frame delay time is up.
*
* @par
* When the refresh driver corresponding to the imgIContainer that this image is
* a part of notifies the RasterImage that it's time to invalidate,
* RequestRefresh() is called with a given TimeStamp to advance to. As long as
* the timeout of the given frame (the frame's "delay") plus the time that frame
* was first displayed is less than or equal to the TimeStamp given,
* RequestRefresh() calls AdvanceFrame().
*
* @par
* AdvanceFrame() is responsible for advancing a single frame of the animation.
* It can return true, meaning that the frame advanced, or false, meaning that
* the frame failed to advance (usually because the next frame hasn't been
* decoded yet). It is also responsible for performing the final animation stop
* procedure if the final frame of a non-looping animation is reached.
* Notify() moves on to the next frame, sets up the new timer delay, destroys
* the old frame, and forces a redraw via observer->FrameChanged().
*
* @par
* Each frame can have a different method of removing itself. These are
@ -170,6 +151,7 @@ class imgDecodeWorker;
class Decoder;
class RasterImage : public Image
, public nsITimerCallback
, public nsIProperties
, public nsSupportsWeakReference
#ifdef DEBUG
@ -178,6 +160,7 @@ class RasterImage : public Image
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSITIMERCALLBACK
NS_DECL_NSIPROPERTIES
#ifdef DEBUG
NS_DECL_IMGICONTAINERDEBUG
@ -200,7 +183,6 @@ public:
NS_SCRIPTABLE NS_IMETHOD LockImage(void);
NS_SCRIPTABLE NS_IMETHOD UnlockImage(void);
NS_SCRIPTABLE NS_IMETHOD ResetAnimation(void);
NS_IMETHOD_(void) RequestRefresh(const mozilla::TimeStamp& aTime);
// END NS_DECL_IMGICONTAINER
RasterImage(imgStatusTracker* aStatusTracker = nsnull);
@ -352,10 +334,6 @@ private:
//! Area of the first frame that needs to be redrawn on subsequent loops.
nsIntRect firstFrameRefreshArea;
PRUint32 currentAnimationFrameIndex; // 0 to numFrames-1
// the time that the animation advanced to the current frame
TimeStamp currentAnimationFrameTime;
//! Track the last composited frame for Optimizations (See DoComposite code)
PRInt32 lastCompositedFrameIndex;
/** For managing blending of frames
@ -374,33 +352,23 @@ private:
* when it's done with the current frame.
*/
nsAutoPtr<imgFrame> compositingPrevFrame;
//! Timer to animate multiframed images
nsCOMPtr<nsITimer> timer;
Anim() :
firstFrameRefreshArea(),
currentAnimationFrameIndex(0),
lastCompositedFrameIndex(-1) {}
~Anim() {}
lastCompositedFrameIndex(-1)
{
;
}
~Anim()
{
if (timer)
timer->Cancel();
}
};
/**
* Advances the animation. Typically, this will advance a single frame, but it
* may advance multiple frames. This may happen if we have infrequently
* "ticking" refresh drivers (e.g. in background tabs), or extremely short-
* lived animation frames.
*
* @param aTime the time that the animation should advance to. This will
* typically be <= TimeStamp::Now().
*
* @param [out] aDirtyRect a pointer to an nsIntRect which encapsulates the
* area to be repainted after the frame is advanced.
*
* @returns true, if the frame was successfully advanced, false if it was not
* able to be advanced (e.g. the frame to which we want to advance is
* still decoding). Note: If false is returned, then aDirtyRect will
* remain unmodified.
*/
bool AdvanceFrame(mozilla::TimeStamp aTime, nsIntRect* aDirtyRect);
/**
* Deletes and nulls out the frame in mFrames[framenum].
*
@ -417,7 +385,6 @@ private:
imgFrame* GetCurrentImgFrame();
imgFrame* GetCurrentDrawableImgFrame();
PRUint32 GetCurrentImgFrameIndex() const;
mozilla::TimeStamp GetCurrentImgFrameEndTime() const;
inline void EnsureAnimExists()
{
@ -438,7 +405,7 @@ private:
LockImage();
}
}
/** Function for doing the frame compositing of animations
*
* @param aDirtyRect Area that the display will need to update
@ -450,7 +417,7 @@ private:
imgFrame* aPrevFrame,
imgFrame* aNextFrame,
PRInt32 aNextFrameIndex);
/** Clears an area of <aFrame> with transparent black.
*
* @param aFrame Target Frame
@ -458,7 +425,7 @@ private:
* @note Does also clears the transparancy mask
*/
static void ClearFrame(imgFrame* aFrame);
//! @overload
static void ClearFrame(imgFrame* aFrame, nsIntRect &aRect);

Просмотреть файл

@ -172,6 +172,7 @@ SVGDrawingCallback::operator()(gfxContext* aContext,
gfxContextMatrixAutoSaveRestore contextMatrixRestorer(aContext);
aContext->Multiply(gfxMatrix(aTransform).Invert());
nsPresContext* presContext = presShell->GetPresContext();
NS_ABORT_IF_FALSE(presContext, "pres shell w/out pres context");
@ -329,14 +330,6 @@ VectorImage::GetWidth(PRInt32* aWidth)
return NS_OK;
}
//******************************************************************************
/* [notxpcom] void requestRefresh ([const] in TimeStamp aTime); */
NS_IMETHODIMP_(void)
VectorImage::RequestRefresh(const mozilla::TimeStamp& aTime)
{
// TODO: Implement for b666446.
}
//******************************************************************************
/* readonly attribute PRInt32 height; */
NS_IMETHODIMP

Просмотреть файл

@ -42,7 +42,6 @@
#include "Image.h"
#include "nsIStreamListener.h"
#include "nsWeakReference.h"
#include "mozilla/TimeStamp.h"
class imgIDecoderObserver;
@ -77,7 +76,6 @@ public:
NS_SCRIPTABLE NS_IMETHOD LockImage(void);
NS_SCRIPTABLE NS_IMETHOD UnlockImage(void);
NS_SCRIPTABLE NS_IMETHOD ResetAnimation(void);
NS_IMETHOD_(void) RequestRefresh(const mozilla::TimeStamp& aTime);
// END NS_DECL_IMGICONTAINER
VectorImage(imgStatusTracker* aStatusTracker = nsnull);

Просмотреть файл

@ -93,27 +93,8 @@ _TEST_FILES = imgutils.js \
# test_bug478398.html disabled - See bug 579139
_CHROME_FILES = imgutils.js \
animationPolling.js \
lime-anim-100x100.svg \
animation.svg \
test_animSVGImage.html \
test_animation.html \
animated-gif-finalframe.gif \
animated-gif.gif \
animated-gif2.gif \
purple.gif \
test_svg_animatedGIF.html \
test_bullet_animation.html \
test_background_image_anim.html \
filter.svg \
filter-final.svg \
test_svg_filter_animation.html \
test_xultree_animation.xhtml \
test_changeOfSource.html \
test_changeOfSource2.html \
test_undisplayed_iframe.html \
iframe.html \
ref-iframe.html \
$(NULL)
libs:: $(_TEST_FILES)

Двоичные данные
image/test/mochitest/animated-gif-finalframe.gif

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 72 B

Двоичные данные
image/test/mochitest/animated-gif.gif

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 146 B

Двоичные данные
image/test/mochitest/animated-gif2.gif

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 165 B

Просмотреть файл

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<image id="anim" xlink:href="animated-gif.gif" width="40" height="40"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 170 B

Просмотреть файл

@ -1,395 +0,0 @@
var currentTest;
var gIsImageLoaded = false;
var gIsRefImageLoaded = false;
function pollForSuccess ()
{
if (!currentTest.isTestFinished) {
if (!currentTest.reusingReferenceImage || (currentTest.reusingReferenceImage
&& gRefImageLoaded)) {
currentTest.checkImage();
}
setTimeout(pollForSuccess, currentTest.pollFreq);
}
};
function imageLoadCallback()
{
gIsImageLoaded = true;
}
function referencePoller()
{
currentTest.takeReferenceSnapshot();
}
function reuseImageCallback()
{
gIsRefImageLoaded = true;
}
function failTest ()
{
if (currentTest.isTestFinished || currentTest.closeFunc) {
return;
}
ok(false, "timing out after " + currentTest.timeout + "ms. "
+ "Animated image still doesn't look correct, " + "after call #"
+ currentTest.onStopFrameCounter + " to onStopFrame");
currentTest.wereFailures = true;
currentTest.enableDisplay(document.getElementById(currentTest.debugElementId));
currentTest.cleanUpAndFinish();
};
/**
* Create a new AnimationTest object.
*
* @param pollFreq The amount of time (in ms) to wait between consecutive
* snapshots if the reference image and the test image don't match.
* @param timeout The total amount of time (in ms) to wait before declaring the
* test as failed.
* @param referenceElementId The id attribute of the reference image element, or
* the source of the image to change to, once the reference snapshot has
* been successfully taken. This latter option could be used if you don't
* want the image to become invisible at any time during the test.
* @param imageElementId The id attribute of the test image element.
* @param debugElementId The id attribute of the div where links should be
* appended if the test fails.
* @param cleanId The id attribute of the div or element to use as the 'clean'
* test. This element is only enabled when we are testing to verify that
* the reference image has been loaded. It can be undefined.
* @param srcAttr The location of the source of the image, for preloading. This
* is usually not required, but it useful for preloading reference
* images.
* @param xulTest A boolean value indicating whether or not this is a XUL test
* (uses hidden=true/false rather than display: none to hide/show
* elements).
* @param closeFunc A function that should be called when this test is finished.
* If null, then cleanUpAndFinish() will be called. This can be used to
* chain tests together, so they are all finished exactly once.
* @returns {AnimationTest}
*/
function AnimationTest(pollFreq, timeout, referenceElementId, imageElementId,
debugElementId, cleanId, srcAttr, xulTest, closeFunc)
{
// We want to test the cold loading behavior, so clear cache in case an
// earlier test got our image in there already.
clearImageCache();
this.wereFailures = false;
this.pollFreq = pollFreq;
this.timeout = timeout;
this.imageElementId = imageElementId;
this.referenceElementId = referenceElementId;
if (!document.getElementById(referenceElementId)) {
// In this case, we're assuming the user passed in a string that
// indicates the source of the image they want to change to,
// after the reference image has been taken.
this.reusingImageAsReference = true;
}
this.srcAttr = srcAttr;
this.debugElementId = debugElementId;
this.referenceSnapshot = ""; // value will be set in takeReferenceSnapshot()
this.onStopFrameCounter = 0;
this.isTestFinished = false;
this.numRefsTaken = 0;
this.blankWaitTime = 0;
this.cleanId = cleanId ? cleanId : '';
this.xulTest = xulTest ? xulTest : '';
this.closeFunc = closeFunc ? closeFunc : '';
if (this.srcAttr) {
this.myImage = new Image();
this.myImage.onload = imageLoadCallback;
this.myImage.src = this.srcAttr;
} else {
gIsImageLoaded = true;
}
}
AnimationTest.prototype.outputDebugInfo = function(message, id, dataUri)
{
var debugElement = document.getElementById(this.debugElementId);
var newDataUriElement = document.createElement("a");
newDataUriElement.setAttribute("id", id);
newDataUriElement.setAttribute("href", dataUri);
newDataUriElement.appendChild(document.createTextNode(message));
debugElement.appendChild(newDataUriElement);
var brElement = document.createElement("br");
debugElement.appendChild(brElement);
};
AnimationTest.prototype.isFinished = function()
{
return this.isTestFinished;
};
AnimationTest.prototype.takeCleanSnapshot = function()
{
var cleanElement;
if (this.cleanId) {
cleanElement = document.getElementById(this.cleanId);
}
// Enable clean page comparison element
if (cleanElement) {
this.enableDisplay(cleanElement);
}
// Take a snapshot of the initial (clean) page
this.cleanSnapshot = snapshotWindow(window, false);
// Disable the clean page comparison element
if (cleanElement) {
this.disableDisplay(cleanElement);
}
var dataString1 = "Clean Snapshot";
this.outputDebugInfo(dataString1, 'cleanSnap',
this.cleanSnapshot.toDataURL());
};
AnimationTest.prototype.takeBlankSnapshot = function()
{
// Take a snapshot of the initial (essentially blank) page
this.blankSnapshot = snapshotWindow(window, false);
var dataString1 = "Initial Blank Snapshot";
this.outputDebugInfo(dataString1, 'blank1Snap',
this.blankSnapshot.toDataURL());
};
/**
* Begin the AnimationTest. This will utilize the information provided in the
* constructor to invoke a mochitest on animated images. It will automatically
* fail if allowed to run past the timeout.
*/
AnimationTest.prototype.beginTest = function ()
{
SimpleTest.waitForExplicitFinish();
currentTest = this;
this.takeReferenceSnapshot();
// In case something goes wrong, fail earlier than mochitest timeout,
// and with more information.
setTimeout(failTest, this.timeout);
if (!this.reusingImageAsReference) {
this.disableDisplay(document.getElementById(this.imageElementId));
}
this.setupPolledImage();
setTimeout(pollForSuccess, 10);
};
AnimationTest.prototype.setupPolledImage = function ()
{
// Make sure the image is visible
if (!this.reusingImageAsReference) {
this.enableDisplay(document.getElementById(this.imageElementId));
var currentSnapshot = snapshotWindow(window, false);
var result = compareSnapshots(currentSnapshot, this.referenceSnapshot, true);
var dataString = "Snapshot #" + this.onStopFrameCounter;
this.outputDebugInfo(dataString, 'snap' + this.onStopFrameCounter,
currentSnapshot.toDataURL());
if (result[0]) {
// SUCCESS!
ok(true, "Animated image looks correct, " + "at call #"
+ this.onStopFrameCounter + " to onStopFrame");
this.cleanUpAndFinish();
}
} else {
if (!gIsRefImageLoaded) {
this.myImage = new Image();
this.myImage.onload = reuseImageCallback;
document.getElementById(this.imageElementId).setAttribute('src',
this.referenceElementId);
}
}
}
AnimationTest.prototype.checkImage = function ()
{
if (this.isTestFinished) {
return;
}
this.onStopFrameCounter++;
// We need this for some tests, because we need to force the
// test image to be visible.
if (!this.reusingImageAsReference) {
this.enableDisplay(document.getElementById(this.imageElementId));
}
var currentSnapshot = snapshotWindow(window, false);
var result = compareSnapshots(currentSnapshot, this.referenceSnapshot, true);
var dataString = "Snapshot #" + this.onStopFrameCounter;
this.outputDebugInfo(dataString, 'snap' + this.onStopFrameCounter,
currentSnapshot.toDataURL());
if (result[0]) {
// SUCCESS!
ok(true, "Animated image looks correct, " + "at call #"
+ this.onStopFrameCounter + " to onStopFrame");
this.cleanUpAndFinish();
}
};
AnimationTest.prototype.takeReferenceSnapshot = function ()
{
this.numRefsTaken++;
// Test to make sure the reference image doesn't match a clean snapshot
if (!this.cleanSnapshot) {
this.takeCleanSnapshot();
}
// Used later to verify that the reference div disappeared
if (!this.blankSnapshot) {
this.takeBlankSnapshot();
}
if (this.reusingImageAsReference) {
// Show reference div, & take a snapshot
var referenceDiv = document.getElementById(this.imageElementId);
this.enableDisplay(referenceDiv);
this.referenceSnapshot = snapshotWindow(window, false);
var snapResult = compareSnapshots(this.cleanSnapshot, this.referenceSnapshot,
false);
if (!snapResult[0]) {
if (this.blankWaitTime > 2000) {
// if it took longer than two seconds to load the image, we probably
// have a problem.
this.wereFailures = true;
ok(snapResult[0],
"Reference snapshot shouldn't match clean (non-image) snapshot");
} else {
this.blankWaitTime += 20;
// let's wait a bit and see if it clears up
setTimeout(referencePoller, 20);
return;
}
}
ok(snapResult[0],
"Reference snapshot shouldn't match clean (non-image) snapshot");
var dataString = "Reference Snapshot #" + this.numRefsTaken;
this.outputDebugInfo(dataString, 'refSnapId',
this.referenceSnapshot.toDataURL());
} else {
// Make sure the animation section is hidden
this.disableDisplay(document.getElementById(this.imageElementId));
// Show reference div, & take a snapshot
var referenceDiv = document.getElementById(this.referenceElementId);
this.enableDisplay(referenceDiv);
this.referenceSnapshot = snapshotWindow(window, false);
var snapResult = compareSnapshots(this.cleanSnapshot, this.referenceSnapshot, false);
if (!snapResult[0]) {
if (this.blankWaitTime > 2000) {
// if it took longer than two seconds to load the image, we probably
// have a problem.
this.wereFailures = true;
ok(snapResult[0],
"Reference snapshot shouldn't match clean (non-image) snapshot");
} else {
this.blankWaitTime += 20;
// let's wait a bit and see if it clears up
setTimeout(referencePoller, 20);
return;
}
}
ok(snapResult[0],
"Reference snapshot shouldn't match clean (non-image) snapshot");
var dataString = "Reference Snapshot #" + this.numRefsTaken;
this.outputDebugInfo(dataString, 'refSnapId',
this.referenceSnapshot.toDataURL());
// Re-hide reference div, and take another snapshot to be sure it's gone
this.disableDisplay(referenceDiv);
this.testBlankCameBack();
}
};
AnimationTest.prototype.enableDisplay = function(element)
{
if (!element) {
return;
}
if (!this.xulTest) {
element.style.display = '';
} else {
element.setAttribute('hidden', 'false');
}
};
AnimationTest.prototype.disableDisplay = function(element)
{
if (!element) {
return;
}
if (!this.xulTest) {
element.style.display = 'none';
} else {
element.setAttribute('hidden', 'true');
}
};
AnimationTest.prototype.testBlankCameBack = function()
{
var blankSnapshot2 = snapshotWindow(window, false);
var result = compareSnapshots(this.blankSnapshot, blankSnapshot2, true);
ok(result[0], "Reference image should disappear when it becomes display:none");
if (!result[0]) {
this.wereFailures = true;
var dataString = "Second Blank Snapshot";
this.outputDebugInfo(dataString, 'blank2SnapId', result[2]);
}
};
AnimationTest.prototype.cleanUpAndFinish = function ()
{
// On the off chance that failTest and checkImage are triggered
// back-to-back, use a flag to prevent multiple calls to SimpleTest.finish.
if (this.isTestFinished) {
return;
}
this.isTestFinished = true;
// Call our closing function, if one exists
if (this.closeFunc) {
this.closeFunc();
return;
}
if (this.wereFailures) {
document.getElementById(this.debugElementId).style.display = 'block';
}
SimpleTest.finish();
document.getElementById(this.debugElementId).style.display = "";
};

Просмотреть файл

@ -1,9 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<filter id="filter1" x="0%" y="0%" width="100%" height="100%">
<feImage xlink:href="animated-gif-finalframe.gif"/>
</filter>
<g>
<rect x="0" y="0" width="100%" height="100%" filter="url(#filter1)"/>
</g>
</svg>

До

Ширина:  |  Высота:  |  Размер: 299 B

Просмотреть файл

@ -1,9 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<filter id="filter1" x="0%" y="0%" width="100%" height="100%">
<feImage xlink:href="animated-gif.gif"/>
</filter>
<g>
<rect x="0" y="0" width="100%" height="100%" filter="url(#filter1)"/>
</g>
</svg>

До

Ширина:  |  Высота:  |  Размер: 288 B

Просмотреть файл

@ -1,5 +0,0 @@
<html>
<body bgcolor="gray">
<img src="animated-gif.gif">
</body>
</html>

Двоичные данные
image/test/mochitest/purple.gif

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 86 B

Просмотреть файл

@ -1,6 +0,0 @@
<html>
<body bgcolor="gray">
<div id="referenceImage"
style="height: 40px; width: 40px; background: #2aff00"></div>
</body>
</html>

Просмотреть файл

@ -1,46 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=666446
-->
<head>
<title>Test for Bug 666446 - General Animated GIF Test</title>
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
<script type="application/javascript" src="imgutils.js"></script>
<script type="application/javascript" src="animationPolling.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446">
Mozilla Bug 666446: lots of animated gifs swamp us with paint events
</a>
<p id="display"></p>
<div id="content">
<div id="referenceDiv" style="height: 40px; width: 40px;
display: none; background: #2aff00"></div>
<div id="animatedImage">
<img id="animatedGif" src="animated-gif.gif" style="display: none;">
<div id="text-descr"></div>
</div>
<div id="debug" style="display:none">
</div>
</div>
<pre id="test">
<script type="text/javascript;version=1.8">
const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
function main()
{
var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv',
'animatedGif', 'debug');
animTest.beginTest();
}
window.onload = main;
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -1,44 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=666446
-->
<head>
<title>Test for Bug 666446 - Animated Background Images</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
<script type="application/javascript" src="imgutils.js"></script>
<script type="application/javascript" src="animationPolling.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446">
Mozilla Bug 666446: lots of animated gifs swamp us with paint events
</a>
<p id="display"></p>
<div id="content">
<div id="referenceDiv" style="height: 140px; width: 140px;
display: none; background: #2aff00"></div>
<div id="bgImage" style="height: 140px; width: 140px; background-image: url(animated-gif.gif); display: none;">
</div>
</div>
<div id="debug" style="display:none"></div>
<pre id="test">
<script type="text/javascript;version=1.8">
/** Test for Bug 666446 nsImageLoader/RasterImage**/
const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
function main() {
var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv',
'bgImage', 'debug');
animTest.beginTest();
}
window.onload = main;
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -1,57 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=666446
-->
<head>
<title>Test for Bug 666446 - Animated Bullets</title>
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
<script type="application/javascript" src="imgutils.js"></script>
<script type="application/javascript" src="animationPolling.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446">
Mozilla Bug 666446: lots of animated gifs swamp us with paint events
</a>
<p id="display"></p>
<div id="content">
<div id="cleanDiv" style="display: none;">
<ul>
<li>Test 1</li>
</ul>
</div>
<div id="referenceDiv" style="display: none;">
<ul>
<li style="list-style-image: url(animated-gif-finalframe.gif);">Test 1</li>
</ul>
</div>
<div id="animatedImage" style="display: none;">
<ul>
<li style="list-style-image: url(animated-gif.gif);">Test 1</li>
</ul>
</div>
<div id="text-descr"></div>
<div id="debug" style="display:none">
</div>
</div>
<pre id="test">
<script type="text/javascript;version=1.8">
const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
function main()
{
var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv',
'animatedImage', 'debug', 'cleanDiv',
'animated-gif-finalframe.gif');
animTest.beginTest();
}
window.onload = main;
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -1,63 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=666446
-->
<head>
<title>Test for Bug 666446 - Change of Source (1st Version)</title>
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
<script type="application/javascript" src="imgutils.js"></script>
<script type="application/javascript" src="animationPolling.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446">
Mozilla Bug 666446: lots of animated gifs swamp us with paint events
</a>
<p id="display"></p>
<div id="content">
<div id="referenceDiv" style="height: 40px; width: 40px;
display: none; background: #2aff00;">
</div>
<div id="animatedImage">
<img id='animatedGif' src="animated-gif.gif" style="display: none;">
</div>
<div id="text-descr"></div>
<div id="debug" style="display:none">
</div>
</div>
<pre id="test">
<script type="text/javascript;version=1.8">
const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
var gAnimTest;
var gIntervalId;
function initSecondTest() {
document.getElementById('debug').style.display = 'none';
document.getElementById('referenceDiv').style.background = "#9600ff";
document.getElementById('animatedGif').setAttribute('src',
'animated-gif2.gif');
document.getElementById('animatedGif').style.display = 'none';
var secondTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv',
'animatedGif', 'debug', '', '', false);
secondTest.beginTest();
}
function main()
{
gAnimTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv',
'animatedGif', 'debug', '', '', false,
initSecondTest);
gAnimTest.beginTest();
}
window.onload = main;
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -1,48 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=666446
-->
<head>
<title>Test for Bug 691792 - Change of Source (2nd Version)</title>
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
<script type="application/javascript" src="imgutils.js"></script>
<script type="application/javascript" src="animationPolling.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=691792">
Mozilla Bug 691792: Change of src attribute for animated gifs no longer works as expected
</a>
<p id="display"></p>
<div id="content">
<div id="animatedImage">
<img id='animatedGif' src="purple.gif" style="display: none;">
</div>
<div id="text-descr"></div>
<div id="debug" style="display:none">
</div>
</div>
<pre id="test">
<script type="text/javascript;version=1.8">
const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
var gAnimTest;
var gIntervalId;
function main()
{
gAnimTest = new AnimationTest(20, FAILURE_TIMEOUT, 'animated-gif2.gif',
'animatedGif', 'debug', '', 'animated-gif2.gif',
false);
gAnimTest.beginTest();
}
window.onload = main;
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -1,52 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=666446
-->
<head>
<title>Test for Bug 666446 - Animated Raster Images inside of SVG Frames</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
<script type="application/javascript" src="imgutils.js"></script>
<script type="application/javascript" src="animationPolling.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
</head>
<!-- Make sure embed element is snapped to an exact pixel. -->
<div class="bug-header" style="height: 100px;">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446">
Mozilla Bug 666446: lots of animated gifs swamp us with paint events
</a>
</div>
<p id="display"></p>
<div id="content">
<div id="referenceDiv" style="height: 40px; width: 40px;
display: none; background: #2aff00"></div>
<!--
We use <embed> here instead of <img> because the <img> tag utilizes
the VectorImage class for SVG, whereas in this test, we are testing
RasterImage.
-->
<embed id="embeddedSVG" src="animation.svg" type="image/svg+xml" style="display: none;"/>
</div>
<div id="debug" style="display:none"></div>
<pre id="test">
<script type="text/javascript;version=1.8">
/** Test for Bug 666446 nsSVGImageFrame/RasterImage**/
const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
function main() {
var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv',
'embeddedSVG', 'debug', '', 'src');
animTest.beginTest();
}
window.onload = main;
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -1,42 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=666446
-->
<head>
<title>Test for Bug 666446 - Animated Images within SVG Filters</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
<script type="application/javascript" src="imgutils.js"></script>
<script type="application/javascript" src="animationPolling.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446">
Mozilla Bug 666446: lots of animated gifs swamp us with paint events
</a>
<p id="display"></p>
<div id="content">
<embed id="referenceImage" src="filter-final.svg" type="image/svg+xml" style="display: none;"/>
<embed id="embeddedSVGFilt" src="filter.svg" type="image/svg+xml" style="display: none;"/>
</div>
<div id="debug" style="display:none"></div>
<pre id="test">
<script type="text/javascript;version=1.8">
/** Test for Bug 666446 nsSVGFEImageElement/RasterImage**/
const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
function main() {
var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceImage',
'embeddedSVGFilt', 'debug', '', 'src');
animTest.beginTest();
}
window.onload = main;
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -1,48 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=666446
-->
<head>
<title>Test for Bug 666446 - Test for Animated Gif within IFRAME</title>
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
<script type="application/javascript" src="imgutils.js"></script>
<script type="application/javascript" src="animationPolling.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446">
Mozilla Bug 666446: lots of animated gifs swamp us with paint events</a>
<p id="display"></p>
<div id="content">
<div id="referenceDiv" style="display:none;">
<iframe id="referenceIFrame" src="ref-iframe.html" width="50%" height="100">
Browser does not support iframes.
</iframe>
</div>
<div id="animatedImage">
<iframe id="imageIFrame" src="iframe.html" width="50%" height="100" style="display: none;">
Browser does not support iframes.
</iframe>
</div>
<div id="debug" style="display: none"></div>
</div>
<pre id="test">
<script type="text/javascript;version=1.8">
const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
function main()
{
var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv',
'imageIFrame', 'debug');
animTest.beginTest();
}
window.onload = main;
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -1,67 +0,0 @@
<!DOCTYPE HTML>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xml:lang="en" lang="en">
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=666446
-->
<head>
<title>Test for Bug 666446 - Animated Images within SVG Filters</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
<script type="application/javascript" src="imgutils.js"></script>
<script type="application/javascript" src="animationPolling.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446">
Mozilla Bug 666446: lots of animated gifs swamp us with paint events
</a>
<p id="display"></p>
<div id="content">
<xul:caption label="Bug 666446 - XULTree Test" />
<xul:separator />
<br />
<xul:window id="main" title="Bug 666446: XUL Tree Testing" width="100" height="100">
<xul:tree flex="1">
<xul:treecols>
<xul:treecol id="icon" label="Icon" flex="1" />
</xul:treecols>
<xul:treechildren>
<xul:treeitem id="referenceItem" hidden="true">
<xul:treerow>
<xul:treecell src="animated-gif-finalframe.gif" width="40" height="40" />
</xul:treerow>
</xul:treeitem>
<xul:treeitem id="imageItem" hidden="true">
<xul:treerow>
<xul:treecell src="animated-gif.gif" width="40" height="40" />
</xul:treerow>
</xul:treeitem>
</xul:treechildren>
</xul:tree>
</xul:window>
</div>
<div id="debug" style="display:none"></div>
<pre id="test">
<script type="text/javascript;version=1.8">
/** Test for Bug 666446 nsSVGFEImageElement/RasterImage**/
const FAILURE_TIMEOUT = 5000; // Fail early after 120 seconds (2 minutes)
function main() {
var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceItem',
'imageItem', 'debug', '',
'animated-gif-finalframe.gif', true);
animTest.beginTest();
}
window.onload = main;
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -57,7 +57,6 @@
#include "nsStyleContext.h"
#include "nsGkAtoms.h"
#include "nsLayoutUtils.h"
// Paint forcing
#include "prenv.h"
@ -68,14 +67,17 @@ nsImageLoader::nsImageLoader(nsIFrame *aFrame, PRUint32 aActions,
nsImageLoader *aNextLoader)
: mFrame(aFrame),
mActions(aActions),
mNextLoader(aNextLoader),
mRequestRegistered(false)
mNextLoader(aNextLoader)
{
}
nsImageLoader::~nsImageLoader()
{
Destroy();
mFrame = nsnull;
if (mRequest) {
mRequest->CancelAndForgetObserver(NS_ERROR_FAILURE);
}
}
/* static */ already_AddRefed<nsImageLoader>
@ -103,15 +105,12 @@ nsImageLoader::Destroy()
todestroy->Destroy();
}
if (mRequest && mFrame) {
nsPresContext* presContext = mFrame->PresContext();
mFrame = nsnull;
nsLayoutUtils::DeregisterImageRequest(presContext, mRequest,
&mRequestRegistered);
if (mRequest) {
mRequest->CancelAndForgetObserver(NS_ERROR_FAILURE);
}
mFrame = nsnull;
mRequest = nsnull;
}
@ -128,31 +127,17 @@ nsImageLoader::Load(imgIRequest *aImage)
if (!aImage)
return NS_ERROR_FAILURE;
// Deregister mRequest from the refresh driver, since it is no longer
// going to be managed by this nsImageLoader.
nsPresContext* presContext = mFrame->PresContext();
nsLayoutUtils::DeregisterImageRequest(presContext, mRequest,
&mRequestRegistered);
// Make sure to clone into a temporary, then set mRequest, since
// cloning may notify and we don't want to trigger paints from this
// code.
nsCOMPtr<imgIRequest> newRequest;
nsresult rv = aImage->Clone(this, getter_AddRefs(newRequest));
mRequest.swap(newRequest);
// Re-register mRequest with the refresh driver, but immediately deregister
// if it isn't animated.
nsLayoutUtils::RegisterImageRequest(presContext, mRequest,
&mRequestRegistered);
nsLayoutUtils::DeregisterImageRequestIfNotAnimated(presContext, mRequest,
&mRequestRegistered);
return rv;
}
NS_IMETHODIMP nsImageLoader::OnStartContainer(imgIRequest *aRequest,
imgIContainer *aImage)
{
@ -284,35 +269,3 @@ nsImageLoader::DoRedraw(const nsRect* aDamageRect)
mFrame->Invalidate(bounds);
}
}
NS_IMETHODIMP
nsImageLoader::OnStartDecode(imgIRequest *aRequest)
{
// Register our image request with the refresh driver.
nsPresContext* presContext = mFrame->PresContext();
if (!presContext) {
return NS_OK;
}
if (mRequest == aRequest) {
nsLayoutUtils::RegisterImageRequest(presContext, mRequest,
&mRequestRegistered);
}
return NS_OK;
}
NS_IMETHODIMP
nsImageLoader::OnStopDecode(imgIRequest *aRequest, nsresult status,
const PRUnichar *statusArg)
{
if (mRequest == aRequest) {
// Deregister the imgIRequest with the refresh driver if the
// image is not animated.
nsLayoutUtils::DeregisterImageRequestIfNotAnimated(mFrame->PresContext(),
mRequest,
&mRequestRegistered);
}
return NS_OK;
}

Просмотреть файл

@ -82,10 +82,6 @@ public:
// imgIDecoderObserver (override nsStubImageDecoderObserver)
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
NS_IMETHOD OnStartDecode(imgIRequest *aRequest);
NS_IMETHOD OnStopDecode(imgIRequest *aRequest,
nsresult status,
const PRUnichar *statusArg);
NS_IMETHOD OnStopFrame(imgIRequest *aRequest, PRUint32 aFrame);
NS_IMETHOD OnStopRequest(imgIRequest *aRequest, bool aLastPart);
// Do not override OnDataAvailable since background images are not
@ -113,8 +109,4 @@ private:
nsCOMPtr<imgIRequest> mRequest;
PRUint32 mActions;
nsRefPtr<nsImageLoader> mNextLoader;
// This is a boolean flag indicating whether or not the current image request
// has been registered with the refresh driver.
bool mRequestRegistered;
};

Просмотреть файл

@ -4327,102 +4327,6 @@ nsLayoutUtils::Shutdown()
}
}
/* static */
void
nsLayoutUtils::RegisterImageRequest(nsPresContext* aPresContext,
imgIRequest* aRequest,
bool* aRequestRegistered)
{
if (!aPresContext) {
return;
}
if (aRequestRegistered && *aRequestRegistered) {
// Our request is already registered with the refresh driver, so
// no need to register it again.
return;
}
if (aRequest) {
nsCOMPtr<imgIContainer> image;
aRequest->GetImage(getter_AddRefs(image));
if (image) {
if (!aPresContext->RefreshDriver()->AddImageRequest(aRequest)) {
NS_WARNING("Unable to add image request");
return;
}
if (aRequestRegistered) {
*aRequestRegistered = true;
}
}
}
}
/* static */
void
nsLayoutUtils::DeregisterImageRequest(nsPresContext* aPresContext,
imgIRequest* aRequest,
bool* aRequestRegistered)
{
if (!aPresContext) {
return;
}
// Deregister our imgIRequest with the refresh driver to
// complete tear-down, but only if it has been registered
if (aRequestRegistered && !*aRequestRegistered) {
return;
}
if (aRequest) {
nsCOMPtr<imgIContainer> image;
aRequest->GetImage(getter_AddRefs(image));
if (image) {
aPresContext->RefreshDriver()->RemoveImageRequest(aRequest);
if (aRequestRegistered) {
*aRequestRegistered = false;
}
}
}
}
/* static */
void
nsLayoutUtils::DeregisterImageRequestIfNotAnimated(nsPresContext* aPresContext,
imgIRequest* aRequest,
bool* aRequestRegistered)
{
if (!aPresContext) {
return;
}
if (aRequestRegistered && !*aRequestRegistered) {
// Image request isn't registered with the refresh driver - no need
// to try and deregister it.
return;
}
// Deregister the imgIRequest with the refresh driver if the
// image is not animated
nsCOMPtr<imgIContainer> imageContainer;
if (aRequest) {
aRequest->GetImage(getter_AddRefs(imageContainer));
bool animated;
if (!imageContainer) {
return;
}
nsresult rv = imageContainer->GetAnimated(&animated);
if (NS_SUCCEEDED(rv) && !animated) {
nsLayoutUtils::DeregisterImageRequest(aPresContext, aRequest,
aRequestRegistered);
}
}
}
nsSetAttrRunnable::nsSetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName,
const nsAString& aValue)
: mContent(aContent),

Просмотреть файл

@ -1454,63 +1454,6 @@ public:
static void Shutdown();
/**
* Register an imgIRequest object with a refresh driver.
*
* @param aPresContext The nsPresContext whose refresh driver we want to
* register with.
* @param aRequest A pointer to the imgIRequest object which the client wants
* to register with the refresh driver.
* @param aRequestRegistered A pointer to a boolean value which indicates
* whether the given image request is registered. If
* *aRequestRegistered is true, then this request will not be
* registered again. If the request is registered by this function,
* then *aRequestRegistered will be set to true upon the completion of
* this function.
*
*/
static void RegisterImageRequest(nsPresContext* aPresContext,
imgIRequest* aRequest,
bool* aRequestRegistered);
/**
* Deregister an imgIRequest object from a refresh driver.
*
* @param aPresContext The nsPresContext whose refresh driver we want to
* deregister from.
* @param aRequest A pointer to the imgIRequest object with which the client
* previously registered and now wants to deregister from the refresh
* driver.
* @param aRequestRegistered A pointer to a boolean value which indicates
* whether the given image request is registered. If
* *aRequestRegistered is false, then this request will not be
* deregistered. If the request is deregistered by this function,
* then *aRequestRegistered will be set to false upon the completion of
* this function.
*/
static void DeregisterImageRequest(nsPresContext* aPresContext,
imgIRequest* aRequest,
bool* aRequestRegistered);
/**
* Deregister an imgIRequest object from a refresh driver, if the
* imgIRequest object represents a static (i.e. not animated) image.
*
* @param aPresContext The nsPresContext whose refresh driver we want to
* deregister from.
* @param aRequest A pointer to the imgIRequest object with which the client
* previously registered and now wants to deregister from the refresh
* driver.
* @param aRequestRegistered A pointer to a boolean value which indicates
* whether the given image request is registered. If
* *aRequestRegistered is false, then this request will not be
* deregistered. If the request is deregistered by this function,
* then *aRequestRegistered will be set to false upon the completion of
* this function.
*/
static void DeregisterImageRequestIfNotAnimated(nsPresContext* aPresContext,
imgIRequest* aRequest,
bool* aRequestRegistered);
#ifdef DEBUG
/**
* Assert that there are no duplicate continuations of the same frame

Просмотреть файл

@ -114,7 +114,6 @@ nsRefreshDriver::nsRefreshDriver(nsPresContext *aPresContext)
mTimerIsPrecise(false),
mLastTimerInterval(0)
{
mRequests.Init();
}
nsRefreshDriver::~nsRefreshDriver()
@ -186,29 +185,6 @@ nsRefreshDriver::RemoveRefreshObserver(nsARefreshObserver *aObserver,
return array.RemoveElement(aObserver);
}
bool
nsRefreshDriver::AddImageRequest(imgIRequest* aRequest)
{
if (!mRequests.PutEntry(aRequest)) {
return false;
}
EnsureTimerStarted(false);
return true;
}
void
nsRefreshDriver::RemoveImageRequest(imgIRequest* aRequest)
{
mRequests.RemoveEntry(aRequest);
}
void nsRefreshDriver::ClearAllImageRequests()
{
mRequests.Clear();
}
void
nsRefreshDriver::EnsureTimerStarted(bool aAdjustingTimer)
{
@ -262,7 +238,6 @@ nsRefreshDriver::ObserverCount() const
for (PRUint32 i = 0; i < ArrayLength(mObservers); ++i) {
sum += mObservers[i].Length();
}
// Even while throttled, we need to process layout and style changes. Style
// changes can trigger transitions which fire events when they complete, and
// layout changes can affect media queries on child documents, triggering
@ -274,12 +249,6 @@ nsRefreshDriver::ObserverCount() const
return sum;
}
PRUint32
nsRefreshDriver::ImageRequestCount() const
{
return mRequests.Count();
}
void
nsRefreshDriver::UpdateMostRecentRefresh()
{
@ -334,7 +303,7 @@ nsRefreshDriver::Notify(nsITimer *aTimer)
UpdateMostRecentRefresh();
nsCOMPtr<nsIPresShell> presShell = mPresContext->GetPresShell();
if (!presShell || (ObserverCount() == 0 && ImageRequestCount() == 0)) {
if (!presShell || ObserverCount() == 0) {
// Things are being destroyed, or we no longer have any observers.
// We don't want to stop the timer when observers are initially
// removed, because sometimes observers can be added and removed
@ -363,7 +332,6 @@ nsRefreshDriver::Notify(nsITimer *aTimer)
return NS_OK;
}
}
if (i == 0) {
// Don't just loop while we have things in mBeforePaintTargets,
// the whole point is that event handlers should readd the
@ -436,17 +404,6 @@ nsRefreshDriver::Notify(nsITimer *aTimer)
}
}
/*
* Perform notification to imgIRequests subscribed to listen
* for refresh events.
*/
ImageRequestParameters parms = {mMostRecentRefresh};
if (mRequests.Count()) {
mRequests.EnumerateEntries(nsRefreshDriver::ImageRequestEnumerator, &parms);
EnsureTimerStarted(false);
}
if (mThrottled ||
(mTimerIsPrecise !=
(GetRefreshTimerType() == nsITimer::TYPE_REPEATING_PRECISE_CAN_SKIP))) {
@ -467,24 +424,6 @@ nsRefreshDriver::Notify(nsITimer *aTimer)
return NS_OK;
}
PLDHashOperator
nsRefreshDriver::ImageRequestEnumerator(nsISupportsHashKey* aEntry,
void* aUserArg)
{
ImageRequestParameters* parms =
static_cast<ImageRequestParameters*> (aUserArg);
mozilla::TimeStamp mostRecentRefresh = parms->ts;
imgIRequest* req = static_cast<imgIRequest*>(aEntry->GetKey());
NS_ABORT_IF_FALSE(req, "Unable to retrieve the image request");
nsCOMPtr<imgIContainer> image;
req->GetImage(getter_AddRefs(image));
if (image) {
image->RequestRefresh(mostRecentRefresh);
}
return PL_DHASH_NEXT;
}
void
nsRefreshDriver::Freeze()
{
@ -498,7 +437,7 @@ nsRefreshDriver::Thaw()
{
NS_ASSERTION(mFrozen, "Thaw called on an unfrozen refresh driver");
mFrozen = false;
if (ObserverCount() || ImageRequestCount()) {
if (ObserverCount()) {
// FIXME: This isn't quite right, since our EnsureTimerStarted call
// updates our mMostRecentRefresh, but the DoRefresh call won't run
// and notify our observers until we get back to the event loop.

Просмотреть файл

@ -50,13 +50,10 @@
#include "nsTObserverArray.h"
#include "nsTArray.h"
#include "nsAutoPtr.h"
#include "nsTHashtable.h"
#include "nsHashKeys.h"
class nsPresContext;
class nsIPresShell;
class nsIDocument;
class imgIRequest;
/**
* An abstract base class to be implemented by callers wanting to be
@ -131,24 +128,6 @@ public:
bool RemoveRefreshObserver(nsARefreshObserver *aObserver,
mozFlushType aFlushType);
/**
* Add/Remove imgIRequest versions of observers.
*
* These are used for hooking into the refresh driver for
* controlling animated images.
*
* @note The refresh driver owns a reference to these listeners.
*
* @note Technically, imgIRequest objects are not nsARefreshObservers, but
* for controlling animated image repaint events, we subscribe the
* imgIRequests to the nsRefreshDriver for notification of paint events.
*
* @returns whether the operation succeeded, or void in the case of removal.
*/
bool AddImageRequest(imgIRequest* aRequest);
void RemoveImageRequest(imgIRequest* aRequest);
void ClearAllImageRequests();
/**
* Add / remove presshells that we should flush style and layout on
*/
@ -239,15 +218,10 @@ public:
private:
typedef nsTObserverArray<nsARefreshObserver*> ObserverArray;
typedef nsTHashtable<nsISupportsHashKey> RequestTable;
void EnsureTimerStarted(bool aAdjustingTimer);
void StopTimer();
PRUint32 ObserverCount() const;
PRUint32 ImageRequestCount() const;
static PLDHashOperator ImageRequestEnumerator(nsISupportsHashKey* aEntry,
void* aUserArg);
void UpdateMostRecentRefresh();
ObserverArray& ArrayFor(mozFlushType aFlushType);
// Trigger a refresh immediately, if haven't been disconnected or frozen.
@ -278,8 +252,6 @@ private:
// separate arrays for each flush type we support
ObserverArray mObservers[3];
RequestTable mRequests;
nsAutoTArray<nsIPresShell*, 16> mStyleFlushObservers;
nsAutoTArray<nsIPresShell*, 16> mLayoutFlushObservers;
// nsTArray on purpose, because we want to be able to swap.
@ -290,11 +262,6 @@ private:
// This is the last interval we used for our timer. May be 0 if we
// haven't computed a timer interval yet.
mutable PRInt32 mLastTimerInterval;
// Helper struct for processing image requests
struct ImageRequestParameters {
mozilla::TimeStamp ts;
};
};
#endif /* !defined(nsRefreshDriver_h_) */

Просмотреть файл

@ -78,7 +78,6 @@ public:
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, bool aCurrentFrame,
const nsIntRect *aRect);
NS_IMETHOD OnStartDecode(imgIRequest *aRequest);
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
const PRUnichar *statusArg);
// imgIContainerObserver (override nsStubImageDecoderObserver)
@ -102,10 +101,6 @@ nsBulletFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
// Stop image loading first
if (mImageRequest) {
// Deregister our image request from the refresh driver
nsLayoutUtils::DeregisterImageRequest(PresContext(),
mImageRequest,
&mRequestRegistered);
mImageRequest->CancelAndForgetObserver(NS_ERROR_FAILURE);
mImageRequest = nsnull;
}
@ -175,8 +170,6 @@ nsBulletFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
if (same) {
needNewRequest = false;
} else {
nsLayoutUtils::DeregisterImageRequest(PresContext(), mImageRequest,
&mRequestRegistered);
mImageRequest->Cancel(NS_ERROR_FAILURE);
mImageRequest = nsnull;
}
@ -185,15 +178,10 @@ nsBulletFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
if (needNewRequest) {
newRequest->Clone(mListener, getter_AddRefs(mImageRequest));
nsLayoutUtils::RegisterImageRequest(PresContext(), mImageRequest,
&mRequestRegistered);
}
} else {
// No image request on the new style context
if (mImageRequest) {
nsLayoutUtils::DeregisterImageRequest(PresContext(), mImageRequest,
&mRequestRegistered);
mImageRequest->Cancel(NS_ERROR_FAILURE);
mImageRequest = nsnull;
}
@ -1533,17 +1521,6 @@ NS_IMETHODIMP nsBulletFrame::OnDataAvailable(imgIRequest *aRequest,
return NS_OK;
}
NS_IMETHODIMP nsBulletFrame::OnStartDecode(imgIRequest* aRequest)
{
// Register the image request with the refresh driver.
if (aRequest == mImageRequest) {
nsLayoutUtils::RegisterImageRequest(PresContext(), mImageRequest,
&mRequestRegistered);
}
return NS_OK;
}
NS_IMETHODIMP nsBulletFrame::OnStopDecode(imgIRequest *aRequest,
nsresult aStatus,
const PRUnichar *aStatusArg)
@ -1560,14 +1537,6 @@ NS_IMETHODIMP nsBulletFrame::OnStopDecode(imgIRequest *aRequest,
}
#endif
// Deregister the imgIRequest with the refresh driver if the
// image is not animated.
if (aRequest == mImageRequest) {
nsLayoutUtils::DeregisterImageRequestIfNotAnimated(PresContext(),
mImageRequest,
&mRequestRegistered);
}
return NS_OK;
}
@ -1665,25 +1634,17 @@ NS_IMETHODIMP nsBulletListener::OnDataAvailable(imgIRequest *aRequest,
const nsIntRect *aRect)
{
if (!mFrame)
return NS_OK;
return NS_ERROR_FAILURE;
return mFrame->OnDataAvailable(aRequest, aCurrentFrame, aRect);
}
NS_IMETHODIMP nsBulletListener::OnStartDecode(imgIRequest *aRequest)
{
if (!mFrame)
return NS_OK;
return mFrame->OnStartDecode(aRequest);
}
NS_IMETHODIMP nsBulletListener::OnStopDecode(imgIRequest *aRequest,
nsresult status,
const PRUnichar *statusArg)
{
if (!mFrame)
return NS_OK;
return NS_ERROR_FAILURE;
return mFrame->OnStopDecode(aRequest, status, statusArg);
}
@ -1692,7 +1653,7 @@ NS_IMETHODIMP nsBulletListener::FrameChanged(imgIContainer *aContainer,
const nsIntRect *aDirtyRect)
{
if (!mFrame)
return NS_OK;
return NS_ERROR_FAILURE;
return mFrame->FrameChanged(aContainer, aDirtyRect);
}

Просмотреть файл

@ -84,7 +84,6 @@ public:
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest,
bool aCurrentFrame,
const nsIntRect *aRect);
NS_IMETHOD OnStartDecode(imgIRequest *aRequest);
NS_IMETHOD OnStopDecode(imgIRequest *aRequest,
nsresult aStatus,
const PRUnichar *aStatusArg);
@ -122,12 +121,6 @@ protected:
nsSize mComputedSize;
PRInt32 mOrdinal;
bool mTextIsRTL;
private:
// This is a boolean flag indicating whether or not the current image request
// has been registered with the refresh driver.
bool mRequestRegistered;
};
#endif /* nsBulletFrame_h___ */

Просмотреть файл

@ -579,10 +579,6 @@ protected:
/**
* Implements Destroy(). Do not call this directly except from within a
* DestroyFrom() implementation.
*
* @note This will always be called, so it is not necessary to override
* Destroy() in subclasses of nsFrame, just DestroyFrom().
*
* @param aDestructRoot is the root of the subtree being destroyed
*/
virtual void DestroyFrom(nsIFrame* aDestructRoot) = 0;

Просмотреть файл

@ -231,10 +231,6 @@ nsImageFrame::DestroyFrom(nsIFrame* aDestructRoot)
nsCxPusher pusher;
pusher.PushNull();
// Notify our image loading content that we are going away so it can
// deregister with our refresh driver.
imageLoader->FrameDestroyed(this);
imageLoader->RemoveObserver(mListener);
}
@ -280,10 +276,6 @@ nsImageFrame::Init(nsIContent* aContent,
if (!gIconLoad)
LoadIcons(aPresContext);
// We have a PresContext now, so we need to notify the image content node
// that it can register images.
imageLoader->FrameCreated(this);
// Give image loads associated with an image frame a small priority boost!
nsCOMPtr<imgIRequest> currentRequest;
imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,

Просмотреть файл

@ -103,7 +103,6 @@ public:
NS_IMETHOD Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aPrevInFlow);
virtual void DestroyFrom(nsIFrame* aDestructRoot);
/**
* Get the "type" of the frame
@ -180,10 +179,6 @@ nsSVGImageFrame::Init(nsIContent* aContent,
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
NS_ENSURE_TRUE(imageLoader, NS_ERROR_UNEXPECTED);
// We should have a PresContext now, so let's notify our image loader that
// we need to register any image animations with the refresh driver.
imageLoader->FrameCreated(this);
// Push a null JSContext on the stack so that code that runs within
// the below code doesn't think it's being called by JS. See bug
// 604262.
@ -195,19 +190,6 @@ nsSVGImageFrame::Init(nsIContent* aContent,
return NS_OK;
}
/* virtual */ void
nsSVGImageFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
nsCOMPtr<nsIImageLoadingContent> imageLoader =
do_QueryInterface(nsFrame::mContent);
if (imageLoader) {
imageLoader->FrameDestroyed(this);
}
nsFrame::DestroyFrom(aDestructRoot);
}
//----------------------------------------------------------------------
// nsIFrame methods:

Просмотреть файл

@ -36,7 +36,6 @@
#include "nsFrame.h"
#include "nsSVGEffects.h"
#include "nsImageLoadingContent.h"
class nsSVGLeafFrame : public nsFrame
{
@ -48,12 +47,6 @@ protected:
public:
NS_DECL_FRAMEARENA_HELPERS
NS_IMETHOD Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* asPrevInFlow);
virtual void DestroyFrom(nsIFrame* aDestructRoot);
virtual bool IsFrameOfType(PRUint32 aFlags) const
{
return nsFrame::IsFrameOfType(aFlags & ~(nsIFrame::eSVG));
@ -77,33 +70,6 @@ NS_NewSVGLeafFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
NS_IMPL_FRAMEARENA_HELPERS(nsSVGLeafFrame)
NS_IMETHODIMP
nsSVGLeafFrame::Init(nsIContent* aContent, nsIFrame* aParent, nsIFrame* asPrevInFlow)
{
nsFrame::Init(aContent, aParent, asPrevInFlow);
nsCOMPtr<nsIImageLoadingContent> imageLoader =
do_QueryInterface(nsFrame::mContent);
if (imageLoader) {
imageLoader->FrameCreated(this);
}
return NS_OK;
}
/* virtual */ void
nsSVGLeafFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
nsCOMPtr<nsIImageLoadingContent> imageLoader =
do_QueryInterface(nsFrame::mContent);
if (imageLoader) {
imageLoader->FrameDestroyed(this);
}
nsFrame::DestroyFrom(aDestructRoot);
}
/* virtual */ void
nsSVGLeafFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{

Просмотреть файл

@ -72,7 +72,6 @@
#include "nsIDOMDocument.h"
#include "nsTransform2D.h"
#include "nsITheme.h"
#include "nsIImageLoadingContent.h"
#include "nsIServiceManager.h"
#include "nsIURI.h"
@ -174,7 +173,6 @@ nsImageBoxFrame::AttributeChanged(PRInt32 aNameSpaceID,
nsImageBoxFrame::nsImageBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext):
nsLeafBoxFrame(aShell, aContext),
mIntrinsicSize(0,0),
mRequestRegistered(false),
mLoadFlags(nsIRequest::LOAD_NORMAL),
mUseSrcAttr(false),
mSuppressStyleCheck(false)
@ -197,16 +195,9 @@ nsImageBoxFrame::MarkIntrinsicWidthsDirty()
void
nsImageBoxFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
if (mImageRequest) {
nsPresContext* presContext = PresContext();
NS_ASSERTION(presContext, "No PresContext");
nsLayoutUtils::DeregisterImageRequest(presContext,
mImageRequest,
&mRequestRegistered);
// Release image loader first so that it's refcnt can go to zero
// Release image loader first so that it's refcnt can go to zero
if (mImageRequest)
mImageRequest->CancelAndForgetObserver(NS_ERROR_FAILURE);
}
if (mListener)
reinterpret_cast<nsImageBoxListener*>(mListener.get())->SetFrame(nsnull); // set the frame to null so we don't send messages to a dead object.
@ -241,12 +232,7 @@ nsImageBoxFrame::Init(nsIContent* aContent,
void
nsImageBoxFrame::UpdateImage()
{
nsPresContext* presContext = PresContext();
NS_ASSERTION(presContext, "No PresContext");
if (mImageRequest) {
nsLayoutUtils::DeregisterImageRequest(presContext, mImageRequest,
&mRequestRegistered);
mImageRequest->CancelAndForgetObserver(NS_ERROR_FAILURE);
mImageRequest = nsnull;
}
@ -273,12 +259,6 @@ nsImageBoxFrame::UpdateImage()
nsContentUtils::LoadImage(uri, doc, mContent->NodePrincipal(),
doc->GetDocumentURI(), mListener, mLoadFlags,
getter_AddRefs(mImageRequest));
// Register our imgIRequest with the refresh driver
nsLayoutUtils::RegisterImageRequest(presContext,
mImageRequest,
&mRequestRegistered);
}
} else {
// Only get the list-style-image if we aren't being drawn
@ -603,31 +583,10 @@ NS_IMETHODIMP nsImageBoxFrame::OnStopContainer(imgIRequest *request,
return NS_OK;
}
NS_IMETHODIMP nsImageBoxFrame::OnStartDecode(imgIRequest* aRequest)
{
nsPresContext* presContext = PresContext();
NS_ASSERTION(presContext, "No PresContext");
nsLayoutUtils::RegisterImageRequest(presContext,
mImageRequest,
&mRequestRegistered);
return NS_OK;
}
NS_IMETHODIMP nsImageBoxFrame::OnStopDecode(imgIRequest *request,
nsresult aStatus,
const PRUnichar *statusArg)
{
// If the imgIRequest does not represent an animated image, then we should
// deregister it from our refresh driver.
nsPresContext* presContext = PresContext();
NS_ASSERTION(presContext, "No PresContext");
nsLayoutUtils::DeregisterImageRequestIfNotAnimated(presContext,
mImageRequest,
&mRequestRegistered);
if (NS_SUCCEEDED(aStatus))
// Fire an onload DOM event.
FireImageDOMEvent(mContent, NS_LOAD);
@ -665,7 +624,7 @@ NS_IMETHODIMP nsImageBoxListener::OnStartContainer(imgIRequest *request,
imgIContainer *image)
{
if (!mFrame)
return NS_OK;
return NS_ERROR_FAILURE;
return mFrame->OnStartContainer(request, image);
}
@ -674,26 +633,17 @@ NS_IMETHODIMP nsImageBoxListener::OnStopContainer(imgIRequest *request,
imgIContainer *image)
{
if (!mFrame)
return NS_OK;
return NS_ERROR_FAILURE;
return mFrame->OnStopContainer(request, image);
}
NS_IMETHODIMP nsImageBoxListener::OnStartDecode(imgIRequest *aRequest)
{
if (!mFrame) {
return NS_OK;
}
return mFrame->OnStartDecode(aRequest);
}
NS_IMETHODIMP nsImageBoxListener::OnStopDecode(imgIRequest *request,
nsresult status,
const PRUnichar *statusArg)
{
if (!mFrame)
return NS_OK;
return NS_ERROR_FAILURE;
return mFrame->OnStopDecode(request, status, statusArg);
}

Просмотреть файл

@ -56,7 +56,6 @@ public:
// imgIDecoderObserver (override nsStubImageDecoderObserver)
NS_IMETHOD OnStartContainer(imgIRequest *request, imgIContainer *image);
NS_IMETHOD OnStopContainer(imgIRequest *request, imgIContainer *image);
NS_IMETHOD OnStartDecode(imgIRequest *aRequest);
NS_IMETHOD OnStopDecode(imgIRequest *request, nsresult status,
const PRUnichar *statusArg);
// imgIContainerObserver (override nsStubImageDecoderObserver)
@ -120,7 +119,6 @@ public:
NS_IMETHOD OnStartContainer(imgIRequest *request, imgIContainer *image);
NS_IMETHOD OnStopContainer(imgIRequest *request, imgIContainer *image);
NS_IMETHOD OnStartDecode(imgIRequest *aRequest);
NS_IMETHOD OnStopDecode(imgIRequest *request,
nsresult status,
const PRUnichar *statusArg);
@ -144,10 +142,6 @@ private:
nsSize mIntrinsicSize;
nsSize mImageSize;
// Boolean variable to determine if the current image request has been
// registered with the refresh driver.
bool mRequestRegistered;
nsCOMPtr<imgIRequest> mImageRequest;
nsCOMPtr<imgIDecoderObserver> mListener;

Просмотреть файл

@ -1,64 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Dave Hyatt <hyatt@mozilla.org> (Original Author)
* Jan Varga <varga@ku.sk>
* Scott Johnson <sjohnson@mozilla.com>, Mozilla Corporation
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsITreeImageListener_h__
#define nsITreeImageListener_h__
// The interface for our image listener.
// {90586540-2D50-403e-8DCE-981CAA778444}
#define NS_ITREEIMAGELISTENER_IID \
{ 0x90586540, 0x2d50, 0x403e, { 0x8d, 0xce, 0x98, 0x1c, 0xaa, 0x77, 0x84, 0x44 } }
class nsITreeImageListener : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ITREEIMAGELISTENER_IID)
NS_IMETHOD AddCell(PRInt32 aIndex, nsITreeColumn* aCol) = 0;
/**
* Clear the internal frame pointer to prevent dereferencing an object
* that no longer exists.
*/
NS_IMETHOD ClearFrame() = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsITreeImageListener, NS_ITREEIMAGELISTENER_IID)
#endif

Просмотреть файл

@ -54,7 +54,6 @@
#include "nsTreeBodyFrame.h"
#include "nsTreeSelection.h"
#include "nsTreeImageListener.h"
#include "nsGkAtoms.h"
#include "nsCSSAnonBoxes.h"
@ -115,14 +114,6 @@ static PLDHashOperator
CancelImageRequest(const nsAString& aKey,
nsTreeImageCacheEntry aEntry, void* aData)
{
// If our imgIRequest object was registered with the refresh driver,
// then we need to deregister it.
nsTreeBodyFrame* frame = static_cast<nsTreeBodyFrame*>(aData);
nsLayoutUtils::DeregisterImageRequest(frame->PresContext(), aEntry.request,
nsnull);
aEntry.request->CancelAndForgetObserver(NS_BINDING_ABORTED);
return PL_DHASH_NEXT;
}
@ -173,8 +164,7 @@ nsTreeBodyFrame::nsTreeBodyFrame(nsIPresShell* aPresShell, nsStyleContext* aCont
// Destructor
nsTreeBodyFrame::~nsTreeBodyFrame()
{
mImageCache.EnumerateRead(CancelImageRequest, this);
DetachImageListeners();
mImageCache.EnumerateRead(CancelImageRequest, nsnull);
delete mSlots;
}
@ -207,11 +197,8 @@ nsTreeBodyFrame::Init(nsIContent* aContent,
mIndentation = GetIndentation();
mRowHeight = GetRowHeight();
NS_ENSURE_TRUE(mCreatedListeners.Init(), NS_ERROR_OUT_OF_MEMORY);
NS_ENSURE_TRUE(mImageCache.Init(16), NS_ERROR_OUT_OF_MEMORY);
EnsureBoxObject();
return rv;
}
@ -2167,14 +2154,10 @@ nsTreeBodyFrame::GetImage(PRInt32 aRowIndex, nsTreeColumn* aCol, bool aUseContex
if (!*aResult) {
// Create a new nsTreeImageListener object and pass it our row and column
// information.
nsTreeImageListener* listener = new nsTreeImageListener(this);
nsTreeImageListener* listener = new nsTreeImageListener(mTreeBoxObject);
if (!listener)
return NS_ERROR_OUT_OF_MEMORY;
if (!mCreatedListeners.PutEntry(listener)) {
return NS_ERROR_FAILURE;
}
listener->AddCell(aRowIndex, aCol);
nsCOMPtr<imgIDecoderObserver> imgDecoderObserver = listener;
@ -4253,7 +4236,7 @@ nsresult
nsTreeBodyFrame::ClearStyleAndImageCaches()
{
mStyleCache.Clear();
mImageCache.EnumerateRead(CancelImageRequest, this);
mImageCache.EnumerateRead(CancelImageRequest, nsnull);
mImageCache.Clear();
return NS_OK;
}
@ -4485,20 +4468,6 @@ nsTreeBodyFrame::PostScrollEvent()
}
}
void
nsTreeBodyFrame::DetachImageListeners()
{
mCreatedListeners.Clear();
}
void
nsTreeBodyFrame::RemoveTreeImageListener(nsTreeImageListener* aListener)
{
if (aListener) {
mCreatedListeners.RemoveEntry(aListener);
}
}
#ifdef ACCESSIBILITY
void
nsTreeBodyFrame::FireRowCountChangedEvent(PRInt32 aIndex, PRInt32 aCount)
@ -4672,19 +4641,3 @@ nsTreeBodyFrame::FullScrollbarsUpdate(bool aNeedsFullInvalidation)
nsContentUtils::AddScriptRunner(new nsOverflowChecker(this));
return weakFrame.IsAlive();
}
nsresult
nsTreeBodyFrame::OnStartDecode(imgIRequest* aRequest)
{
nsLayoutUtils::RegisterImageRequest(PresContext(), aRequest, nsnull);
return NS_OK;
}
nsresult
nsTreeBodyFrame::OnStopDecode(imgIRequest* aRequest, nsresult aStatus,
const PRUnichar* aStatusArg)
{
nsLayoutUtils::DeregisterImageRequestIfNotAnimated(PresContext(), aRequest,
nsnull);
return NS_OK;
}

Просмотреть файл

@ -54,6 +54,7 @@
#include "nsTArray.h"
#include "nsTreeStyleCache.h"
#include "nsTreeColumns.h"
#include "nsTreeImageListener.h"
#include "nsAutoPtr.h"
#include "nsDataHashtable.h"
#include "imgIRequest.h"
@ -61,10 +62,8 @@
#include "nsScrollbarFrame.h"
#include "nsThreadUtils.h"
#include "mozilla/LookAndFeel.h"
#include "nsITreeImageListener.h"
class nsOverflowChecker;
class nsTreeImageListener;
// An entry in the tree's image cache
struct nsTreeImageCacheEntry
@ -92,13 +91,6 @@ public:
NS_DECL_QUERYFRAME
NS_DECL_FRAMEARENA_HELPERS
// Callback handler methods for refresh driver based animations.
// Calls to these functions are forwarded from nsTreeImageListener. These
// mirror how nsImageFrame works.
nsresult OnStartDecode(imgIRequest* aRequest);
nsresult OnStopDecode(imgIRequest* aRequest, nsresult aStatus,
const PRUnichar* aStatusArg);
// non-virtual signatures like nsITreeBodyFrame
nsresult GetColumns(nsITreeColumns **aColumns);
nsresult GetView(nsITreeView **aView);
@ -443,15 +435,6 @@ public:
return col;
}
/**
* Remove an nsITreeImageListener from being tracked by this frame. Only tree
* image listeners that are created by this frame are tracked.
*
* @param aListener A pointer to an nsTreeImageListener to no longer
* track.
*/
void RemoveTreeImageListener(nsTreeImageListener* aListener);
protected:
// Create a new timer. This method is used to delay various actions like
@ -482,12 +465,6 @@ protected:
void PostScrollEvent();
void FireScrollEvent();
/**
* Clear the pointer to this frame for all nsTreeImageListeners that were
* created by this frame.
*/
void DetachImageListeners();
#ifdef ACCESSIBILITY
/**
* Fires 'treeRowCountChanged' event asynchronously. The event supports
@ -625,11 +602,6 @@ protected: // Data Members
bool mHorizontalOverflow;
bool mReflowCallbackPosted;
// Hash table to keep track of which listeners we created and thus
// have pointers to us.
nsTHashtable<nsPtrHashKey<nsTreeImageListener> > mCreatedListeners;
}; // class nsTreeBodyFrame
#endif

Просмотреть файл

@ -44,8 +44,8 @@
NS_IMPL_ISUPPORTS3(nsTreeImageListener, imgIDecoderObserver, imgIContainerObserver, nsITreeImageListener)
nsTreeImageListener::nsTreeImageListener(nsTreeBodyFrame* aTreeFrame)
: mTreeFrame(aTreeFrame),
nsTreeImageListener::nsTreeImageListener(nsITreeBoxObject* aTree)
: mTree(aTree),
mInvalidationSuppressed(true),
mInvalidationArea(nsnull)
{
@ -56,29 +56,6 @@ nsTreeImageListener::~nsTreeImageListener()
delete mInvalidationArea;
}
NS_IMETHODIMP
nsTreeImageListener::OnStartDecode(imgIRequest *aRequest)
{
if (!mTreeFrame) {
return NS_OK;
}
// grab the frame we want to use
return mTreeFrame->OnStartDecode(aRequest);
}
NS_IMETHODIMP
nsTreeImageListener::OnStopDecode(imgIRequest *aRequest,
nsresult aStatus,
const PRUnichar *aStatusArg)
{
if (!mTreeFrame) {
return NS_OK;
}
return mTreeFrame->OnStopDecode(aRequest, aStatus, aStatusArg);
}
NS_IMETHODIMP nsTreeImageListener::OnStartContainer(imgIRequest *aRequest,
imgIContainer *aImage)
{
@ -136,16 +113,10 @@ void
nsTreeImageListener::Invalidate()
{
if (!mInvalidationSuppressed) {
for (InvalidationArea* currArea = mInvalidationArea; currArea;
currArea = currArea->GetNext()) {
for (InvalidationArea* currArea = mInvalidationArea; currArea; currArea = currArea->GetNext()) {
// Loop from min to max, invalidating each cell that was listening for this image.
for (PRInt32 i = currArea->GetMin(); i <= currArea->GetMax(); ++i) {
if (mTreeFrame) {
nsITreeBoxObject* tree = mTreeFrame->GetTreeBoxObject();
if (tree) {
tree->InvalidateCell(i, currArea->GetCol());
}
}
mTree->InvalidateCell(i, currArea->GetCol());
}
}
}
@ -169,10 +140,3 @@ nsTreeImageListener::InvalidationArea::AddRow(PRInt32 aIndex)
else if (aIndex > mMax)
mMax = aIndex;
}
NS_IMETHODIMP
nsTreeImageListener::ClearFrame()
{
mTreeFrame = nsnull;
return NS_OK;
}

Просмотреть файл

@ -44,21 +44,33 @@
#include "nsCOMPtr.h"
#include "nsITreeColumns.h"
#include "nsStubImageDecoderObserver.h"
#include "nsTreeBodyFrame.h"
#include "nsITreeImageListener.h"
class nsITreeBoxObject;
// The interface for our image listener.
// {90586540-2D50-403e-8DCE-981CAA778444}
#define NS_ITREEIMAGELISTENER_IID \
{ 0x90586540, 0x2d50, 0x403e, { 0x8d, 0xce, 0x98, 0x1c, 0xaa, 0x77, 0x84, 0x44 } }
class nsITreeImageListener : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ITREEIMAGELISTENER_IID)
NS_IMETHOD AddCell(PRInt32 aIndex, nsITreeColumn* aCol) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsITreeImageListener, NS_ITREEIMAGELISTENER_IID)
// This class handles image load observation.
class nsTreeImageListener : public nsStubImageDecoderObserver, public nsITreeImageListener
{
public:
nsTreeImageListener(nsTreeBodyFrame *aTreeFrame);
nsTreeImageListener(nsITreeBoxObject* aTree);
~nsTreeImageListener();
NS_DECL_ISUPPORTS
// imgIDecoderObserver (override nsStubImageDecoderObserver)
NS_IMETHOD OnStartDecode(imgIRequest *aRequest);
NS_IMETHOD OnStopDecode(imgIRequest *aRequest,
nsresult aStatus, const PRUnichar *aStatusArg);
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, bool aCurrentFrame,
const nsIntRect *aRect);
@ -67,8 +79,7 @@ public:
const nsIntRect *aDirtyRect);
NS_IMETHOD AddCell(PRInt32 aIndex, nsITreeColumn* aCol);
NS_IMETHOD ClearFrame();
friend class nsTreeBodyFrame;
protected:
@ -76,7 +87,7 @@ protected:
void Invalidate();
private:
nsTreeBodyFrame* mTreeFrame;
nsITreeBoxObject* mTree;
// A guard that prevents us from recursive painting.
bool mInvalidationSuppressed;