mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Merge inbound to m-c.
This commit is contained in:
commit
aff5207df8
@ -6,8 +6,17 @@ function test() {
|
|||||||
gBrowser.selectedTab = gBrowser.addTab();
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
|
||||||
// Navigate to malware site. Can't use an onload listener here since
|
// Navigate to malware site. Can't use an onload listener here since
|
||||||
// error pages don't fire onload
|
// error pages don't fire onload. Also can't register the DOMContentLoaded
|
||||||
|
// handler here because registering it too soon would mean that we might
|
||||||
|
// get it for about:blank, and not about:blocked.
|
||||||
|
gBrowser.addTabsProgressListener({
|
||||||
|
onLocationChange: function(aTab, aWebProgress, aRequest, aLocation, aFlags) {
|
||||||
|
if (aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) {
|
||||||
|
gBrowser.removeTabsProgressListener(this);
|
||||||
window.addEventListener("DOMContentLoaded", testMalware, true);
|
window.addEventListener("DOMContentLoaded", testMalware, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
content.location = "http://www.mozilla.org/firefox/its-an-attack.html";
|
content.location = "http://www.mozilla.org/firefox/its-an-attack.html";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -837,6 +837,10 @@
|
|||||||
; Adds a pinned shortcut to Task Bar on update for Windows 7 and above if this
|
; Adds a pinned shortcut to Task Bar on update for Windows 7 and above if this
|
||||||
; macro has never been called before and the application is default (see
|
; macro has never been called before and the application is default (see
|
||||||
; PinToTaskBar for more details).
|
; PinToTaskBar for more details).
|
||||||
|
; Since defaults handling is handled by Windows in Win8 and later, we always
|
||||||
|
; attempt to pin a taskbar on that OS. If Windows sets the defaults at
|
||||||
|
; installation time, then we don't get the opportunity to run this code at
|
||||||
|
; that time.
|
||||||
!macro MigrateTaskBarShortcut
|
!macro MigrateTaskBarShortcut
|
||||||
${GetShortcutsLogPath} $0
|
${GetShortcutsLogPath} $0
|
||||||
${If} ${FileExists} "$0"
|
${If} ${FileExists} "$0"
|
||||||
@ -846,13 +850,17 @@
|
|||||||
ClearErrors
|
ClearErrors
|
||||||
WriteIniStr "$0" "TASKBAR" "Migrated" "true"
|
WriteIniStr "$0" "TASKBAR" "Migrated" "true"
|
||||||
${If} ${AtLeastWin7}
|
${If} ${AtLeastWin7}
|
||||||
|
; No need to check the default on Win8 and later
|
||||||
|
${If} ${AtMostWin2008R2}
|
||||||
; Check if the Firefox is the http handler for this user
|
; Check if the Firefox is the http handler for this user
|
||||||
SetShellVarContext current ; Set SHCTX to the current user
|
SetShellVarContext current ; Set SHCTX to the current user
|
||||||
${IsHandlerForInstallDir} "http" $R9
|
${IsHandlerForInstallDir} "http" $R9
|
||||||
${If} $TmpVal == "HKLM"
|
${If} $TmpVal == "HKLM"
|
||||||
SetShellVarContext all ; Set SHCTX to all users
|
SetShellVarContext all ; Set SHCTX to all users
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
${EndIf}
|
||||||
${If} "$R9" == "true"
|
${If} "$R9" == "true"
|
||||||
|
${OrIf} ${AtLeastWin8}
|
||||||
${PinToTaskBar}
|
${PinToTaskBar}
|
||||||
${EndIf}
|
${EndIf}
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
@ -64,7 +64,7 @@ class nsIParserService;
|
|||||||
class nsIIOService;
|
class nsIIOService;
|
||||||
class nsIURI;
|
class nsIURI;
|
||||||
class imgIContainer;
|
class imgIContainer;
|
||||||
class imgIDecoderObserver;
|
class imgINotificationObserver;
|
||||||
class imgIRequest;
|
class imgIRequest;
|
||||||
class imgILoader;
|
class imgILoader;
|
||||||
class imgICache;
|
class imgICache;
|
||||||
@ -661,7 +661,7 @@ public:
|
|||||||
nsIDocument* aLoadingDocument,
|
nsIDocument* aLoadingDocument,
|
||||||
nsIPrincipal* aLoadingPrincipal,
|
nsIPrincipal* aLoadingPrincipal,
|
||||||
nsIURI* aReferrer,
|
nsIURI* aReferrer,
|
||||||
imgIDecoderObserver* aObserver,
|
imgINotificationObserver* aObserver,
|
||||||
int32_t aLoadFlags,
|
int32_t aLoadFlags,
|
||||||
imgIRequest** aRequest);
|
imgIRequest** aRequest);
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "imgIDecoderObserver.idl"
|
#include "imgINotificationObserver.idl"
|
||||||
|
|
||||||
interface imgIRequest;
|
interface imgIRequest;
|
||||||
interface nsIChannel;
|
interface nsIChannel;
|
||||||
@ -34,8 +34,8 @@ interface nsIFrame;
|
|||||||
* sufficient, when combined with the imageBlockingStatus information.)
|
* sufficient, when combined with the imageBlockingStatus information.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
[scriptable, uuid(4bf1a7c5-6edb-4191-a257-e31a90f6aa85)]
|
[scriptable, builtinclass, uuid(497bfb9b-d996-4d1e-a647-8137b0cfc876)]
|
||||||
interface nsIImageLoadingContent : imgIDecoderObserver
|
interface nsIImageLoadingContent : imgINotificationObserver
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Request types. Image loading content nodes attempt to do atomic
|
* Request types. Image loading content nodes attempt to do atomic
|
||||||
@ -75,14 +75,14 @@ interface nsIImageLoadingContent : imgIDecoderObserver
|
|||||||
*
|
*
|
||||||
* @throws NS_ERROR_OUT_OF_MEMORY
|
* @throws NS_ERROR_OUT_OF_MEMORY
|
||||||
*/
|
*/
|
||||||
void addObserver(in imgIDecoderObserver aObserver);
|
void addObserver(in imgINotificationObserver aObserver);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to unregister an image decoder observer.
|
* Used to unregister an image decoder observer.
|
||||||
*
|
*
|
||||||
* @param aObserver the observer to unregister
|
* @param aObserver the observer to unregister
|
||||||
*/
|
*/
|
||||||
void removeObserver(in imgIDecoderObserver aObserver);
|
void removeObserver(in imgINotificationObserver aObserver);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accessor to get the image requests
|
* Accessor to get the image requests
|
||||||
|
@ -28,7 +28,6 @@ EXPORTS = \
|
|||||||
nsRange.h \
|
nsRange.h \
|
||||||
nsScriptLoader.h \
|
nsScriptLoader.h \
|
||||||
nsStubDocumentObserver.h \
|
nsStubDocumentObserver.h \
|
||||||
nsStubImageDecoderObserver.h \
|
|
||||||
nsStubMutationObserver.h \
|
nsStubMutationObserver.h \
|
||||||
nsTextFragment.h \
|
nsTextFragment.h \
|
||||||
mozAutoDocUpdate.h \
|
mozAutoDocUpdate.h \
|
||||||
@ -109,7 +108,6 @@ CPPSRCS = \
|
|||||||
nsScriptElement.cpp \
|
nsScriptElement.cpp \
|
||||||
nsScriptLoader.cpp \
|
nsScriptLoader.cpp \
|
||||||
nsStubDocumentObserver.cpp \
|
nsStubDocumentObserver.cpp \
|
||||||
nsStubImageDecoderObserver.cpp \
|
|
||||||
nsStubMutationObserver.cpp \
|
nsStubMutationObserver.cpp \
|
||||||
nsStyledElement.cpp \
|
nsStyledElement.cpp \
|
||||||
nsStyleLinkElement.cpp \
|
nsStyleLinkElement.cpp \
|
||||||
|
@ -1225,15 +1225,9 @@ nsContentSink::Notify(nsITimer *timer)
|
|||||||
#ifdef MOZ_DEBUG
|
#ifdef MOZ_DEBUG
|
||||||
{
|
{
|
||||||
PRTime now = PR_Now();
|
PRTime now = PR_Now();
|
||||||
int64_t diff, interval;
|
|
||||||
int32_t delay;
|
|
||||||
|
|
||||||
LL_I2L(interval, GetNotificationInterval());
|
int64_t interval = GetNotificationInterval();
|
||||||
diff = now - mLastNotificationTime;
|
delay = int32_t(now - mLastNotificationTime - interval) / PR_USEC_PER_MSEC;
|
||||||
|
|
||||||
diff -= interval;
|
|
||||||
LL_L2I(delay, diff);
|
|
||||||
delay /= PR_USEC_PER_MSEC;
|
|
||||||
|
|
||||||
mBackoffCount--;
|
mBackoffCount--;
|
||||||
SINK_TRACE(gContentSinkLogModuleInfo, SINK_TRACE_REFLOW,
|
SINK_TRACE(gContentSinkLogModuleInfo, SINK_TRACE_REFLOW,
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
#include "nsIForm.h"
|
#include "nsIForm.h"
|
||||||
#include "nsIFormControl.h"
|
#include "nsIFormControl.h"
|
||||||
#include "nsGkAtoms.h"
|
#include "nsGkAtoms.h"
|
||||||
#include "imgIDecoderObserver.h"
|
#include "imgINotificationObserver.h"
|
||||||
#include "imgIRequest.h"
|
#include "imgIRequest.h"
|
||||||
#include "imgIContainer.h"
|
#include "imgIContainer.h"
|
||||||
#include "imgILoader.h"
|
#include "imgILoader.h"
|
||||||
@ -2734,7 +2734,7 @@ nsContentUtils::IsImageInCache(nsIURI* aURI, nsIDocument* aDocument)
|
|||||||
nsresult
|
nsresult
|
||||||
nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
|
nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
|
||||||
nsIPrincipal* aLoadingPrincipal, nsIURI* aReferrer,
|
nsIPrincipal* aLoadingPrincipal, nsIURI* aReferrer,
|
||||||
imgIDecoderObserver* aObserver, int32_t aLoadFlags,
|
imgINotificationObserver* aObserver, int32_t aLoadFlags,
|
||||||
imgIRequest** aRequest)
|
imgIRequest** aRequest)
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aURI, "Must have a URI");
|
NS_PRECONDITION(aURI, "Must have a URI");
|
||||||
@ -2777,7 +2777,7 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
|
|||||||
aReferrer, /* referrer */
|
aReferrer, /* referrer */
|
||||||
aLoadingPrincipal, /* loading principal */
|
aLoadingPrincipal, /* loading principal */
|
||||||
loadGroup, /* loadgroup */
|
loadGroup, /* loadgroup */
|
||||||
aObserver, /* imgIDecoderObserver */
|
aObserver, /* imgINotificationObserver */
|
||||||
aLoadingDocument, /* uniquification key */
|
aLoadingDocument, /* uniquification key */
|
||||||
aLoadFlags, /* load flags */
|
aLoadFlags, /* load flags */
|
||||||
nullptr, /* cache key */
|
nullptr, /* cache key */
|
||||||
|
@ -6874,9 +6874,7 @@ nsDocument::RetrieveRelevantHeaders(nsIChannel *aChannel)
|
|||||||
rv = file->GetLastModifiedTime(&msecs);
|
rv = file->GetLastModifiedTime(&msecs);
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
int64_t intermediateValue;
|
modDate = msecs * int64_t(PR_USEC_PER_MSEC);
|
||||||
LL_I2L(intermediateValue, PR_USEC_PER_MSEC);
|
|
||||||
modDate = msecs * intermediateValue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -48,11 +48,10 @@ public:
|
|||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS_INHERITED4(nsGenConImageContent,
|
NS_IMPL_ISUPPORTS_INHERITED3(nsGenConImageContent,
|
||||||
nsXMLElement,
|
nsXMLElement,
|
||||||
nsIImageLoadingContent,
|
nsIImageLoadingContent,
|
||||||
imgIContainerObserver,
|
imgINotificationObserver,
|
||||||
imgIDecoderObserver,
|
|
||||||
imgIOnloadBlocker)
|
imgIOnloadBlocker)
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -122,114 +122,63 @@ nsImageLoadingContent::~nsImageLoadingContent()
|
|||||||
} \
|
} \
|
||||||
PR_END_MACRO
|
PR_END_MACRO
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* imgIContainerObserver impl
|
* imgINotificationObserver impl
|
||||||
*/
|
*/
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsImageLoadingContent::FrameChanged(imgIRequest* aRequest,
|
nsImageLoadingContent::Notify(imgIRequest* aRequest,
|
||||||
imgIContainer* aContainer,
|
int32_t aType,
|
||||||
const nsIntRect* aDirtyRect)
|
const nsIntRect* aData)
|
||||||
{
|
{
|
||||||
LOOP_OVER_OBSERVERS(FrameChanged(aRequest, aContainer, aDirtyRect));
|
if (aType == imgINotificationObserver::IS_ANIMATED) {
|
||||||
return NS_OK;
|
return OnImageIsAnimated(aRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* imgIDecoderObserver impl
|
|
||||||
*/
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageLoadingContent::OnStartRequest(imgIRequest* aRequest)
|
|
||||||
{
|
|
||||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
|
||||||
|
|
||||||
LOOP_OVER_OBSERVERS(OnStartRequest(aRequest));
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageLoadingContent::OnStartDecode(imgIRequest* aRequest)
|
|
||||||
{
|
|
||||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
|
||||||
|
|
||||||
LOOP_OVER_OBSERVERS(OnStartDecode(aRequest));
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageLoadingContent::OnStartContainer(imgIRequest* aRequest,
|
|
||||||
imgIContainer* aContainer)
|
|
||||||
{
|
|
||||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
|
||||||
|
|
||||||
LOOP_OVER_OBSERVERS(OnStartContainer(aRequest, aContainer));
|
|
||||||
|
|
||||||
// Have to check for state changes here, since we might have been in
|
|
||||||
// the LOADING state before.
|
|
||||||
UpdateImageState(true);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageLoadingContent::OnStartFrame(imgIRequest* aRequest,
|
|
||||||
uint32_t aFrame)
|
|
||||||
{
|
|
||||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
|
||||||
|
|
||||||
LOOP_OVER_OBSERVERS(OnStartFrame(aRequest, aFrame));
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageLoadingContent::OnDataAvailable(imgIRequest* aRequest,
|
|
||||||
bool aCurrentFrame,
|
|
||||||
const nsIntRect* aRect)
|
|
||||||
{
|
|
||||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
|
||||||
|
|
||||||
LOOP_OVER_OBSERVERS(OnDataAvailable(aRequest, aCurrentFrame, aRect));
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageLoadingContent::OnStopFrame(imgIRequest* aRequest,
|
|
||||||
uint32_t aFrame)
|
|
||||||
{
|
|
||||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
|
||||||
|
|
||||||
LOOP_OVER_OBSERVERS(OnStopFrame(aRequest, aFrame));
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageLoadingContent::OnStopContainer(imgIRequest* aRequest,
|
|
||||||
imgIContainer* aContainer)
|
|
||||||
{
|
|
||||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
|
||||||
|
|
||||||
LOOP_OVER_OBSERVERS(OnStopContainer(aRequest, aContainer));
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Warning - This isn't actually fired when decode is complete. Rather, it's
|
|
||||||
// fired when load is complete. See bug 505385, and in the mean time use
|
|
||||||
// OnStopContainer.
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest,
|
|
||||||
nsresult aStatus,
|
|
||||||
const PRUnichar* aStatusArg)
|
|
||||||
{
|
|
||||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::LOAD_COMPLETE) {
|
||||||
// We should definitely have a request here
|
// We should definitely have a request here
|
||||||
NS_ABORT_IF_FALSE(aRequest, "no request?");
|
NS_ABORT_IF_FALSE(aRequest, "no request?");
|
||||||
|
|
||||||
NS_PRECONDITION(aRequest == mCurrentRequest || aRequest == mPendingRequest,
|
NS_PRECONDITION(aRequest == mCurrentRequest || aRequest == mPendingRequest,
|
||||||
"Unknown request");
|
"Unknown request");
|
||||||
LOOP_OVER_OBSERVERS(OnStopDecode(aRequest, aStatus, aStatusArg));
|
}
|
||||||
|
|
||||||
// XXXbholley - When we fix bug 505385, everything here should go in
|
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
||||||
// OnStopRequest.
|
|
||||||
|
LOOP_OVER_OBSERVERS(Notify(aRequest, aType, aData));
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
|
||||||
|
// Have to check for state changes here, since we might have been in
|
||||||
|
// the LOADING state before.
|
||||||
|
UpdateImageState(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::LOAD_COMPLETE) {
|
||||||
|
uint32_t reqStatus;
|
||||||
|
aRequest->GetImageStatus(&reqStatus);
|
||||||
|
nsresult status =
|
||||||
|
reqStatus & imgIRequest::STATUS_ERROR ? NS_ERROR_FAILURE : NS_OK;
|
||||||
|
return OnStopRequest(aRequest, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsImageLoadingContent::OnStopRequest(imgIRequest* aRequest,
|
||||||
|
nsresult aStatus)
|
||||||
|
{
|
||||||
|
uint32_t oldStatus;
|
||||||
|
aRequest->GetImageStatus(&oldStatus);
|
||||||
|
|
||||||
|
//XXXjdm This occurs when we have a pending request created, then another
|
||||||
|
// pending request replaces it before the first one is finished.
|
||||||
|
// This begs the question of what the correct behaviour is; we used
|
||||||
|
// to not have to care because we ran this code in OnStopDecode which
|
||||||
|
// wasn't called when the first request was cancelled. For now, I choose
|
||||||
|
// to punt when the given request doesn't appear to have terminated in
|
||||||
|
// an expected state.
|
||||||
|
if (!(oldStatus & (imgIRequest::STATUS_ERROR | imgIRequest::STATUS_LOAD_COMPLETE)))
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
// Our state may change. Watch it.
|
// Our state may change. Watch it.
|
||||||
AutoStateChanger changer(this, true);
|
AutoStateChanger changer(this, true);
|
||||||
@ -284,17 +233,7 @@ nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
nsresult
|
||||||
nsImageLoadingContent::OnStopRequest(imgIRequest* aRequest, bool aLastPart)
|
|
||||||
{
|
|
||||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
|
||||||
|
|
||||||
LOOP_OVER_OBSERVERS(OnStopRequest(aRequest, aLastPart));
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageLoadingContent::OnImageIsAnimated(imgIRequest *aRequest)
|
nsImageLoadingContent::OnImageIsAnimated(imgIRequest *aRequest)
|
||||||
{
|
{
|
||||||
bool* requestFlag = GetRegisteredFlagForRequest(aRequest);
|
bool* requestFlag = GetRegisteredFlagForRequest(aRequest);
|
||||||
@ -306,16 +245,6 @@ nsImageLoadingContent::OnImageIsAnimated(imgIRequest *aRequest)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageLoadingContent::OnDiscard(imgIRequest *aRequest)
|
|
||||||
{
|
|
||||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
|
||||||
|
|
||||||
LOOP_OVER_OBSERVERS(OnDiscard(aRequest));
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nsIImageLoadingContent impl
|
* nsIImageLoadingContent impl
|
||||||
*/
|
*/
|
||||||
@ -351,7 +280,7 @@ nsImageLoadingContent::GetImageBlockingStatus(int16_t* aStatus)
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsImageLoadingContent::AddObserver(imgIDecoderObserver* aObserver)
|
nsImageLoadingContent::AddObserver(imgINotificationObserver* aObserver)
|
||||||
{
|
{
|
||||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
||||||
|
|
||||||
@ -379,7 +308,7 @@ nsImageLoadingContent::AddObserver(imgIDecoderObserver* aObserver)
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsImageLoadingContent::RemoveObserver(imgIDecoderObserver* aObserver)
|
nsImageLoadingContent::RemoveObserver(imgINotificationObserver* aObserver)
|
||||||
{
|
{
|
||||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
||||||
|
|
||||||
|
@ -13,8 +13,7 @@
|
|||||||
#ifndef nsImageLoadingContent_h__
|
#ifndef nsImageLoadingContent_h__
|
||||||
#define nsImageLoadingContent_h__
|
#define nsImageLoadingContent_h__
|
||||||
|
|
||||||
#include "imgIContainerObserver.h"
|
#include "imgINotificationObserver.h"
|
||||||
#include "imgIDecoderObserver.h"
|
|
||||||
#include "imgIOnloadBlocker.h"
|
#include "imgIOnloadBlocker.h"
|
||||||
#include "mozilla/CORSMode.h"
|
#include "mozilla/CORSMode.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
@ -36,8 +35,7 @@ public:
|
|||||||
nsImageLoadingContent();
|
nsImageLoadingContent();
|
||||||
virtual ~nsImageLoadingContent();
|
virtual ~nsImageLoadingContent();
|
||||||
|
|
||||||
NS_DECL_IMGICONTAINEROBSERVER
|
NS_DECL_IMGINOTIFICATIONOBSERVER
|
||||||
NS_DECL_IMGIDECODEROBSERVER
|
|
||||||
NS_DECL_NSIIMAGELOADINGCONTENT
|
NS_DECL_NSIIMAGELOADINGCONTENT
|
||||||
NS_DECL_IMGIONLOADBLOCKER
|
NS_DECL_IMGIONLOADBLOCKER
|
||||||
|
|
||||||
@ -161,12 +159,15 @@ protected:
|
|||||||
nsIContent* aBindingParent, bool aCompileEventHandlers);
|
nsIContent* aBindingParent, bool aCompileEventHandlers);
|
||||||
void UnbindFromTree(bool aDeep, bool aNullParent);
|
void UnbindFromTree(bool aDeep, bool aNullParent);
|
||||||
|
|
||||||
|
nsresult OnStopRequest(imgIRequest* aRequest, nsresult aStatus);
|
||||||
|
nsresult OnImageIsAnimated(imgIRequest *aRequest);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Struct used to manage the image observers.
|
* Struct used to manage the image observers.
|
||||||
*/
|
*/
|
||||||
struct ImageObserver {
|
struct ImageObserver {
|
||||||
ImageObserver(imgIDecoderObserver* aObserver) :
|
ImageObserver(imgINotificationObserver* aObserver) :
|
||||||
mObserver(aObserver),
|
mObserver(aObserver),
|
||||||
mNext(nullptr)
|
mNext(nullptr)
|
||||||
{
|
{
|
||||||
@ -178,7 +179,7 @@ private:
|
|||||||
NS_CONTENT_DELETE_LIST_MEMBER(ImageObserver, this, mNext);
|
NS_CONTENT_DELETE_LIST_MEMBER(ImageObserver, this, mNext);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<imgIDecoderObserver> mObserver;
|
nsCOMPtr<imgINotificationObserver> mObserver;
|
||||||
ImageObserver* mNext;
|
ImageObserver* mNext;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -98,13 +98,6 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||||||
NS_DECL_NSIINTERFACEREQUESTOR
|
NS_DECL_NSIINTERFACEREQUESTOR
|
||||||
NS_DECL_NSICHANNELEVENTSINK
|
NS_DECL_NSICHANNELEVENTSINK
|
||||||
|
|
||||||
#ifdef HAVE_CPP_AMBIGUITY_RESOLVING_USING
|
|
||||||
// Fix gcc compile warnings
|
|
||||||
using nsImageLoadingContent::OnStartRequest;
|
|
||||||
using nsImageLoadingContent::OnDataAvailable;
|
|
||||||
using nsImageLoadingContent::OnStopRequest;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object state. This is a bitmask of NS_EVENT_STATEs epresenting the
|
* Object state. This is a bitmask of NS_EVENT_STATEs epresenting the
|
||||||
* current state of the object.
|
* current state of the object.
|
||||||
|
@ -1,89 +0,0 @@
|
|||||||
/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "nsStubImageDecoderObserver.h"
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsStubImageDecoderObserver::OnStartRequest(imgIRequest *aRequest)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsStubImageDecoderObserver::OnStartDecode(imgIRequest *aRequest)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsStubImageDecoderObserver::OnStartContainer(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsStubImageDecoderObserver::OnStartFrame(imgIRequest *aRequest,
|
|
||||||
uint32_t aFrame)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsStubImageDecoderObserver::OnDataAvailable(imgIRequest *aRequest,
|
|
||||||
bool aCurrentFrame,
|
|
||||||
const nsIntRect * aRect)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsStubImageDecoderObserver::OnStopFrame(imgIRequest *aRequest,
|
|
||||||
uint32_t aFrame)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsStubImageDecoderObserver::OnStopContainer(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsStubImageDecoderObserver::OnStopDecode(imgIRequest *aRequest,
|
|
||||||
nsresult status,
|
|
||||||
const PRUnichar *statusArg)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsStubImageDecoderObserver::OnStopRequest(imgIRequest *aRequest,
|
|
||||||
bool aIsLastPart)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsStubImageDecoderObserver::OnDiscard(imgIRequest *aRequest)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsStubImageDecoderObserver::OnImageIsAnimated(imgIRequest *aRequest)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsStubImageDecoderObserver::FrameChanged(imgIRequest* aRequest,
|
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* nsStubImageDecoderObserver is an implementation of the imgIDecoderObserver
|
|
||||||
* interface (except for the methods on nsISupports) that is intended to be
|
|
||||||
* used as a base class within the content/layout library. All methods do
|
|
||||||
* nothing.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef nsStubImageDecoderObserver_h_
|
|
||||||
#define nsStubImageDecoderObserver_h_
|
|
||||||
|
|
||||||
#include "imgIDecoderObserver.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* There are two advantages to inheriting from nsStubImageDecoderObserver
|
|
||||||
* rather than directly from imgIDecoderObserver:
|
|
||||||
* 1. smaller compiled code size (since there's no need for the code
|
|
||||||
* for the empty virtual function implementations for every
|
|
||||||
* imgIDecoderObserver implementation)
|
|
||||||
* 2. the performance of document's loop over observers benefits from
|
|
||||||
* the fact that more of the functions called are the same (which
|
|
||||||
* can reduce instruction cache misses and perhaps improve branch
|
|
||||||
* prediction)
|
|
||||||
*/
|
|
||||||
class nsStubImageDecoderObserver : public imgIDecoderObserver {
|
|
||||||
public:
|
|
||||||
NS_DECL_IMGICONTAINEROBSERVER
|
|
||||||
NS_DECL_IMGIDECODEROBSERVER
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* !defined(nsStubImageDecoderObserver_h_) */
|
|
@ -4110,7 +4110,7 @@ NS_IMETHODIMP nsXMLHttpProgressEvent::GetPosition(uint32_t *aPosition)
|
|||||||
{
|
{
|
||||||
WarnAboutLSProgressEvent(nsIDocument::ePosition);
|
WarnAboutLSProgressEvent(nsIDocument::ePosition);
|
||||||
// XXX can we change the iface?
|
// XXX can we change the iface?
|
||||||
LL_L2UI(*aPosition, mCurProgress);
|
*aPosition = uint32_t(mCurProgress);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4118,7 +4118,7 @@ NS_IMETHODIMP nsXMLHttpProgressEvent::GetTotalSize(uint32_t *aTotalSize)
|
|||||||
{
|
{
|
||||||
WarnAboutLSProgressEvent(nsIDocument::eTotalSize);
|
WarnAboutLSProgressEvent(nsIDocument::eTotalSize);
|
||||||
// XXX can we change the iface?
|
// XXX can we change the iface?
|
||||||
LL_L2UI(*aTotalSize, mMaxProgress);
|
*aTotalSize = uint32_t(mMaxProgress);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,8 +132,6 @@ protected:
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
extern bool AzureCanvasEnabled();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -2,8 +2,8 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#ifndef nsCanvasRenderingContext2DAzure_h
|
#ifndef CanvasRenderingContext2D_h
|
||||||
#define nsCanvasRenderingContext2DAzure_h
|
#define CanvasRenderingContext2D_h
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "nsIDOMCanvasRenderingContext2D.h"
|
#include "nsIDOMCanvasRenderingContext2D.h"
|
||||||
@ -19,24 +19,26 @@
|
|||||||
#include "mozilla/dom/ImageData.h"
|
#include "mozilla/dom/ImageData.h"
|
||||||
#include "mozilla/dom/UnionTypes.h"
|
#include "mozilla/dom/UnionTypes.h"
|
||||||
|
|
||||||
|
#define NS_CANVASGRADIENTAZURE_PRIVATE_IID \
|
||||||
|
{0x28425a6a, 0x90e0, 0x4d42, {0x9c, 0x75, 0xff, 0x60, 0x09, 0xb3, 0x10, 0xa8}}
|
||||||
|
#define NS_CANVASPATTERNAZURE_PRIVATE_IID \
|
||||||
|
{0xc9bacc25, 0x28da, 0x421e, {0x9a, 0x4b, 0xbb, 0xd6, 0x93, 0x05, 0x12, 0xbc}}
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
|
||||||
template<typename T> class Optional;
|
|
||||||
}
|
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
struct Rect;
|
struct Rect;
|
||||||
class SourceSurface;
|
class SourceSurface;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
namespace dom {
|
||||||
extern const mozilla::gfx::Float SIGMA_MAX;
|
extern const mozilla::gfx::Float SIGMA_MAX;
|
||||||
|
|
||||||
|
template<typename T> class Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** nsCanvasGradientAzure
|
** CanvasGradient
|
||||||
**/
|
**/
|
||||||
#define NS_CANVASGRADIENTAZURE_PRIVATE_IID \
|
class CanvasGradient : public nsIDOMCanvasGradient
|
||||||
{0x28425a6a, 0x90e0, 0x4d42, {0x9c, 0x75, 0xff, 0x60, 0x09, 0xb3, 0x10, 0xa8}}
|
|
||||||
class nsCanvasGradientAzure : public nsIDOMCanvasGradient
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASGRADIENTAZURE_PRIVATE_IID)
|
NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASGRADIENTAZURE_PRIVATE_IID)
|
||||||
@ -71,21 +73,19 @@ public:
|
|||||||
NS_IMETHOD AddColorStop(float offset, const nsAString& colorstr);
|
NS_IMETHOD AddColorStop(float offset, const nsAString& colorstr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsCanvasGradientAzure(Type aType) : mType(aType)
|
CanvasGradient(Type aType) : mType(aType)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
nsTArray<mozilla::gfx::GradientStop> mRawStops;
|
nsTArray<mozilla::gfx::GradientStop> mRawStops;
|
||||||
mozilla::RefPtr<mozilla::gfx::GradientStops> mStops;
|
mozilla::RefPtr<mozilla::gfx::GradientStops> mStops;
|
||||||
Type mType;
|
Type mType;
|
||||||
virtual ~nsCanvasGradientAzure() {}
|
virtual ~CanvasGradient() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** nsCanvasPatternAzure
|
** CanvasPattern
|
||||||
**/
|
**/
|
||||||
#define NS_CANVASPATTERNAZURE_PRIVATE_IID \
|
class CanvasPattern MOZ_FINAL : public nsIDOMCanvasPattern
|
||||||
{0xc9bacc25, 0x28da, 0x421e, {0x9a, 0x4b, 0xbb, 0xd6, 0x93, 0x05, 0x12, 0xbc}}
|
|
||||||
class nsCanvasPatternAzure MOZ_FINAL : public nsIDOMCanvasPattern
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASPATTERNAZURE_PRIVATE_IID)
|
NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASPATTERNAZURE_PRIVATE_IID)
|
||||||
@ -98,7 +98,7 @@ public:
|
|||||||
NOREPEAT
|
NOREPEAT
|
||||||
};
|
};
|
||||||
|
|
||||||
nsCanvasPatternAzure(mozilla::gfx::SourceSurface* aSurface,
|
CanvasPattern(mozilla::gfx::SourceSurface* aSurface,
|
||||||
RepeatMode aRepeat,
|
RepeatMode aRepeat,
|
||||||
nsIPrincipal* principalForSecurityCheck,
|
nsIPrincipal* principalForSecurityCheck,
|
||||||
bool forceWriteOnly,
|
bool forceWriteOnly,
|
||||||
@ -120,13 +120,13 @@ public:
|
|||||||
const bool mCORSUsed;
|
const bool mCORSUsed;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nsCanvasBidiProcessorAzure;
|
struct CanvasBidiProcessor;
|
||||||
class CanvasRenderingContext2DUserDataAzure;
|
class CanvasRenderingContext2DUserData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** nsCanvasRenderingContext2DAzure
|
** CanvasRenderingContext2D
|
||||||
**/
|
**/
|
||||||
class nsCanvasRenderingContext2DAzure :
|
class CanvasRenderingContext2D :
|
||||||
public nsIDOMCanvasRenderingContext2D,
|
public nsIDOMCanvasRenderingContext2D,
|
||||||
public nsICanvasRenderingContextInternal,
|
public nsICanvasRenderingContextInternal,
|
||||||
public nsWrapperCache
|
public nsWrapperCache
|
||||||
@ -135,8 +135,8 @@ typedef mozilla::dom::HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement
|
|||||||
HTMLImageOrCanvasOrVideoElement;
|
HTMLImageOrCanvasOrVideoElement;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
nsCanvasRenderingContext2DAzure();
|
CanvasRenderingContext2D();
|
||||||
virtual ~nsCanvasRenderingContext2DAzure();
|
virtual ~CanvasRenderingContext2D();
|
||||||
|
|
||||||
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
|
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
|
||||||
bool *triedToWrap);
|
bool *triedToWrap);
|
||||||
@ -495,7 +495,7 @@ public:
|
|||||||
// nsISupports interface + CC
|
// nsISupports interface + CC
|
||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
|
|
||||||
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsCanvasRenderingContext2DAzure,
|
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(CanvasRenderingContext2D,
|
||||||
nsIDOMCanvasRenderingContext2D)
|
nsIDOMCanvasRenderingContext2D)
|
||||||
|
|
||||||
// nsIDOMCanvasRenderingContext2D interface
|
// nsIDOMCanvasRenderingContext2D interface
|
||||||
@ -535,7 +535,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class CanvasRenderingContext2DUserDataAzure;
|
friend class CanvasRenderingContext2DUserData;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
|
nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
|
||||||
@ -572,12 +572,12 @@ protected:
|
|||||||
void SetStyleFromJSValue(JSContext* cx, JS::Value& value, Style whichStyle);
|
void SetStyleFromJSValue(JSContext* cx, JS::Value& value, Style whichStyle);
|
||||||
void SetStyleFromString(const nsAString& str, Style whichStyle);
|
void SetStyleFromString(const nsAString& str, Style whichStyle);
|
||||||
|
|
||||||
void SetStyleFromGradient(nsCanvasGradientAzure *gradient, Style whichStyle)
|
void SetStyleFromGradient(CanvasGradient *gradient, Style whichStyle)
|
||||||
{
|
{
|
||||||
CurrentState().SetGradientStyle(whichStyle, gradient);
|
CurrentState().SetGradientStyle(whichStyle, gradient);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetStyleFromPattern(nsCanvasPatternAzure *pattern, Style whichStyle)
|
void SetStyleFromPattern(CanvasPattern *pattern, Style whichStyle)
|
||||||
{
|
{
|
||||||
CurrentState().SetPatternStyle(whichStyle, pattern);
|
CurrentState().SetPatternStyle(whichStyle, pattern);
|
||||||
}
|
}
|
||||||
@ -704,7 +704,7 @@ protected:
|
|||||||
// This is needed for drawing in drawAsyncXULElement
|
// This is needed for drawing in drawAsyncXULElement
|
||||||
bool mIPC;
|
bool mIPC;
|
||||||
|
|
||||||
nsTArray<CanvasRenderingContext2DUserDataAzure*> mUserDatas;
|
nsTArray<CanvasRenderingContext2DUserData*> mUserDatas;
|
||||||
|
|
||||||
// If mCanvasElement is not provided, then a docshell is
|
// If mCanvasElement is not provided, then a docshell is
|
||||||
nsCOMPtr<nsIDocShell> mDocShell;
|
nsCOMPtr<nsIDocShell> mDocShell;
|
||||||
@ -886,18 +886,21 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetColorStyle(Style whichStyle, nscolor color) {
|
void SetColorStyle(Style whichStyle, nscolor color)
|
||||||
|
{
|
||||||
colorStyles[whichStyle] = color;
|
colorStyles[whichStyle] = color;
|
||||||
gradientStyles[whichStyle] = nullptr;
|
gradientStyles[whichStyle] = nullptr;
|
||||||
patternStyles[whichStyle] = nullptr;
|
patternStyles[whichStyle] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPatternStyle(Style whichStyle, nsCanvasPatternAzure* pat) {
|
void SetPatternStyle(Style whichStyle, CanvasPattern* pat)
|
||||||
|
{
|
||||||
gradientStyles[whichStyle] = nullptr;
|
gradientStyles[whichStyle] = nullptr;
|
||||||
patternStyles[whichStyle] = pat;
|
patternStyles[whichStyle] = pat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetGradientStyle(Style whichStyle, nsCanvasGradientAzure* grad) {
|
void SetGradientStyle(Style whichStyle, CanvasGradient* grad)
|
||||||
|
{
|
||||||
gradientStyles[whichStyle] = grad;
|
gradientStyles[whichStyle] = grad;
|
||||||
patternStyles[whichStyle] = nullptr;
|
patternStyles[whichStyle] = nullptr;
|
||||||
}
|
}
|
||||||
@ -914,8 +917,8 @@ protected:
|
|||||||
std::vector<mozilla::RefPtr<mozilla::gfx::Path> > clipsPushed;
|
std::vector<mozilla::RefPtr<mozilla::gfx::Path> > clipsPushed;
|
||||||
|
|
||||||
nsRefPtr<gfxFontGroup> fontGroup;
|
nsRefPtr<gfxFontGroup> fontGroup;
|
||||||
nsRefPtr<nsCanvasGradientAzure> gradientStyles[STYLE_MAX];
|
nsRefPtr<CanvasGradient> gradientStyles[STYLE_MAX];
|
||||||
nsRefPtr<nsCanvasPatternAzure> patternStyles[STYLE_MAX];
|
nsRefPtr<CanvasPattern> patternStyles[STYLE_MAX];
|
||||||
|
|
||||||
nsString font;
|
nsString font;
|
||||||
TextAlign textAlign;
|
TextAlign textAlign;
|
||||||
@ -951,7 +954,8 @@ protected:
|
|||||||
friend class AdjustedTarget;
|
friend class AdjustedTarget;
|
||||||
|
|
||||||
// other helpers
|
// other helpers
|
||||||
void GetAppUnitsValues(uint32_t *perDevPixel, uint32_t *perCSSPixel) {
|
void GetAppUnitsValues(uint32_t *perDevPixel, uint32_t *perCSSPixel)
|
||||||
|
{
|
||||||
// If we don't have a canvas element, we just return something generic.
|
// If we don't have a canvas element, we just return something generic.
|
||||||
uint32_t devPixel = 60;
|
uint32_t devPixel = 60;
|
||||||
uint32_t cssPixel = 60;
|
uint32_t cssPixel = 60;
|
||||||
@ -972,7 +976,10 @@ protected:
|
|||||||
*perCSSPixel = cssPixel;
|
*perCSSPixel = cssPixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend struct nsCanvasBidiProcessorAzure;
|
friend struct CanvasBidiProcessor;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsCanvasRenderingContext2DAzure_h */
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CanvasRenderingContext2D_h */
|
@ -1,38 +0,0 @@
|
|||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef CustomQS_Canvas_h
|
|
||||||
#define CustomQS_Canvas_h
|
|
||||||
|
|
||||||
#include "jsapi.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/ImageData.h"
|
|
||||||
|
|
||||||
#include "XPCQuickStubs.h"
|
|
||||||
|
|
||||||
static bool
|
|
||||||
GetImageData(JSContext* cx, JS::Value& imageData,
|
|
||||||
uint32_t* width, uint32_t* height, JS::Anchor<JSObject*>* array)
|
|
||||||
{
|
|
||||||
if (!imageData.isObject()) {
|
|
||||||
return xpc_qsThrow(cx, NS_ERROR_DOM_TYPE_MISMATCH_ERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIDOMImageData* domImageData;
|
|
||||||
xpc_qsSelfRef imageDataRef;
|
|
||||||
nsresult rv = xpc_qsUnwrapArg<nsIDOMImageData>(cx, imageData, &domImageData,
|
|
||||||
&imageDataRef.ptr, &imageData);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return xpc_qsThrow(cx, rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
mozilla::dom::ImageData* concreteImageData =
|
|
||||||
static_cast<mozilla::dom::ImageData*>(domImageData);
|
|
||||||
*width = concreteImageData->GetWidth();
|
|
||||||
*height = concreteImageData->GetHeight();
|
|
||||||
array->set(concreteImageData->GetDataObject());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CustomQS_Canvas_h
|
|
@ -1,302 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "nsError.h"
|
|
||||||
#include "nsIDOMCanvasRenderingContext2D.h"
|
|
||||||
#include "mozilla/CheckedInt.h"
|
|
||||||
#include "nsMathUtils.h"
|
|
||||||
#include "CustomQS_Canvas.h"
|
|
||||||
|
|
||||||
#include "jsapi.h"
|
|
||||||
#include "jsfriendapi.h"
|
|
||||||
|
|
||||||
typedef NS_STDCALL_FUNCPROTO(nsresult, CanvasStyleSetterType, nsIDOMCanvasRenderingContext2D,
|
|
||||||
SetStrokeStyle_multi, (const nsAString &, nsISupports *));
|
|
||||||
typedef NS_STDCALL_FUNCPROTO(nsresult, CanvasStyleGetterType, nsIDOMCanvasRenderingContext2D,
|
|
||||||
GetStrokeStyle_multi, (nsAString &, nsISupports **, int32_t *));
|
|
||||||
|
|
||||||
static JSBool
|
|
||||||
Canvas2D_SetStyleHelper(JSContext *cx, JSObject *obj, jsid id, JSMutableHandleValue vp,
|
|
||||||
CanvasStyleSetterType setfunc)
|
|
||||||
{
|
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
|
||||||
nsIDOMCanvasRenderingContext2D *self;
|
|
||||||
xpc_qsSelfRef selfref;
|
|
||||||
JS::AutoValueRooter tvr(cx);
|
|
||||||
if (!xpc_qsUnwrapThis(cx, obj, &self, &selfref.ptr, tvr.jsval_addr(), nullptr))
|
|
||||||
return JS_FALSE;
|
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
|
||||||
if (JSVAL_IS_STRING(vp)) {
|
|
||||||
xpc_qsDOMString arg0(cx, vp, vp.address(),
|
|
||||||
xpc_qsDOMString::eDefaultNullBehavior,
|
|
||||||
xpc_qsDOMString::eDefaultUndefinedBehavior);
|
|
||||||
if (!arg0.IsValid())
|
|
||||||
return JS_FALSE;
|
|
||||||
|
|
||||||
rv = (self->*setfunc)(arg0, nullptr);
|
|
||||||
} else {
|
|
||||||
nsISupports *arg0;
|
|
||||||
xpc_qsSelfRef arg0ref;
|
|
||||||
rv = xpc_qsUnwrapArg<nsISupports>(cx, vp, &arg0, &arg0ref.ptr, vp.address());
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
xpc_qsThrowBadSetterValue(cx, rv, JSVAL_TO_OBJECT(*tvr.jsval_addr()), id);
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = (self->*setfunc)(NullString(), arg0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return xpc_qsThrowGetterSetterFailed(cx, rv, JSVAL_TO_OBJECT(*tvr.jsval_addr()), id);
|
|
||||||
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSBool
|
|
||||||
Canvas2D_GetStyleHelper(JSContext *cx, JSObject *obj, jsid id, JSMutableHandleValue vp,
|
|
||||||
CanvasStyleGetterType getfunc)
|
|
||||||
{
|
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
|
||||||
nsIDOMCanvasRenderingContext2D *self;
|
|
||||||
xpc_qsSelfRef selfref;
|
|
||||||
XPCLazyCallContext lccx(JS_CALLER, cx, obj);
|
|
||||||
if (!xpc_qsUnwrapThis(cx, obj, &self, &selfref.ptr, vp.address(), &lccx))
|
|
||||||
return JS_FALSE;
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
nsString resultString;
|
|
||||||
nsCOMPtr<nsISupports> resultInterface;
|
|
||||||
int32_t resultType;
|
|
||||||
rv = (self->*getfunc)(resultString, getter_AddRefs(resultInterface), &resultType);
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return xpc_qsThrowGetterSetterFailed(cx, rv, JSVAL_TO_OBJECT(vp), id);
|
|
||||||
|
|
||||||
switch (resultType) {
|
|
||||||
case nsIDOMCanvasRenderingContext2D::CMG_STYLE_STRING:
|
|
||||||
return xpc::StringToJsval(cx, resultString, vp.address());
|
|
||||||
|
|
||||||
case nsIDOMCanvasRenderingContext2D::CMG_STYLE_PATTERN:
|
|
||||||
{
|
|
||||||
qsObjectHelper helper(resultInterface,
|
|
||||||
xpc_qsGetWrapperCache(resultInterface));
|
|
||||||
return xpc_qsXPCOMObjectToJsval(lccx, helper,
|
|
||||||
&NS_GET_IID(nsIDOMCanvasPattern),
|
|
||||||
&interfaces[k_nsIDOMCanvasPattern], vp.address());
|
|
||||||
}
|
|
||||||
case nsIDOMCanvasRenderingContext2D::CMG_STYLE_GRADIENT:
|
|
||||||
{
|
|
||||||
qsObjectHelper helper(resultInterface,
|
|
||||||
xpc_qsGetWrapperCache(resultInterface));
|
|
||||||
return xpc_qsXPCOMObjectToJsval(lccx, helper,
|
|
||||||
&NS_GET_IID(nsIDOMCanvasGradient),
|
|
||||||
&interfaces[k_nsIDOMCanvasGradient], vp.address());
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return xpc_qsThrowGetterSetterFailed(cx, NS_ERROR_FAILURE, JSVAL_TO_OBJECT(vp), id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSBool
|
|
||||||
nsIDOMCanvasRenderingContext2D_SetStrokeStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, JSMutableHandleValue vp)
|
|
||||||
{
|
|
||||||
return Canvas2D_SetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::SetStrokeStyle_multi);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSBool
|
|
||||||
nsIDOMCanvasRenderingContext2D_GetStrokeStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMutableHandleValue vp)
|
|
||||||
{
|
|
||||||
return Canvas2D_GetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::GetStrokeStyle_multi);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSBool
|
|
||||||
nsIDOMCanvasRenderingContext2D_SetFillStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, JSMutableHandleValue vp)
|
|
||||||
{
|
|
||||||
return Canvas2D_SetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::SetFillStyle_multi);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSBool
|
|
||||||
nsIDOMCanvasRenderingContext2D_GetFillStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMutableHandleValue vp)
|
|
||||||
{
|
|
||||||
return Canvas2D_GetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::GetFillStyle_multi);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
CreateImageData(JSContext* cx, JSObject* obj, uint32_t w, uint32_t h, jsval* vp)
|
|
||||||
{
|
|
||||||
using mozilla::CheckedInt;
|
|
||||||
|
|
||||||
if (w == 0)
|
|
||||||
w = 1;
|
|
||||||
if (h == 0)
|
|
||||||
h = 1;
|
|
||||||
|
|
||||||
CheckedInt<uint32_t> len = CheckedInt<uint32_t>(w) * h * 4;
|
|
||||||
if (!len.isValid()) {
|
|
||||||
return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the fast typed array; it's initialized to 0 by default.
|
|
||||||
JSObject* darray = JS_NewUint8ClampedArray(cx, len.value());
|
|
||||||
JS::AutoObjectRooter rd(cx, darray);
|
|
||||||
if (!darray) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
XPCLazyCallContext lccx(JS_CALLER, cx, obj);
|
|
||||||
const nsIID *iid = &NS_GET_IID(nsIDOMImageData);
|
|
||||||
nsRefPtr<mozilla::dom::ImageData> imageData =
|
|
||||||
new mozilla::dom::ImageData(w, h, *darray);
|
|
||||||
qsObjectHelper helper(imageData, NULL);
|
|
||||||
return xpc_qsXPCOMObjectToJsval(lccx, helper, iid,
|
|
||||||
&interfaces[k_nsIDOMImageData], vp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSBool
|
|
||||||
nsIDOMCanvasRenderingContext2D_CreateImageData(JSContext *cx, unsigned argc, jsval *vp)
|
|
||||||
{
|
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
|
||||||
|
|
||||||
JSObject* obj = JS_THIS_OBJECT(cx, vp);
|
|
||||||
if (!obj) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc < 1)
|
|
||||||
return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
|
|
||||||
|
|
||||||
jsval *argv = JS_ARGV(cx, vp);
|
|
||||||
|
|
||||||
if (argc == 1) {
|
|
||||||
uint32_t data_width, data_height;
|
|
||||||
JS::Anchor<JSObject*> darray;
|
|
||||||
if (!GetImageData(cx, argv[0], &data_width, &data_height, &darray)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CreateImageData(cx, obj, data_width, data_height, vp);
|
|
||||||
}
|
|
||||||
|
|
||||||
double width, height;
|
|
||||||
if (!JS_ValueToNumber(cx, argv[0], &width) ||
|
|
||||||
!JS_ValueToNumber(cx, argv[1], &height))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!NS_finite(width) || !NS_finite(height))
|
|
||||||
return xpc_qsThrow(cx, NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
|
||||||
|
|
||||||
if (!width || !height)
|
|
||||||
return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
|
|
||||||
|
|
||||||
int32_t wi = JS_DoubleToInt32(width);
|
|
||||||
int32_t hi = JS_DoubleToInt32(height);
|
|
||||||
|
|
||||||
uint32_t w = NS_ABS(wi);
|
|
||||||
uint32_t h = NS_ABS(hi);
|
|
||||||
return CreateImageData(cx, obj, w, h, vp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSBool
|
|
||||||
nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, unsigned argc, jsval *vp)
|
|
||||||
{
|
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
|
||||||
|
|
||||||
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
|
||||||
if (!obj)
|
|
||||||
return JS_FALSE;
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
nsIDOMCanvasRenderingContext2D *self;
|
|
||||||
xpc_qsSelfRef selfref;
|
|
||||||
JS::AutoValueRooter tvr(cx);
|
|
||||||
if (!xpc_qsUnwrapThis(cx, obj, &self, &selfref.ptr, tvr.jsval_addr(), nullptr))
|
|
||||||
return JS_FALSE;
|
|
||||||
|
|
||||||
if (argc < 3)
|
|
||||||
return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
|
|
||||||
|
|
||||||
jsval *argv = JS_ARGV(cx, vp);
|
|
||||||
|
|
||||||
uint32_t w, h;
|
|
||||||
JS::Anchor<JSObject*> darray;
|
|
||||||
if (!GetImageData(cx, argv[0], &w, &h, &darray)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
double xd, yd;
|
|
||||||
if (!JS_ValueToNumber(cx, argv[1], &xd) ||
|
|
||||||
!JS_ValueToNumber(cx, argv[2], &yd)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NS_finite(xd) || !NS_finite(yd)) {
|
|
||||||
return xpc_qsThrow(cx, NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t x = JS_DoubleToInt32(xd);
|
|
||||||
int32_t y = JS_DoubleToInt32(yd);
|
|
||||||
|
|
||||||
// the optional dirty rect
|
|
||||||
bool hasDirtyRect = false;
|
|
||||||
int32_t dirtyX = 0,
|
|
||||||
dirtyY = 0,
|
|
||||||
dirtyWidth = w,
|
|
||||||
dirtyHeight = h;
|
|
||||||
|
|
||||||
if (argc >= 7) {
|
|
||||||
double dx, dy, dw, dh;
|
|
||||||
if (!JS_ValueToNumber(cx, argv[3], &dx) ||
|
|
||||||
!JS_ValueToNumber(cx, argv[4], &dy) ||
|
|
||||||
!JS_ValueToNumber(cx, argv[5], &dw) ||
|
|
||||||
!JS_ValueToNumber(cx, argv[6], &dh)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NS_finite(dx) || !NS_finite(dy) ||
|
|
||||||
!NS_finite(dw) || !NS_finite(dh)) {
|
|
||||||
return xpc_qsThrow(cx, NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
dirtyX = JS_DoubleToInt32(dx);
|
|
||||||
dirtyY = JS_DoubleToInt32(dy);
|
|
||||||
dirtyWidth = JS_DoubleToInt32(dw);
|
|
||||||
dirtyHeight = JS_DoubleToInt32(dh);
|
|
||||||
|
|
||||||
hasDirtyRect = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
JS::AutoValueRooter tsrc_tvr(cx);
|
|
||||||
|
|
||||||
JSObject * tsrc = NULL;
|
|
||||||
if (JS_IsInt8Array(darray.get(), cx) ||
|
|
||||||
JS_IsUint8Array(darray.get(), cx) ||
|
|
||||||
JS_IsUint8ClampedArray(darray.get(), cx))
|
|
||||||
{
|
|
||||||
tsrc = darray.get();
|
|
||||||
} else if (JS_IsTypedArrayObject(darray.get(), cx) || JS_IsArrayObject(cx, darray.get())) {
|
|
||||||
// ugh, this isn't a uint8 typed array, someone made their own object; convert it to a typed array
|
|
||||||
JSObject *nobj = JS_NewUint8ClampedArrayFromArray(cx, darray.get());
|
|
||||||
if (!nobj)
|
|
||||||
return JS_FALSE;
|
|
||||||
|
|
||||||
*tsrc_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
|
|
||||||
tsrc = nobj;
|
|
||||||
} else {
|
|
||||||
// yeah, no.
|
|
||||||
return xpc_qsThrow(cx, NS_ERROR_DOM_TYPE_MISMATCH_ERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
// make the call
|
|
||||||
MOZ_ASSERT(JS_IsTypedArrayObject(tsrc, cx));
|
|
||||||
uint8_t* data = reinterpret_cast<uint8_t*>(JS_GetArrayBufferViewData(tsrc, cx));
|
|
||||||
uint32_t byteLength = JS_GetTypedArrayByteLength(tsrc, cx);
|
|
||||||
rv = self->PutImageData_explicit(x, y, w, h, data, byteLength, hasDirtyRect, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return xpc_qsThrowMethodFailed(cx, rv, vp);
|
|
||||||
|
|
||||||
*vp = JSVAL_VOID;
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
@ -17,8 +17,6 @@ LIBRARY_NAME = gkconcvs_s
|
|||||||
LIBXUL_LIBRARY = 1
|
LIBXUL_LIBRARY = 1
|
||||||
|
|
||||||
EXPORTS = \
|
EXPORTS = \
|
||||||
CustomQS_Canvas.h \
|
|
||||||
CustomQS_Canvas2D.h \
|
|
||||||
WebGLContext.h \
|
WebGLContext.h \
|
||||||
WebGLElementArrayCache.h \
|
WebGLElementArrayCache.h \
|
||||||
WebGLExtensions.h \
|
WebGLExtensions.h \
|
||||||
@ -27,14 +25,14 @@ EXPORTS = \
|
|||||||
EXPORTS_NAMESPACES = mozilla/dom
|
EXPORTS_NAMESPACES = mozilla/dom
|
||||||
|
|
||||||
EXPORTS_mozilla/dom = \
|
EXPORTS_mozilla/dom = \
|
||||||
|
CanvasRenderingContext2D.h \
|
||||||
ImageData.h \
|
ImageData.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
CPPSRCS = \
|
CPPSRCS = \
|
||||||
CanvasImageCache.cpp \
|
CanvasImageCache.cpp \
|
||||||
|
CanvasRenderingContext2D.cpp \
|
||||||
CanvasUtils.cpp \
|
CanvasUtils.cpp \
|
||||||
nsCanvasRenderingContext2D.cpp \
|
|
||||||
nsCanvasRenderingContext2DAzure.cpp \
|
|
||||||
DocumentRendererParent.cpp \
|
DocumentRendererParent.cpp \
|
||||||
DocumentRendererChild.cpp \
|
DocumentRendererChild.cpp \
|
||||||
ImageData.cpp \
|
ImageData.cpp \
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -168,7 +168,6 @@ protected:
|
|||||||
const nsAString& aType,
|
const nsAString& aType,
|
||||||
nsIDOMFile** aResult);
|
nsIDOMFile** aResult);
|
||||||
nsresult GetContextHelper(const nsAString& aContextId,
|
nsresult GetContextHelper(const nsAString& aContextId,
|
||||||
bool aForceThebes,
|
|
||||||
nsICanvasRenderingContextInternal **aContext);
|
nsICanvasRenderingContextInternal **aContext);
|
||||||
void CallPrintCallback();
|
void CallPrintCallback();
|
||||||
|
|
||||||
|
@ -601,7 +601,6 @@ nsHTMLCanvasElement::MozGetAsFileImpl(const nsAString& aName,
|
|||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLCanvasElement::GetContextHelper(const nsAString& aContextId,
|
nsHTMLCanvasElement::GetContextHelper(const nsAString& aContextId,
|
||||||
bool aForceThebes,
|
|
||||||
nsICanvasRenderingContextInternal **aContext)
|
nsICanvasRenderingContextInternal **aContext)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG(aContext);
|
NS_ENSURE_ARG(aContext);
|
||||||
@ -624,10 +623,6 @@ nsHTMLCanvasElement::GetContextHelper(const nsAString& aContextId,
|
|||||||
nsCString ctxString("@mozilla.org/content/canvas-rendering-context;1?id=");
|
nsCString ctxString("@mozilla.org/content/canvas-rendering-context;1?id=");
|
||||||
ctxString.Append(ctxId);
|
ctxString.Append(ctxId);
|
||||||
|
|
||||||
if (aForceThebes && ctxId.EqualsASCII("2d")) {
|
|
||||||
ctxString.AssignASCII("@mozilla.org/content/2dthebes-canvas-rendering-context;1");
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsCOMPtr<nsICanvasRenderingContextInternal> ctx =
|
nsCOMPtr<nsICanvasRenderingContextInternal> ctx =
|
||||||
do_CreateInstance(ctxString.get(), &rv);
|
do_CreateInstance(ctxString.get(), &rv);
|
||||||
@ -653,10 +648,8 @@ nsHTMLCanvasElement::GetContext(const nsAString& aContextId,
|
|||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
bool forceThebes = false;
|
if (mCurrentContextId.IsEmpty()) {
|
||||||
|
rv = GetContextHelper(aContextId, getter_AddRefs(mCurrentContext));
|
||||||
while (mCurrentContextId.IsEmpty()) {
|
|
||||||
rv = GetContextHelper(aContextId, forceThebes, getter_AddRefs(mCurrentContext));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
if (!mCurrentContext) {
|
if (!mCurrentContext) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -720,17 +713,12 @@ nsHTMLCanvasElement::GetContext(const nsAString& aContextId,
|
|||||||
|
|
||||||
rv = UpdateContext(contextProps);
|
rv = UpdateContext(contextProps);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
if (!forceThebes) {
|
|
||||||
// Try again with a Thebes context
|
|
||||||
forceThebes = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentContextId.Assign(aContextId);
|
mCurrentContextId.Assign(aContextId);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mCurrentContextId.Equals(aContextId)) {
|
if (!mCurrentContextId.Equals(aContextId)) {
|
||||||
//XXX eventually allow for more than one active context on a given canvas
|
//XXX eventually allow for more than one active context on a given canvas
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -754,7 +742,7 @@ nsHTMLCanvasElement::MozGetIPCContext(const nsAString& aContextId,
|
|||||||
return NS_ERROR_INVALID_ARG;
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
|
||||||
if (mCurrentContextId.IsEmpty()) {
|
if (mCurrentContextId.IsEmpty()) {
|
||||||
nsresult rv = GetContextHelper(aContextId, false, getter_AddRefs(mCurrentContext));
|
nsresult rv = GetContextHelper(aContextId, getter_AddRefs(mCurrentContext));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
if (!mCurrentContext) {
|
if (!mCurrentContext) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -948,16 +936,3 @@ nsHTMLCanvasElement::RenderContextsExternal(gfxContext *aContext, gfxPattern::Gr
|
|||||||
return mCurrentContext->Render(aContext, aFilter, aFlags);
|
return mCurrentContext->Render(aContext, aFilter, aFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult NS_NewCanvasRenderingContext2DThebes(nsIDOMCanvasRenderingContext2D** aResult);
|
|
||||||
nsresult NS_NewCanvasRenderingContext2DAzure(nsIDOMCanvasRenderingContext2D** aResult);
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
NS_NewCanvasRenderingContext2D(nsIDOMCanvasRenderingContext2D** aResult)
|
|
||||||
{
|
|
||||||
Telemetry::Accumulate(Telemetry::CANVAS_2D_USED, 1);
|
|
||||||
if (AzureCanvasEnabled()) {
|
|
||||||
return NS_NewCanvasRenderingContext2DAzure(aResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_NewCanvasRenderingContext2DThebes(aResult);
|
|
||||||
}
|
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include "imgIContainer.h"
|
#include "imgIContainer.h"
|
||||||
#include "imgILoader.h"
|
#include "imgILoader.h"
|
||||||
#include "imgIRequest.h"
|
#include "imgIRequest.h"
|
||||||
#include "imgIDecoderObserver.h"
|
#include "imgINotificationObserver.h"
|
||||||
|
|
||||||
#include "nsILoadGroup.h"
|
#include "nsILoadGroup.h"
|
||||||
|
|
||||||
@ -89,13 +89,12 @@ DOMCI_NODE_DATA(HTMLImageElement, nsHTMLImageElement)
|
|||||||
|
|
||||||
// QueryInterface implementation for nsHTMLImageElement
|
// QueryInterface implementation for nsHTMLImageElement
|
||||||
NS_INTERFACE_TABLE_HEAD(nsHTMLImageElement)
|
NS_INTERFACE_TABLE_HEAD(nsHTMLImageElement)
|
||||||
NS_HTML_CONTENT_INTERFACE_TABLE6(nsHTMLImageElement,
|
NS_HTML_CONTENT_INTERFACE_TABLE5(nsHTMLImageElement,
|
||||||
nsIDOMHTMLImageElement,
|
nsIDOMHTMLImageElement,
|
||||||
nsIJSNativeInitializer,
|
nsIJSNativeInitializer,
|
||||||
imgIDecoderObserver,
|
|
||||||
nsIImageLoadingContent,
|
nsIImageLoadingContent,
|
||||||
imgIContainerObserver,
|
imgIOnloadBlocker,
|
||||||
imgIOnloadBlocker)
|
imgINotificationObserver)
|
||||||
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLImageElement,
|
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLImageElement,
|
||||||
nsGenericHTMLElement)
|
nsGenericHTMLElement)
|
||||||
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLImageElement)
|
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLImageElement)
|
||||||
|
@ -642,13 +642,12 @@ DOMCI_NODE_DATA(HTMLInputElement, nsHTMLInputElement)
|
|||||||
|
|
||||||
// QueryInterface implementation for nsHTMLInputElement
|
// QueryInterface implementation for nsHTMLInputElement
|
||||||
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLInputElement)
|
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLInputElement)
|
||||||
NS_HTML_CONTENT_INTERFACE_TABLE9(nsHTMLInputElement,
|
NS_HTML_CONTENT_INTERFACE_TABLE8(nsHTMLInputElement,
|
||||||
nsIDOMHTMLInputElement,
|
nsIDOMHTMLInputElement,
|
||||||
nsITextControlElement,
|
nsITextControlElement,
|
||||||
nsIPhonetic,
|
nsIPhonetic,
|
||||||
imgIDecoderObserver,
|
imgINotificationObserver,
|
||||||
nsIImageLoadingContent,
|
nsIImageLoadingContent,
|
||||||
imgIContainerObserver,
|
|
||||||
imgIOnloadBlocker,
|
imgIOnloadBlocker,
|
||||||
nsIDOMNSEditableElement,
|
nsIDOMNSEditableElement,
|
||||||
nsIConstraintValidation)
|
nsIConstraintValidation)
|
||||||
|
@ -185,14 +185,13 @@ DOMCI_NODE_DATA(HTMLObjectElement, nsHTMLObjectElement)
|
|||||||
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLObjectElement)
|
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLObjectElement)
|
||||||
NS_HTML_CONTENT_INTERFACE_TABLE_BEGIN(nsHTMLObjectElement)
|
NS_HTML_CONTENT_INTERFACE_TABLE_BEGIN(nsHTMLObjectElement)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIDOMHTMLObjectElement)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIDOMHTMLObjectElement)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, imgIDecoderObserver)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, imgINotificationObserver)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIRequestObserver)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIRequestObserver)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIStreamListener)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIStreamListener)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIFrameLoaderOwner)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIFrameLoaderOwner)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIObjectLoadingContent)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIObjectLoadingContent)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIImageLoadingContent)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIImageLoadingContent)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, imgIOnloadBlocker)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, imgIOnloadBlocker)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, imgIContainerObserver)
|
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIInterfaceRequestor)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIInterfaceRequestor)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIChannelEventSink)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIChannelEventSink)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIConstraintValidation)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIConstraintValidation)
|
||||||
|
@ -234,9 +234,8 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLSharedObjectElement)
|
|||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIRequestObserver)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIRequestObserver)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIStreamListener)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIStreamListener)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIFrameLoaderOwner)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIFrameLoaderOwner)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, imgIContainerObserver)
|
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIObjectLoadingContent)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIObjectLoadingContent)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, imgIDecoderObserver)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, imgINotificationObserver)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIImageLoadingContent)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIImageLoadingContent)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, imgIOnloadBlocker)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, imgIOnloadBlocker)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIInterfaceRequestor)
|
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIInterfaceRequestor)
|
||||||
|
@ -72,7 +72,7 @@ function HTML_TAG(aTagName, aImplClass) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const objectIfaces = [
|
const objectIfaces = [
|
||||||
"imgIDecoderObserver", "nsIRequestObserver", "nsIStreamListener",
|
"imgINotificationObserver", "nsIRequestObserver", "nsIStreamListener",
|
||||||
"nsIFrameLoaderOwner", "nsIObjectLoadingContent", "nsIInterfaceRequestor",
|
"nsIFrameLoaderOwner", "nsIObjectLoadingContent", "nsIInterfaceRequestor",
|
||||||
"nsIChannelEventSink"
|
"nsIChannelEventSink"
|
||||||
];
|
];
|
||||||
@ -160,9 +160,9 @@ HTML_TAG("i", "");
|
|||||||
HTML_TAG("iframe", "IFrame", [ "nsIDOMGetSVGDocument", "nsIDOMMozBrowserFrame" ],
|
HTML_TAG("iframe", "IFrame", [ "nsIDOMGetSVGDocument", "nsIDOMMozBrowserFrame" ],
|
||||||
[ "nsIFrameLoaderOwner" ]);
|
[ "nsIFrameLoaderOwner" ]);
|
||||||
HTML_TAG("image", "Span");
|
HTML_TAG("image", "Span");
|
||||||
HTML_TAG("img", "Image", [], [ "imgIDecoderObserver",
|
HTML_TAG("img", "Image", [], [ "imgINotificationObserver",
|
||||||
"nsIImageLoadingContent" ]);
|
"nsIImageLoadingContent" ]);
|
||||||
HTML_TAG("input", "Input", [], [ "imgIDecoderObserver",
|
HTML_TAG("input", "Input", [], [ "imgINotificationObserver",
|
||||||
"nsIImageLoadingContent",
|
"nsIImageLoadingContent",
|
||||||
"nsIDOMNSEditableElement" ]);
|
"nsIDOMNSEditableElement" ]);
|
||||||
HTML_TAG("ins", "Mod");
|
HTML_TAG("ins", "Mod");
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include "imgIRequest.h"
|
#include "imgIRequest.h"
|
||||||
#include "imgILoader.h"
|
#include "imgILoader.h"
|
||||||
#include "imgIContainer.h"
|
#include "imgIContainer.h"
|
||||||
#include "nsStubImageDecoderObserver.h"
|
#include "imgINotificationObserver.h"
|
||||||
#include "nsIPresShell.h"
|
#include "nsIPresShell.h"
|
||||||
#include "nsPresContext.h"
|
#include "nsPresContext.h"
|
||||||
#include "nsStyleContext.h"
|
#include "nsStyleContext.h"
|
||||||
@ -64,7 +64,7 @@ public:
|
|||||||
|
|
||||||
class ImageDocument : public MediaDocument
|
class ImageDocument : public MediaDocument
|
||||||
, public nsIImageDocument
|
, public nsIImageDocument
|
||||||
, public nsStubImageDecoderObserver
|
, public imgINotificationObserver
|
||||||
, public nsIDOMEventListener
|
, public nsIDOMEventListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -89,12 +89,7 @@ public:
|
|||||||
nsIDOMEventTarget* aDispatchStartTarget);
|
nsIDOMEventTarget* aDispatchStartTarget);
|
||||||
|
|
||||||
NS_DECL_NSIIMAGEDOCUMENT
|
NS_DECL_NSIIMAGEDOCUMENT
|
||||||
|
NS_DECL_IMGINOTIFICATIONOBSERVER
|
||||||
// imgIDecoderObserver (override nsStubImageDecoderObserver)
|
|
||||||
NS_IMETHOD OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage);
|
|
||||||
NS_IMETHOD OnStopContainer(imgIRequest* aRequest, imgIContainer* aImage);
|
|
||||||
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult aStatus, const PRUnichar *aStatusArg);
|
|
||||||
NS_IMETHOD OnDiscard(imgIRequest *aRequest);
|
|
||||||
|
|
||||||
// nsIDOMEventListener
|
// nsIDOMEventListener
|
||||||
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
|
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
|
||||||
@ -123,6 +118,9 @@ protected:
|
|||||||
void ResetZoomLevel();
|
void ResetZoomLevel();
|
||||||
float GetZoomLevel();
|
float GetZoomLevel();
|
||||||
|
|
||||||
|
nsresult OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage);
|
||||||
|
nsresult OnStopRequest(imgIRequest *aRequest, nsresult aStatus);
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> mImageContent;
|
nsCOMPtr<nsIContent> mImageContent;
|
||||||
|
|
||||||
int32_t mVisibleWidth;
|
int32_t mVisibleWidth;
|
||||||
@ -238,8 +236,7 @@ DOMCI_NODE_DATA(ImageDocument, ImageDocument)
|
|||||||
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(ImageDocument)
|
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(ImageDocument)
|
||||||
NS_HTML_DOCUMENT_INTERFACE_TABLE_BEGIN(ImageDocument)
|
NS_HTML_DOCUMENT_INTERFACE_TABLE_BEGIN(ImageDocument)
|
||||||
NS_INTERFACE_TABLE_ENTRY(ImageDocument, nsIImageDocument)
|
NS_INTERFACE_TABLE_ENTRY(ImageDocument, nsIImageDocument)
|
||||||
NS_INTERFACE_TABLE_ENTRY(ImageDocument, imgIDecoderObserver)
|
NS_INTERFACE_TABLE_ENTRY(ImageDocument, imgINotificationObserver)
|
||||||
NS_INTERFACE_TABLE_ENTRY(ImageDocument, imgIContainerObserver)
|
|
||||||
NS_INTERFACE_TABLE_ENTRY(ImageDocument, nsIDOMEventListener)
|
NS_INTERFACE_TABLE_ENTRY(ImageDocument, nsIDOMEventListener)
|
||||||
NS_OFFSET_AND_INTERFACE_TABLE_END
|
NS_OFFSET_AND_INTERFACE_TABLE_END
|
||||||
NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
|
NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
|
||||||
@ -509,6 +506,45 @@ ImageDocument::ToggleImageSize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
ImageDocument::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* aData)
|
||||||
|
{
|
||||||
|
if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
|
||||||
|
nsCOMPtr<imgIContainer> image;
|
||||||
|
aRequest->GetImage(getter_AddRefs(image));
|
||||||
|
return OnStartContainer(aRequest, image);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::DECODE_COMPLETE) {
|
||||||
|
if (mImageContent) {
|
||||||
|
// Update the background-color of the image only after the
|
||||||
|
// image has been decoded to prevent flashes of just the
|
||||||
|
// background-color.
|
||||||
|
mImageContent->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
|
||||||
|
NS_LITERAL_STRING("decoded"), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::DISCARD) {
|
||||||
|
// mImageContent can be null if the document is already destroyed
|
||||||
|
if (mImageContent) {
|
||||||
|
// Remove any decoded-related styling when the image is unloaded.
|
||||||
|
mImageContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::_class,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::LOAD_COMPLETE) {
|
||||||
|
uint32_t reqStatus;
|
||||||
|
aRequest->GetImageStatus(&reqStatus);
|
||||||
|
nsresult status =
|
||||||
|
reqStatus & imgIRequest::STATUS_ERROR ? NS_ERROR_FAILURE : NS_OK;
|
||||||
|
return OnStopRequest(aRequest, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
ImageDocument::OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage)
|
ImageDocument::OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage)
|
||||||
{
|
{
|
||||||
aImage->GetWidth(&mImageWidth);
|
aImage->GetWidth(&mImageWidth);
|
||||||
@ -521,24 +557,9 @@ ImageDocument::OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
nsresult
|
||||||
ImageDocument::OnStopContainer(imgIRequest* aRequest, imgIContainer* aImage)
|
ImageDocument::OnStopRequest(imgIRequest *aRequest,
|
||||||
{
|
nsresult aStatus)
|
||||||
if (mImageContent) {
|
|
||||||
// Update the background-color of the image only after the
|
|
||||||
// image has been decoded to prevent flashes of just the
|
|
||||||
// background-color.
|
|
||||||
mImageContent->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
|
|
||||||
NS_LITERAL_STRING("decoded"), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
ImageDocument::OnStopDecode(imgIRequest *aRequest,
|
|
||||||
nsresult aStatus,
|
|
||||||
const PRUnichar *aStatusArg)
|
|
||||||
{
|
{
|
||||||
UpdateTitleAndCharset();
|
UpdateTitleAndCharset();
|
||||||
|
|
||||||
@ -559,18 +580,6 @@ ImageDocument::OnStopDecode(imgIRequest *aRequest,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
ImageDocument::OnDiscard(imgIRequest *aRequest)
|
|
||||||
{
|
|
||||||
// mImageContent can be null if the document is already destroyed
|
|
||||||
if (mImageContent) {
|
|
||||||
// Remove any decoded-related styling when the image is unloaded.
|
|
||||||
mImageContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::_class,
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
ImageDocument::HandleEvent(nsIDOMEvent* aEvent)
|
ImageDocument::HandleEvent(nsIDOMEvent* aEvent)
|
||||||
{
|
{
|
||||||
|
@ -5505,7 +5505,7 @@ NS_INTERFACE_TABLE_HEAD(nsSVGFEImageElement)
|
|||||||
nsIDOMSVGElement,
|
nsIDOMSVGElement,
|
||||||
nsIDOMSVGFilterPrimitiveStandardAttributes,
|
nsIDOMSVGFilterPrimitiveStandardAttributes,
|
||||||
nsIDOMSVGFEImageElement, nsIDOMSVGURIReference,
|
nsIDOMSVGFEImageElement, nsIDOMSVGURIReference,
|
||||||
imgIDecoderObserver, nsIImageLoadingContent,
|
imgINotificationObserver, nsIImageLoadingContent,
|
||||||
imgIOnloadBlocker)
|
imgIOnloadBlocker)
|
||||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFEImageElement)
|
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFEImageElement)
|
||||||
NS_INTERFACE_MAP_END_INHERITING(nsSVGFEImageElementBase)
|
NS_INTERFACE_MAP_END_INHERITING(nsSVGFEImageElementBase)
|
||||||
@ -5756,43 +5756,27 @@ nsSVGFEImageElement::GetStringInfo()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// imgIDecoderObserver methods
|
// imgINotificationObserver methods
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsSVGFEImageElement::OnStopDecode(imgIRequest *aRequest,
|
nsSVGFEImageElement::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* aData)
|
||||||
nsresult status,
|
|
||||||
const PRUnichar *statusArg)
|
|
||||||
{
|
{
|
||||||
nsresult rv =
|
nsresult rv = nsImageLoadingContent::Notify(aRequest, aType, aData);
|
||||||
nsImageLoadingContent::OnStopDecode(aRequest, status, statusArg);
|
|
||||||
Invalidate();
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSVGFEImageElement::FrameChanged(imgIRequest* aRequest,
|
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect)
|
|
||||||
{
|
|
||||||
nsresult rv =
|
|
||||||
nsImageLoadingContent::FrameChanged(aRequest, aContainer, aDirtyRect);
|
|
||||||
Invalidate();
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSVGFEImageElement::OnStartContainer(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer)
|
|
||||||
{
|
|
||||||
nsresult rv =
|
|
||||||
nsImageLoadingContent::OnStartContainer(aRequest, aContainer);
|
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
|
||||||
// Request a decode
|
// Request a decode
|
||||||
NS_ABORT_IF_FALSE(aContainer, "who sent the notification then?");
|
nsCOMPtr<imgIContainer> container;
|
||||||
aContainer->StartDecoding();
|
aRequest->GetImage(getter_AddRefs(container));
|
||||||
|
NS_ABORT_IF_FALSE(container, "who sent the notification then?");
|
||||||
|
container->StartDecoding();
|
||||||
|
}
|
||||||
|
|
||||||
// We have a size - invalidate
|
if (aType == imgINotificationObserver::LOAD_COMPLETE ||
|
||||||
|
aType == imgINotificationObserver::FRAME_UPDATE ||
|
||||||
|
aType == imgINotificationObserver::SIZE_AVAILABLE) {
|
||||||
Invalidate();
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,16 +267,7 @@ public:
|
|||||||
virtual void UnbindFromTree(bool aDeep, bool aNullParent);
|
virtual void UnbindFromTree(bool aDeep, bool aNullParent);
|
||||||
virtual nsEventStates IntrinsicState() const;
|
virtual nsEventStates IntrinsicState() const;
|
||||||
|
|
||||||
// imgIDecoderObserver
|
NS_IMETHODIMP Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData);
|
||||||
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
|
|
||||||
const PRUnichar *statusArg);
|
|
||||||
// imgIContainerObserver
|
|
||||||
NS_IMETHOD FrameChanged(imgIRequest* aRequest,
|
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect);
|
|
||||||
// imgIContainerObserver
|
|
||||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer);
|
|
||||||
|
|
||||||
void MaybeLoadSVGImage();
|
void MaybeLoadSVGImage();
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "imgIContainer.h"
|
#include "imgIContainer.h"
|
||||||
#include "imgIDecoderObserver.h"
|
#include "imgINotificationObserver.h"
|
||||||
#include "gfxContext.h"
|
#include "gfxContext.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
@ -42,7 +42,7 @@ NS_INTERFACE_TABLE_HEAD(nsSVGImageElement)
|
|||||||
NS_NODE_INTERFACE_TABLE9(nsSVGImageElement, nsIDOMNode, nsIDOMElement,
|
NS_NODE_INTERFACE_TABLE9(nsSVGImageElement, nsIDOMNode, nsIDOMElement,
|
||||||
nsIDOMSVGElement, nsIDOMSVGTests,
|
nsIDOMSVGElement, nsIDOMSVGTests,
|
||||||
nsIDOMSVGImageElement,
|
nsIDOMSVGImageElement,
|
||||||
nsIDOMSVGURIReference, imgIDecoderObserver,
|
nsIDOMSVGURIReference, imgINotificationObserver,
|
||||||
nsIImageLoadingContent, imgIOnloadBlocker)
|
nsIImageLoadingContent, imgIOnloadBlocker)
|
||||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGImageElement)
|
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGImageElement)
|
||||||
NS_INTERFACE_MAP_END_INHERITING(nsSVGImageElementBase)
|
NS_INTERFACE_MAP_END_INHERITING(nsSVGImageElementBase)
|
||||||
|
@ -532,12 +532,8 @@ protected:
|
|||||||
static inline uint32_t
|
static inline uint32_t
|
||||||
PRTimeToSeconds(PRTime t_usec)
|
PRTimeToSeconds(PRTime t_usec)
|
||||||
{
|
{
|
||||||
PRTime usec_per_sec;
|
PRTime usec_per_sec = PR_USEC_PER_SEC;
|
||||||
uint32_t t_sec;
|
return uint32_t(t_usec /= usec_per_sec);
|
||||||
LL_I2L(usec_per_sec, PR_USEC_PER_SEC);
|
|
||||||
t_usec /= usec_per_sec;
|
|
||||||
LL_L2I(t_sec, t_usec);
|
|
||||||
return t_sec;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsFrame();
|
bool IsFrame();
|
||||||
|
@ -4546,11 +4546,6 @@ nsDOMClassInfo::Init()
|
|||||||
// overwrite some values.
|
// overwrite some values.
|
||||||
mozilla::dom::oldproxybindings::Register(nameSpaceManager);
|
mozilla::dom::oldproxybindings::Register(nameSpaceManager);
|
||||||
|
|
||||||
if (!AzureCanvasEnabled()) {
|
|
||||||
nameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING("CanvasRenderingContext2D"),
|
|
||||||
nullptr, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
sIsInitialized = true;
|
sIsInitialized = true;
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -109,10 +109,6 @@ DOMInterfaces = {
|
|||||||
|
|
||||||
'CanvasRenderingContext2D': [
|
'CanvasRenderingContext2D': [
|
||||||
{
|
{
|
||||||
'nativeType': 'nsCanvasRenderingContext2DAzure',
|
|
||||||
# Making this non-prefable requires that we ensure that nothing takes this
|
|
||||||
# type as an argument or that the non-Azure variant is removed.
|
|
||||||
'prefable': True,
|
|
||||||
'implicitJSContext': [
|
'implicitJSContext': [
|
||||||
'createImageData', 'getImageData', 'putImageData', 'strokeStyle',
|
'createImageData', 'getImageData', 'putImageData', 'strokeStyle',
|
||||||
'fillStyle', 'mozDash'
|
'fillStyle', 'mozDash'
|
||||||
|
@ -20,13 +20,15 @@
|
|||||||
USING_BLUETOOTH_NAMESPACE
|
USING_BLUETOOTH_NAMESPACE
|
||||||
using namespace mozilla::ipc;
|
using namespace mozilla::ipc;
|
||||||
|
|
||||||
static const uint32_t kUpdateProgressBase = 500000;
|
// Sending system message "bluetooth-opp-update-progress" every 50kb
|
||||||
|
static const uint32_t kUpdateProgressBase = 50 * 1024;
|
||||||
|
|
||||||
static mozilla::RefPtr<BluetoothOppManager> sInstance;
|
static mozilla::RefPtr<BluetoothOppManager> sInstance;
|
||||||
static nsCOMPtr<nsIInputStream> stream = nullptr;
|
static nsCOMPtr<nsIInputStream> stream = nullptr;
|
||||||
static uint32_t sSentFileLength = 0;
|
static uint32_t sSentFileLength = 0;
|
||||||
static nsString sFileName;
|
static nsString sFileName;
|
||||||
static uint64_t sFileLength = 0;
|
static uint64_t sFileLength = 0;
|
||||||
|
static nsString sContentType;
|
||||||
static int sUpdateProgressCounter = 0;
|
static int sUpdateProgressCounter = 0;
|
||||||
|
|
||||||
class ReadFileTask : public nsRunnable
|
class ReadFileTask : public nsRunnable
|
||||||
@ -97,6 +99,11 @@ BluetoothOppManager::BluetoothOppManager() : mConnected(false)
|
|||||||
, mReadFileThread(nullptr)
|
, mReadFileThread(nullptr)
|
||||||
, mPacketLeftLength(0)
|
, mPacketLeftLength(0)
|
||||||
{
|
{
|
||||||
|
// FIXME / Bug 800249:
|
||||||
|
// mConnectedDeviceAddress is Bluetooth address of connected device,
|
||||||
|
// we will be able to get this value after bug 800249 lands. For now,
|
||||||
|
// just assign a fake value to it.
|
||||||
|
mConnectedDeviceAddress.AssignASCII("00:00:00:00:00:00");
|
||||||
}
|
}
|
||||||
|
|
||||||
BluetoothOppManager::~BluetoothOppManager()
|
BluetoothOppManager::~BluetoothOppManager()
|
||||||
@ -232,6 +239,12 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rv = mBlob->GetType(sContentType);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_WARNING("Can't get content type");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (NS_FAILED(NS_NewThread(getter_AddRefs(mReadFileThread)))) {
|
if (NS_FAILED(NS_NewThread(getter_AddRefs(mReadFileThread)))) {
|
||||||
NS_WARNING("Can't create thread");
|
NS_WARNING("Can't create thread");
|
||||||
SendDisconnectRequest();
|
SendDisconnectRequest();
|
||||||
@ -242,6 +255,8 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
|
|||||||
sSentFileLength = 0;
|
sSentFileLength = 0;
|
||||||
mAbortFlag = false;
|
mAbortFlag = false;
|
||||||
sInstance->SendPutHeaderRequest(sFileName, sFileLength);
|
sInstance->SendPutHeaderRequest(sFileName, sFileLength);
|
||||||
|
StartFileTransfer(mConnectedDeviceAddress, false,
|
||||||
|
sFileName, sFileLength, sContentType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (mLastCommand == ObexRequestCode::Disconnect) {
|
} else if (mLastCommand == ObexRequestCode::Disconnect) {
|
||||||
@ -262,9 +277,9 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
|
|||||||
if (mAbortFlag || mReadFileThread == nullptr) {
|
if (mAbortFlag || mReadFileThread == nullptr) {
|
||||||
SendAbortRequest();
|
SendAbortRequest();
|
||||||
} else {
|
} else {
|
||||||
// Sending system message "bluetooth-opp-update-progress" every 50kb,
|
|
||||||
if (kUpdateProgressBase * sUpdateProgressCounter < sSentFileLength) {
|
if (kUpdateProgressBase * sUpdateProgressCounter < sSentFileLength) {
|
||||||
UpdateProgress(sSentFileLength, sFileLength);
|
UpdateProgress(mConnectedDeviceAddress, false,
|
||||||
|
sSentFileLength, sFileLength);
|
||||||
++sUpdateProgressCounter;
|
++sUpdateProgressCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +295,8 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
|
|||||||
// FIXME: Needs error handling here
|
// FIXME: Needs error handling here
|
||||||
NS_WARNING("[OPP] PutFinal failed");
|
NS_WARNING("[OPP] PutFinal failed");
|
||||||
} else {
|
} else {
|
||||||
FileTransferComplete(true, false, sFileName, sSentFileLength);
|
FileTransferComplete(mConnectedDeviceAddress, true, false, sFileName,
|
||||||
|
sSentFileLength, sContentType);
|
||||||
SendDisconnectRequest();
|
SendDisconnectRequest();
|
||||||
}
|
}
|
||||||
} else if (mLastCommand == ObexRequestCode::Abort) {
|
} else if (mLastCommand == ObexRequestCode::Abort) {
|
||||||
@ -288,7 +304,8 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
|
|||||||
NS_WARNING("[OPP] Abort failed");
|
NS_WARNING("[OPP] Abort failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
FileTransferComplete(false, false, sFileName, sSentFileLength);
|
FileTransferComplete(mConnectedDeviceAddress, false, false, sFileName,
|
||||||
|
sSentFileLength, sContentType);
|
||||||
SendDisconnectRequest();
|
SendDisconnectRequest();
|
||||||
} else {
|
} else {
|
||||||
// Remote request or unknown mLastCommand
|
// Remote request or unknown mLastCommand
|
||||||
@ -517,16 +534,22 @@ BluetoothOppManager::ReplyToPut(bool aFinal)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BluetoothOppManager::FileTransferComplete(bool aSuccess,
|
BluetoothOppManager::FileTransferComplete(const nsString& aDeviceAddress,
|
||||||
|
bool aSuccess,
|
||||||
bool aReceived,
|
bool aReceived,
|
||||||
const nsString& aFileName,
|
const nsString& aFileName,
|
||||||
uint32_t aFileLength)
|
uint32_t aFileLength,
|
||||||
|
const nsString& aContentType)
|
||||||
{
|
{
|
||||||
nsString type, name;
|
nsString type, name;
|
||||||
BluetoothValue v;
|
BluetoothValue v;
|
||||||
InfallibleTArray<BluetoothNamedValue> parameters;
|
InfallibleTArray<BluetoothNamedValue> parameters;
|
||||||
type.AssignLiteral("bluetooth-opp-transfer-complete");
|
type.AssignLiteral("bluetooth-opp-transfer-complete");
|
||||||
|
|
||||||
|
name.AssignLiteral("address");
|
||||||
|
v = aDeviceAddress;
|
||||||
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
|
|
||||||
name.AssignLiteral("success");
|
name.AssignLiteral("success");
|
||||||
v = aSuccess;
|
v = aSuccess;
|
||||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
@ -535,14 +558,18 @@ BluetoothOppManager::FileTransferComplete(bool aSuccess,
|
|||||||
v = aReceived;
|
v = aReceived;
|
||||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
|
|
||||||
name.AssignLiteral("filename");
|
name.AssignLiteral("fileName");
|
||||||
v = aFileName;
|
v = aFileName;
|
||||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
|
|
||||||
name.AssignLiteral("filelength");
|
name.AssignLiteral("fileLength");
|
||||||
v = aFileLength;
|
v = aFileLength;
|
||||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
|
|
||||||
|
name.AssignLiteral("contentType");
|
||||||
|
v = aContentType;
|
||||||
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
|
|
||||||
if (!BroadcastSystemMessage(type, parameters)) {
|
if (!BroadcastSystemMessage(type, parameters)) {
|
||||||
NS_WARNING("Failed to broadcast [bluetooth-opp-transfer-complete]");
|
NS_WARNING("Failed to broadcast [bluetooth-opp-transfer-complete]");
|
||||||
return;
|
return;
|
||||||
@ -550,18 +577,67 @@ BluetoothOppManager::FileTransferComplete(bool aSuccess,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BluetoothOppManager::UpdateProgress(uint32_t aProcessed, uint32_t aFileLength)
|
BluetoothOppManager::StartFileTransfer(const nsString& aDeviceAddress,
|
||||||
|
bool aReceived,
|
||||||
|
const nsString& aFileName,
|
||||||
|
uint32_t aFileLength,
|
||||||
|
const nsString& aContentType)
|
||||||
|
{
|
||||||
|
nsString type, name;
|
||||||
|
BluetoothValue v;
|
||||||
|
InfallibleTArray<BluetoothNamedValue> parameters;
|
||||||
|
type.AssignLiteral("bluetooth-opp-transfer-start");
|
||||||
|
|
||||||
|
name.AssignLiteral("address");
|
||||||
|
v = aDeviceAddress;
|
||||||
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
|
|
||||||
|
name.AssignLiteral("received");
|
||||||
|
v = aReceived;
|
||||||
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
|
|
||||||
|
name.AssignLiteral("fileName");
|
||||||
|
v = aFileName;
|
||||||
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
|
|
||||||
|
name.AssignLiteral("fileLength");
|
||||||
|
v = aFileLength;
|
||||||
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
|
|
||||||
|
name.AssignLiteral("contentType");
|
||||||
|
v = aContentType;
|
||||||
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
|
|
||||||
|
if (!BroadcastSystemMessage(type, parameters)) {
|
||||||
|
NS_WARNING("Failed to broadcast [bluetooth-opp-transfer-start]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothOppManager::UpdateProgress(const nsString& aDeviceAddress,
|
||||||
|
bool aReceived,
|
||||||
|
uint32_t aProcessedLength,
|
||||||
|
uint32_t aFileLength)
|
||||||
{
|
{
|
||||||
nsString type, name;
|
nsString type, name;
|
||||||
BluetoothValue v;
|
BluetoothValue v;
|
||||||
InfallibleTArray<BluetoothNamedValue> parameters;
|
InfallibleTArray<BluetoothNamedValue> parameters;
|
||||||
type.AssignLiteral("bluetooth-opp-update-progress");
|
type.AssignLiteral("bluetooth-opp-update-progress");
|
||||||
|
|
||||||
name.AssignLiteral("processed");
|
name.AssignLiteral("address");
|
||||||
v = aProcessed;
|
v = aDeviceAddress;
|
||||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
|
|
||||||
name.AssignLiteral("filelength");
|
name.AssignLiteral("received");
|
||||||
|
v = aReceived;
|
||||||
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
|
|
||||||
|
name.AssignLiteral("processedLength");
|
||||||
|
v = aProcessedLength;
|
||||||
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
|
|
||||||
|
name.AssignLiteral("fileLength");
|
||||||
v = aFileLength;
|
v = aFileLength;
|
||||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
|
|
||||||
|
@ -60,9 +60,21 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
BluetoothOppManager();
|
BluetoothOppManager();
|
||||||
void FileTransferComplete(bool aSuccess, bool aReceived,
|
void StartFileTransfer(const nsString& aDeviceAddress,
|
||||||
const nsString& aFileName, uint32_t aFileLength);
|
bool aReceived,
|
||||||
void UpdateProgress(uint32_t aProcessed, uint32_t aFileLength);
|
const nsString& aFileName,
|
||||||
|
uint32_t aFileLength,
|
||||||
|
const nsString& aContentType);
|
||||||
|
void FileTransferComplete(const nsString& aDeviceAddress,
|
||||||
|
bool aSuccess,
|
||||||
|
bool aReceived,
|
||||||
|
const nsString& aFileName,
|
||||||
|
uint32_t aFileLength,
|
||||||
|
const nsString& aContentType);
|
||||||
|
void UpdateProgress(const nsString& aDeviceAddress,
|
||||||
|
bool aReceived,
|
||||||
|
uint32_t aProcessedLength,
|
||||||
|
uint32_t aFileLength);
|
||||||
void ReplyToConnect();
|
void ReplyToConnect();
|
||||||
void ReplyToDisconnect();
|
void ReplyToDisconnect();
|
||||||
void ReplyToPut(bool aFinal);
|
void ReplyToPut(bool aFinal);
|
||||||
@ -77,6 +89,7 @@ private:
|
|||||||
int mRemoteMaxPacketLength;
|
int mRemoteMaxPacketLength;
|
||||||
bool mAbortFlag;
|
bool mAbortFlag;
|
||||||
int mPacketLeftLength;
|
int mPacketLeftLength;
|
||||||
|
nsString mConnectedDeviceAddress;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMBlob> mBlob;
|
nsCOMPtr<nsIDOMBlob> mBlob;
|
||||||
nsCOMPtr<nsIThread> mReadFileThread;
|
nsCOMPtr<nsIThread> mReadFileThread;
|
||||||
|
@ -1183,8 +1183,7 @@ nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest *request,
|
|||||||
PR_ParseTimeString(lastModified.get(), true, &time64); //convert string time to integer time
|
PR_ParseTimeString(lastModified.get(), true, &time64); //convert string time to integer time
|
||||||
|
|
||||||
// Convert PRTime to unix-style time_t, i.e. seconds since the epoch
|
// Convert PRTime to unix-style time_t, i.e. seconds since the epoch
|
||||||
double fpTime;
|
double fpTime = double(time64);
|
||||||
LL_L2D(fpTime, time64);
|
|
||||||
mModified = (uint32_t)(fpTime * 1e-6 + 0.5);
|
mModified = (uint32_t)(fpTime * 1e-6 + 0.5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -418,13 +418,13 @@ nsresult nsAutoConfig::evaluateLocalFile(nsIFile *file)
|
|||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
int64_t fileSize;
|
int64_t fileSize;
|
||||||
uint32_t fs, amt=0;
|
|
||||||
file->GetFileSize(&fileSize);
|
file->GetFileSize(&fileSize);
|
||||||
LL_L2UI(fs, fileSize); // Converting 64 bit structure to unsigned int
|
uint32_t fs = fileSize; // Converting 64 bit structure to unsigned int
|
||||||
char *buf = (char *)PR_Malloc(fs * sizeof(char));
|
char *buf = (char *)PR_Malloc(fs * sizeof(char));
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
uint32_t amt = 0;
|
||||||
rv = inStr->Read(buf, fs, &amt);
|
rv = inStr->Read(buf, fs, &amt);
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
EvaluateAdminConfigScript(buf, fs, nullptr, false,
|
EvaluateAdminConfigScript(buf, fs, nullptr, false,
|
||||||
|
@ -499,7 +499,6 @@ LayerManagerD3D10::CreateDrawTarget(const IntSize &aSize,
|
|||||||
{
|
{
|
||||||
if ((aFormat != FORMAT_B8G8R8A8 &&
|
if ((aFormat != FORMAT_B8G8R8A8 &&
|
||||||
aFormat != FORMAT_B8G8R8X8) ||
|
aFormat != FORMAT_B8G8R8X8) ||
|
||||||
!gfxPlatform::GetPlatform()->SupportsAzureCanvas() ||
|
|
||||||
gfxPlatform::GetPlatform()->GetPreferredCanvasBackend() != BACKEND_DIRECT2D) {
|
gfxPlatform::GetPlatform()->GetPreferredCanvasBackend() != BACKEND_DIRECT2D) {
|
||||||
return LayerManager::CreateDrawTarget(aSize, aFormat);
|
return LayerManager::CreateDrawTarget(aSize, aFormat);
|
||||||
}
|
}
|
||||||
|
@ -706,10 +706,6 @@ gfxPlatform::GetThebesSurfaceForDrawTarget(DrawTarget *aTarget)
|
|||||||
RefPtr<DrawTarget>
|
RefPtr<DrawTarget>
|
||||||
gfxPlatform::CreateDrawTargetForBackend(BackendType aBackend, const IntSize& aSize, SurfaceFormat aFormat)
|
gfxPlatform::CreateDrawTargetForBackend(BackendType aBackend, const IntSize& aSize, SurfaceFormat aFormat)
|
||||||
{
|
{
|
||||||
if (!SupportsAzureCanvas()) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// There is a bunch of knowledge in the gfxPlatform heirarchy about how to
|
// There is a bunch of knowledge in the gfxPlatform heirarchy about how to
|
||||||
// create the best offscreen surface for the current system and situation. We
|
// create the best offscreen surface for the current system and situation. We
|
||||||
// can easily take advantage of this for the Cairo backend, so that's what we
|
// can easily take advantage of this for the Cairo backend, so that's what we
|
||||||
@ -734,10 +730,7 @@ gfxPlatform::CreateDrawTargetForBackend(BackendType aBackend, const IntSize& aSi
|
|||||||
RefPtr<DrawTarget>
|
RefPtr<DrawTarget>
|
||||||
gfxPlatform::CreateOffscreenDrawTarget(const IntSize& aSize, SurfaceFormat aFormat)
|
gfxPlatform::CreateOffscreenDrawTarget(const IntSize& aSize, SurfaceFormat aFormat)
|
||||||
{
|
{
|
||||||
if (!SupportsAzureCanvas()) {
|
NS_ASSERTION(mPreferredCanvasBackend, "No backend.");
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
RefPtr<DrawTarget> target = CreateDrawTargetForBackend(mPreferredCanvasBackend, aSize, aFormat);
|
RefPtr<DrawTarget> target = CreateDrawTargetForBackend(mPreferredCanvasBackend, aSize, aFormat);
|
||||||
if (target ||
|
if (target ||
|
||||||
mFallbackCanvasBackend == BACKEND_NONE) {
|
mFallbackCanvasBackend == BACKEND_NONE) {
|
||||||
@ -751,20 +744,10 @@ gfxPlatform::CreateOffscreenDrawTarget(const IntSize& aSize, SurfaceFormat aForm
|
|||||||
RefPtr<DrawTarget>
|
RefPtr<DrawTarget>
|
||||||
gfxPlatform::CreateDrawTargetForData(unsigned char* aData, const IntSize& aSize, int32_t aStride, SurfaceFormat aFormat)
|
gfxPlatform::CreateDrawTargetForData(unsigned char* aData, const IntSize& aSize, int32_t aStride, SurfaceFormat aFormat)
|
||||||
{
|
{
|
||||||
if (!SupportsAzureCanvas()) {
|
NS_ASSERTION(mPreferredCanvasBackend, "No backend.");
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return Factory::CreateDrawTargetForData(mPreferredCanvasBackend, aData, aSize, aStride, aFormat);
|
return Factory::CreateDrawTargetForData(mPreferredCanvasBackend, aData, aSize, aStride, aFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
gfxPlatform::SupportsAzureCanvas()
|
|
||||||
{
|
|
||||||
NS_ASSERTION(mFallbackCanvasBackend == BACKEND_NONE || mPreferredCanvasBackend != BACKEND_NONE,
|
|
||||||
"fallback backend with no preferred backend");
|
|
||||||
return mPreferredCanvasBackend != BACKEND_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */ BackendType
|
/* static */ BackendType
|
||||||
gfxPlatform::BackendTypeForName(const nsCString& aName)
|
gfxPlatform::BackendTypeForName(const nsCString& aName)
|
||||||
{
|
{
|
||||||
@ -1203,6 +1186,9 @@ void
|
|||||||
gfxPlatform::InitBackendPrefs(uint32_t aCanvasBitmask, uint32_t aContentBitmask)
|
gfxPlatform::InitBackendPrefs(uint32_t aCanvasBitmask, uint32_t aContentBitmask)
|
||||||
{
|
{
|
||||||
mPreferredCanvasBackend = GetCanvasBackendPref(aCanvasBitmask);
|
mPreferredCanvasBackend = GetCanvasBackendPref(aCanvasBitmask);
|
||||||
|
if (!mPreferredCanvasBackend) {
|
||||||
|
mPreferredCanvasBackend = BACKEND_CAIRO;
|
||||||
|
}
|
||||||
mFallbackCanvasBackend = GetCanvasBackendPref(aCanvasBitmask & ~(1 << mPreferredCanvasBackend));
|
mFallbackCanvasBackend = GetCanvasBackendPref(aCanvasBitmask & ~(1 << mPreferredCanvasBackend));
|
||||||
mContentBackend = GetContentBackendPref(aContentBitmask);
|
mContentBackend = GetContentBackendPref(aContentBitmask);
|
||||||
}
|
}
|
||||||
@ -1210,7 +1196,7 @@ gfxPlatform::InitBackendPrefs(uint32_t aCanvasBitmask, uint32_t aContentBitmask)
|
|||||||
/* static */ BackendType
|
/* static */ BackendType
|
||||||
gfxPlatform::GetCanvasBackendPref(uint32_t aBackendBitmask)
|
gfxPlatform::GetCanvasBackendPref(uint32_t aBackendBitmask)
|
||||||
{
|
{
|
||||||
return GetBackendPref("gfx.canvas.azure.enabled", "gfx.canvas.azure.backends", aBackendBitmask);
|
return GetBackendPref(nullptr, "gfx.canvas.azure.backends", aBackendBitmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ BackendType
|
/* static */ BackendType
|
||||||
@ -1222,7 +1208,8 @@ gfxPlatform::GetContentBackendPref(uint32_t aBackendBitmask)
|
|||||||
/* static */ BackendType
|
/* static */ BackendType
|
||||||
gfxPlatform::GetBackendPref(const char* aEnabledPrefName, const char* aBackendPrefName, uint32_t aBackendBitmask)
|
gfxPlatform::GetBackendPref(const char* aEnabledPrefName, const char* aBackendPrefName, uint32_t aBackendBitmask)
|
||||||
{
|
{
|
||||||
if (!Preferences::GetBool(aEnabledPrefName, false)) {
|
if (aEnabledPrefName &&
|
||||||
|
!Preferences::GetBool(aEnabledPrefName, false)) {
|
||||||
return BACKEND_NONE;
|
return BACKEND_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +198,6 @@ public:
|
|||||||
CreateDrawTargetForData(unsigned char* aData, const mozilla::gfx::IntSize& aSize,
|
CreateDrawTargetForData(unsigned char* aData, const mozilla::gfx::IntSize& aSize,
|
||||||
int32_t aStride, mozilla::gfx::SurfaceFormat aFormat);
|
int32_t aStride, mozilla::gfx::SurfaceFormat aFormat);
|
||||||
|
|
||||||
bool SupportsAzureCanvas();
|
|
||||||
bool SupportsAzureContent() {
|
bool SupportsAzureContent() {
|
||||||
return GetContentBackend() != mozilla::gfx::BACKEND_NONE;
|
return GetContentBackend() != mozilla::gfx::BACKEND_NONE;
|
||||||
}
|
}
|
||||||
@ -494,9 +493,10 @@ protected:
|
|||||||
static mozilla::gfx::BackendType GetContentBackendPref(uint32_t aBackendBitmask);
|
static mozilla::gfx::BackendType GetContentBackendPref(uint32_t aBackendBitmask);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the aEnabledPrefName pref and returns BACKEND_NONE if the pref is
|
* If aEnabledPrefName is non-null, checks the aEnabledPrefName pref and
|
||||||
* not enabled. Otherwise it will return the first backend named in
|
* returns BACKEND_NONE if the pref is not enabled.
|
||||||
* aBackendPrefName allowed by aBackendBitmask, a bitmask of backend types.
|
* Otherwise it will return the first backend named in aBackendPrefName
|
||||||
|
* allowed by aBackendBitmask, a bitmask of backend types.
|
||||||
*/
|
*/
|
||||||
static mozilla::gfx::BackendType GetBackendPref(const char* aEnabledPrefName,
|
static mozilla::gfx::BackendType GetBackendPref(const char* aEnabledPrefName,
|
||||||
const char* aBackendPrefName,
|
const char* aBackendPrefName,
|
||||||
|
@ -458,8 +458,8 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Feed the actual image data (not including headers) into the BMP decoder
|
// Feed the actual image data (not including headers) into the BMP decoder
|
||||||
int32_t bmpDataOffset = mDirEntry.mImageOffset + BITMAPINFOSIZE;
|
uint32_t bmpDataOffset = mDirEntry.mImageOffset + BITMAPINFOSIZE;
|
||||||
int32_t bmpDataEnd = mDirEntry.mImageOffset + BITMAPINFOSIZE +
|
uint32_t bmpDataEnd = mDirEntry.mImageOffset + BITMAPINFOSIZE +
|
||||||
static_cast<nsBMPDecoder*>(mContainedDecoder.get())->GetCompressedImageSize() +
|
static_cast<nsBMPDecoder*>(mContainedDecoder.get())->GetCompressedImageSize() +
|
||||||
4 * numColors;
|
4 * numColors;
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ nsICOEncoder::ParseOptions(const nsAString& aOptions, uint32_t* bpp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For each name/value pair in the set
|
// For each name/value pair in the set
|
||||||
for (int i = 0; i < nameValuePairs.Length(); ++i) {
|
for (unsigned i = 0; i < nameValuePairs.Length(); ++i) {
|
||||||
|
|
||||||
// Split the name value pair [0] = name, [1] = value
|
// Split the name value pair [0] = name, [1] = value
|
||||||
nsTArray<nsCString> nameValuePair;
|
nsTArray<nsCString> nameValuePair;
|
||||||
|
@ -23,8 +23,10 @@ XPIDLSRCS = \
|
|||||||
imgIDecoderObserver.idl \
|
imgIDecoderObserver.idl \
|
||||||
imgIEncoder.idl \
|
imgIEncoder.idl \
|
||||||
imgILoader.idl \
|
imgILoader.idl \
|
||||||
|
imgINotificationObserver.idl \
|
||||||
imgIOnloadBlocker.idl \
|
imgIOnloadBlocker.idl \
|
||||||
imgIRequest.idl \
|
imgIRequest.idl \
|
||||||
|
imgIScriptedNotificationObserver.idl \
|
||||||
imgITools.idl \
|
imgITools.idl \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include "nsRect.h"
|
#include "nsRect.h"
|
||||||
%}
|
%}
|
||||||
|
|
||||||
interface imgIContainer;
|
|
||||||
interface imgIRequest;
|
interface imgIRequest;
|
||||||
[ptr] native nsIntRect(nsIntRect);
|
[ptr] native nsIntRect(nsIntRect);
|
||||||
|
|
||||||
@ -20,10 +19,8 @@ interface imgIRequest;
|
|||||||
* @author Stuart Parmenter <pavlov@netscape.com>
|
* @author Stuart Parmenter <pavlov@netscape.com>
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(f01efdb3-4b20-4313-a636-a2aa01a4ef5d)]
|
[scriptable, uuid(f4aaf410-e88f-4036-b91c-610c9c11d825)]
|
||||||
interface imgIContainerObserver : nsISupports
|
interface imgIContainerObserver : nsISupports
|
||||||
{
|
{
|
||||||
[noscript] void frameChanged(in imgIRequest aRequest,
|
[noscript] void frameChanged([const] in nsIntRect aDirtyRect);
|
||||||
in imgIContainer aContainer,
|
|
||||||
[const] in nsIntRect aDirtyRect);
|
|
||||||
};
|
};
|
||||||
|
@ -43,7 +43,7 @@ interface imgIContainer;
|
|||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @see imagelib2
|
* @see imagelib2
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(5ca71b89-1a2f-475f-881d-d76c1531c4c8)]
|
[scriptable, uuid(0089cf0c-210c-4b44-9ab0-8099b32bcf64)]
|
||||||
interface imgIDecoderObserver : imgIContainerObserver
|
interface imgIDecoderObserver : imgIContainerObserver
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -53,7 +53,7 @@ interface imgIDecoderObserver : imgIContainerObserver
|
|||||||
* (used only for observers of imgIRequest objects, which are nsIRequests,
|
* (used only for observers of imgIRequest objects, which are nsIRequests,
|
||||||
* not imgIDecoder objects)
|
* not imgIDecoder objects)
|
||||||
*/
|
*/
|
||||||
void onStartRequest(in imgIRequest aRequest);
|
void onStartRequest();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode notification.
|
* Decode notification.
|
||||||
@ -62,7 +62,7 @@ interface imgIDecoderObserver : imgIContainerObserver
|
|||||||
* "header-only" decodes used by decode-on-draw to parse the width/height
|
* "header-only" decodes used by decode-on-draw to parse the width/height
|
||||||
* out of the image. Thus, it is a decode notification only.
|
* out of the image. Thus, it is a decode notification only.
|
||||||
*/
|
*/
|
||||||
void onStartDecode(in imgIRequest aRequest);
|
void onStartDecode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load notification.
|
* Load notification.
|
||||||
@ -72,54 +72,34 @@ interface imgIDecoderObserver : imgIContainerObserver
|
|||||||
* called, the size has been set on the container and STATUS_SIZE_AVAILABLE
|
* called, the size has been set on the container and STATUS_SIZE_AVAILABLE
|
||||||
* has been set on the associated imgRequest.
|
* has been set on the associated imgRequest.
|
||||||
*/
|
*/
|
||||||
void onStartContainer(in imgIRequest aRequest, in imgIContainer aContainer);
|
void onStartContainer();
|
||||||
|
|
||||||
/**
|
|
||||||
* Decode notification.
|
|
||||||
*
|
|
||||||
* called when each frame is created.
|
|
||||||
*/
|
|
||||||
void onStartFrame(in imgIRequest aRequest, in unsigned long aFrame);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode notification.
|
* Decode notification.
|
||||||
*
|
*
|
||||||
* called when there is more to paint.
|
* called when there is more to paint.
|
||||||
*/
|
*/
|
||||||
[noscript] void onDataAvailable(in imgIRequest aRequest, in boolean aCurrentFrame, [const] in nsIntRect aRect);
|
[noscript] void onDataAvailable([const] in nsIntRect aRect);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode notification.
|
* Decode notification.
|
||||||
*
|
*
|
||||||
* called when a frame is finished decoding.
|
* called when a frame is finished decoding.
|
||||||
*/
|
*/
|
||||||
void onStopFrame(in imgIRequest aRequest, in unsigned long aFrame);
|
void onStopFrame();
|
||||||
|
|
||||||
/**
|
|
||||||
* Do not implement this. It is useless and going away.
|
|
||||||
*/
|
|
||||||
void onStopContainer(in imgIRequest aRequest, in imgIContainer aContainer);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notification for when an image is known to be animated. This should be
|
* Notification for when an image is known to be animated. This should be
|
||||||
* fired at the earliest possible time.
|
* fired at the earliest possible time.
|
||||||
*/
|
*/
|
||||||
void onImageIsAnimated(in imgIRequest aRequest);
|
void onImageIsAnimated();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In theory a decode notification, but currently a load notification.
|
* Decode notification.
|
||||||
*
|
*
|
||||||
* Ideally this would be called when the decode is complete. Unfortunately,
|
* Called when all decoding has terminated.
|
||||||
* this is currently the only way to signal decoding errors to consumers,
|
|
||||||
* and the only decoding errors that consumers care about (indeed, the only
|
|
||||||
* ones that they're prepared to hear about) are failures to instantiate the
|
|
||||||
* decoder (<img src="foo.html"> for example). Thus, currently this is just
|
|
||||||
* a companion to onStopDecode to signal success or failure. This will be
|
|
||||||
* revisited in bug 505385. If you're thinking of doing something new with
|
|
||||||
* this, please talk to bholley first.
|
|
||||||
*/
|
*/
|
||||||
void onStopDecode(in imgIRequest aRequest, in nsresult status,
|
void onStopDecode(in nsresult status);
|
||||||
in wstring statusArg);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load notification.
|
* Load notification.
|
||||||
@ -128,13 +108,13 @@ interface imgIDecoderObserver : imgIContainerObserver
|
|||||||
* (used only for observers of imgIRequest objects, which are nsIRequests,
|
* (used only for observers of imgIRequest objects, which are nsIRequests,
|
||||||
* not imgIDecoder objects)
|
* not imgIDecoder objects)
|
||||||
*/
|
*/
|
||||||
void onStopRequest(in imgIRequest aRequest, in boolean aIsLastPart);
|
void onStopRequest(in boolean aIsLastPart);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the decoded image data is discarded. This means that the frames
|
* Called when the decoded image data is discarded. This means that the frames
|
||||||
* no longer exist in decoded form, and any attempt to access or draw the
|
* no longer exist in decoded form, and any attempt to access or draw the
|
||||||
* image will initiate a new series of progressive decode notifications.
|
* image will initiate a new series of progressive decode notifications.
|
||||||
*/
|
*/
|
||||||
void onDiscard(in imgIRequest aRequest);
|
void onDiscard();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "nsISupports.idl"
|
#include "nsISupports.idl"
|
||||||
|
|
||||||
interface imgIDecoderObserver;
|
interface imgINotificationObserver;
|
||||||
interface imgIRequest;
|
interface imgIRequest;
|
||||||
|
|
||||||
interface nsIChannel;
|
interface nsIChannel;
|
||||||
@ -61,7 +61,7 @@ interface imgILoader : nsISupports
|
|||||||
in nsIURI aReferrerURI,
|
in nsIURI aReferrerURI,
|
||||||
in nsIPrincipal aLoadingPrincipal,
|
in nsIPrincipal aLoadingPrincipal,
|
||||||
in nsILoadGroup aLoadGroup,
|
in nsILoadGroup aLoadGroup,
|
||||||
in imgIDecoderObserver aObserver,
|
in imgINotificationObserver aObserver,
|
||||||
in nsISupports aCX,
|
in nsISupports aCX,
|
||||||
in nsLoadFlags aLoadFlags,
|
in nsLoadFlags aLoadFlags,
|
||||||
in nsISupports cacheKey,
|
in nsISupports cacheKey,
|
||||||
@ -86,7 +86,7 @@ interface imgILoader : nsISupports
|
|||||||
* make sure to Cancel() the resulting request before the observer goes away.
|
* make sure to Cancel() the resulting request before the observer goes away.
|
||||||
*/
|
*/
|
||||||
imgIRequest loadImageWithChannel(in nsIChannel aChannel,
|
imgIRequest loadImageWithChannel(in nsIChannel aChannel,
|
||||||
in imgIDecoderObserver aObserver,
|
in imgINotificationObserver aObserver,
|
||||||
in nsISupports cx,
|
in nsISupports cx,
|
||||||
out nsIStreamListener aListener);
|
out nsIStreamListener aListener);
|
||||||
};
|
};
|
||||||
|
29
image/public/imgINotificationObserver.idl
Normal file
29
image/public/imgINotificationObserver.idl
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "nsISupports.idl"
|
||||||
|
|
||||||
|
interface imgIRequest;
|
||||||
|
|
||||||
|
%{C++
|
||||||
|
#include "nsRect.h"
|
||||||
|
%}
|
||||||
|
|
||||||
|
[ptr] native nsIntRect(nsIntRect);
|
||||||
|
|
||||||
|
[scriptable, builtinclass, uuid(90b3d21c-317d-4d96-93c0-12add64a26bf)]
|
||||||
|
interface imgINotificationObserver : nsISupports
|
||||||
|
{
|
||||||
|
const long SIZE_AVAILABLE = 1;
|
||||||
|
const long FRAME_UPDATE = 2;
|
||||||
|
const long FRAME_COMPLETE = 3;
|
||||||
|
const long LOAD_COMPLETE = 4;
|
||||||
|
const long DECODE_COMPLETE = 5;
|
||||||
|
const long DISCARD = 6;
|
||||||
|
const long IS_ANIMATED = 7;
|
||||||
|
|
||||||
|
[noscript] void notify(in imgIRequest aProxy, in long aType, [const] in nsIntRect aRect);
|
||||||
|
};
|
@ -8,7 +8,7 @@
|
|||||||
#include "nsIRequest.idl"
|
#include "nsIRequest.idl"
|
||||||
|
|
||||||
interface imgIContainer;
|
interface imgIContainer;
|
||||||
interface imgIDecoderObserver;
|
interface imgINotificationObserver;
|
||||||
interface nsIURI;
|
interface nsIURI;
|
||||||
interface nsIPrincipal;
|
interface nsIPrincipal;
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ interface nsIPrincipal;
|
|||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @see imagelib2
|
* @see imagelib2
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(a5a785a8-9881-11e1-aaff-001fbc092072)]
|
[scriptable, uuid(3ea9fc87-2e97-45bf-b373-d1dd253a0b5e)]
|
||||||
interface imgIRequest : nsIRequest
|
interface imgIRequest : nsIRequest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -82,7 +82,7 @@ interface imgIRequest : nsIRequest
|
|||||||
*/
|
*/
|
||||||
readonly attribute nsIURI URI;
|
readonly attribute nsIURI URI;
|
||||||
|
|
||||||
readonly attribute imgIDecoderObserver decoderObserver;
|
readonly attribute imgINotificationObserver notificationObserver;
|
||||||
|
|
||||||
readonly attribute string mimeType;
|
readonly attribute string mimeType;
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ interface imgIRequest : nsIRequest
|
|||||||
* call returns) with all the notifications that have already been dispatched
|
* call returns) with all the notifications that have already been dispatched
|
||||||
* for this image load.
|
* for this image load.
|
||||||
*/
|
*/
|
||||||
imgIRequest clone(in imgIDecoderObserver aObserver);
|
imgIRequest clone(in imgINotificationObserver aObserver);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The principal gotten from the channel the image was loaded from.
|
* The principal gotten from the channel the image was loaded from.
|
||||||
|
21
image/public/imgIScriptedNotificationObserver.idl
Normal file
21
image/public/imgIScriptedNotificationObserver.idl
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "nsISupports.idl"
|
||||||
|
|
||||||
|
interface imgIRequest;
|
||||||
|
|
||||||
|
[scriptable, uuid(10be55b3-2029-41a7-a975-538efed250ed)]
|
||||||
|
interface imgIScriptedNotificationObserver : nsISupports
|
||||||
|
{
|
||||||
|
void sizeAvailable(in imgIRequest aRequest);
|
||||||
|
void frameUpdate(in imgIRequest aRequest);
|
||||||
|
void frameComplete(in imgIRequest aRequest);
|
||||||
|
void loadComplete(in imgIRequest aRequest);
|
||||||
|
void decodeComplete(in imgIRequest aRequest);
|
||||||
|
void discard(in imgIRequest aRequest);
|
||||||
|
void isAnimated(in imgIRequest aRequest);
|
||||||
|
};
|
@ -11,8 +11,10 @@ interface imgIContainer;
|
|||||||
interface imgILoader;
|
interface imgILoader;
|
||||||
interface imgICache;
|
interface imgICache;
|
||||||
interface nsIDOMDocument;
|
interface nsIDOMDocument;
|
||||||
|
interface imgIScriptedNotificationObserver;
|
||||||
|
interface imgINotificationObserver;
|
||||||
|
|
||||||
[scriptable, uuid(53dd1cbe-cb9f-4d9e-8104-1ab72851c88e)]
|
[scriptable, uuid(98bd5bf9-87eb-4d92-81b1-4cd10c64f7b2)]
|
||||||
interface imgITools : nsISupports
|
interface imgITools : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -123,4 +125,12 @@ interface imgITools : nsISupports
|
|||||||
in long aWidth,
|
in long aWidth,
|
||||||
in long aHeight,
|
in long aHeight,
|
||||||
[optional] in AString outputOptions);
|
[optional] in AString outputOptions);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a wrapper around a scripted notification observer (ordinarily
|
||||||
|
* imgINotificationObserver cannot be implemented from scripts).
|
||||||
|
*
|
||||||
|
* @param aObserver The scripted observer to wrap
|
||||||
|
*/
|
||||||
|
imgINotificationObserver createScriptedObserver(in imgIScriptedNotificationObserver aObserver);
|
||||||
};
|
};
|
||||||
|
@ -45,7 +45,7 @@ Decoder::Init()
|
|||||||
|
|
||||||
// Fire OnStartDecode at init time to support bug 512435
|
// Fire OnStartDecode at init time to support bug 512435
|
||||||
if (!IsSizeDecode() && mObserver)
|
if (!IsSizeDecode() && mObserver)
|
||||||
mObserver->OnStartDecode(nullptr);
|
mObserver->OnStartDecode();
|
||||||
|
|
||||||
// Implementation-specific initialization
|
// Implementation-specific initialization
|
||||||
InitInternal();
|
InitInternal();
|
||||||
@ -124,8 +124,7 @@ Decoder::Finish()
|
|||||||
|
|
||||||
// Fire teardown notifications
|
// Fire teardown notifications
|
||||||
if (mObserver) {
|
if (mObserver) {
|
||||||
mObserver->OnStopContainer(nullptr, &mImage);
|
mObserver->OnStopDecode(salvage ? NS_OK : NS_ERROR_FAILURE);
|
||||||
mObserver->OnStopDecode(nullptr, salvage ? NS_OK : NS_ERROR_FAILURE, nullptr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,8 +166,7 @@ Decoder::FlushInvalidations()
|
|||||||
mInvalidRect.Inflate(1);
|
mInvalidRect.Inflate(1);
|
||||||
mInvalidRect = mInvalidRect.Intersect(mImageBound);
|
mInvalidRect = mInvalidRect.Intersect(mImageBound);
|
||||||
#endif
|
#endif
|
||||||
bool isCurrentFrame = mImage.GetCurrentFrameIndex() == (mFrameCount - 1);
|
mObserver->OnDataAvailable(&mInvalidRect);
|
||||||
mObserver->OnDataAvailable(nullptr, isCurrentFrame, &mInvalidRect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the invalidation rectangle
|
// Clear the invalidation rectangle
|
||||||
@ -199,7 +197,7 @@ Decoder::PostSize(int32_t aWidth, int32_t aHeight)
|
|||||||
|
|
||||||
// Notify the observer
|
// Notify the observer
|
||||||
if (mObserver)
|
if (mObserver)
|
||||||
mObserver->OnStartContainer(nullptr, &mImage);
|
mObserver->OnStartContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -222,10 +220,6 @@ Decoder::PostFrameStart()
|
|||||||
// reported by the Image.
|
// reported by the Image.
|
||||||
NS_ABORT_IF_FALSE(mFrameCount == mImage.GetNumFrames(),
|
NS_ABORT_IF_FALSE(mFrameCount == mImage.GetNumFrames(),
|
||||||
"Decoder frame count doesn't match image's!");
|
"Decoder frame count doesn't match image's!");
|
||||||
|
|
||||||
// Fire notification
|
|
||||||
if (mObserver)
|
|
||||||
mObserver->OnStartFrame(nullptr, mFrameCount - 1); // frame # is zero-indexed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -242,10 +236,10 @@ Decoder::PostFrameStop()
|
|||||||
|
|
||||||
// Fire notifications
|
// Fire notifications
|
||||||
if (mObserver) {
|
if (mObserver) {
|
||||||
mObserver->OnStopFrame(nullptr, mFrameCount - 1); // frame # is zero-indexed
|
mObserver->OnStopFrame();
|
||||||
if (mFrameCount > 1 && !mIsAnimated) {
|
if (mFrameCount > 1 && !mIsAnimated) {
|
||||||
mIsAnimated = true;
|
mIsAnimated = true;
|
||||||
mObserver->OnImageIsAnimated(nullptr);
|
mObserver->OnImageIsAnimated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -278,8 +272,7 @@ Decoder::PostDecodeDone()
|
|||||||
// Notify
|
// Notify
|
||||||
mImage.DecodingComplete();
|
mImage.DecodingComplete();
|
||||||
if (mObserver) {
|
if (mObserver) {
|
||||||
mObserver->OnStopContainer(nullptr, &mImage);
|
mObserver->OnStopDecode(NS_OK);
|
||||||
mObserver->OnStopDecode(nullptr, NS_OK, nullptr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ Image::Image(imgStatusTracker* aStatusTracker) :
|
|||||||
mStatusTracker = aStatusTracker;
|
mStatusTracker = aStatusTracker;
|
||||||
mStatusTracker->SetImage(this);
|
mStatusTracker->SetImage(this);
|
||||||
} else {
|
} else {
|
||||||
mStatusTracker = new imgStatusTracker(this);
|
mStatusTracker = new imgStatusTracker(this, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ CPPSRCS = \
|
|||||||
Decoder.cpp \
|
Decoder.cpp \
|
||||||
DiscardTracker.cpp \
|
DiscardTracker.cpp \
|
||||||
RasterImage.cpp \
|
RasterImage.cpp \
|
||||||
|
ScriptedNotificationObserver.cpp \
|
||||||
SVGDocumentWrapper.cpp \
|
SVGDocumentWrapper.cpp \
|
||||||
VectorImage.cpp \
|
VectorImage.cpp \
|
||||||
imgFrame.cpp \
|
imgFrame.cpp \
|
||||||
|
@ -514,7 +514,7 @@ RasterImage::RequestRefresh(const mozilla::TimeStamp& aTime)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
UpdateImageContainer();
|
UpdateImageContainer();
|
||||||
observer->FrameChanged(nullptr, this, &dirtyRect);
|
observer->FrameChanged(&dirtyRect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1500,7 +1500,7 @@ RasterImage::ResetAnimation()
|
|||||||
// Update display if we were animating before
|
// Update display if we were animating before
|
||||||
nsCOMPtr<imgIContainerObserver> observer(do_QueryReferent(mObserver));
|
nsCOMPtr<imgIContainerObserver> observer(do_QueryReferent(mObserver));
|
||||||
if (mAnimating && observer)
|
if (mAnimating && observer)
|
||||||
observer->FrameChanged(nullptr, this, &(mAnim->firstFrameRefreshArea));
|
observer->FrameChanged(&(mAnim->firstFrameRefreshArea));
|
||||||
|
|
||||||
if (ShouldAnimate()) {
|
if (ShouldAnimate()) {
|
||||||
StartAnimation();
|
StartAnimation();
|
||||||
@ -2284,7 +2284,7 @@ RasterImage::Discard(bool force)
|
|||||||
// Notify that we discarded
|
// Notify that we discarded
|
||||||
nsCOMPtr<imgIDecoderObserver> observer(do_QueryReferent(mObserver));
|
nsCOMPtr<imgIDecoderObserver> observer(do_QueryReferent(mObserver));
|
||||||
if (observer)
|
if (observer)
|
||||||
observer->OnDiscard(nullptr);
|
observer->OnDiscard();
|
||||||
|
|
||||||
if (force)
|
if (force)
|
||||||
DiscardTracker::Remove(&mDiscardTrackerNode);
|
DiscardTracker::Remove(&mDiscardTrackerNode);
|
||||||
@ -2774,7 +2774,7 @@ RasterImage::DrawWorker::Run()
|
|||||||
imgFrame *scaledFrame = request->dstFrame.get();
|
imgFrame *scaledFrame = request->dstFrame.get();
|
||||||
scaledFrame->ImageUpdated(scaledFrame->GetRect());
|
scaledFrame->ImageUpdated(scaledFrame->GetRect());
|
||||||
nsIntRect frameRect = request->srcFrame->GetRect();
|
nsIntRect frameRect = request->srcFrame->GetRect();
|
||||||
observer->FrameChanged(nullptr, request->image, &frameRect);
|
observer->FrameChanged(&frameRect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
49
image/src/ScriptedNotificationObserver.cpp
Normal file
49
image/src/ScriptedNotificationObserver.cpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "ScriptedNotificationObserver.h"
|
||||||
|
#include "imgIScriptedNotificationObserver.h"
|
||||||
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
|
||||||
|
using namespace mozilla::image;
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_1(ScriptedNotificationObserver, mInner)
|
||||||
|
|
||||||
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ScriptedNotificationObserver)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(imgINotificationObserver)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||||
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(ScriptedNotificationObserver)
|
||||||
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(ScriptedNotificationObserver)
|
||||||
|
|
||||||
|
ScriptedNotificationObserver::ScriptedNotificationObserver(
|
||||||
|
imgIScriptedNotificationObserver* aInner)
|
||||||
|
: mInner(aInner)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
ScriptedNotificationObserver::Notify(imgIRequest* aRequest,
|
||||||
|
int32_t aType,
|
||||||
|
const nsIntRect* /*aUnused*/)
|
||||||
|
{
|
||||||
|
if (aType == imgINotificationObserver::SIZE_AVAILABLE)
|
||||||
|
return mInner->SizeAvailable(aRequest);
|
||||||
|
if (aType == imgINotificationObserver::FRAME_UPDATE)
|
||||||
|
return mInner->FrameUpdate(aRequest);
|
||||||
|
if (aType == imgINotificationObserver::FRAME_COMPLETE)
|
||||||
|
return mInner->FrameComplete(aRequest);
|
||||||
|
if (aType == imgINotificationObserver::DECODE_COMPLETE)
|
||||||
|
return mInner->DecodeComplete(aRequest);
|
||||||
|
if (aType == imgINotificationObserver::LOAD_COMPLETE)
|
||||||
|
return mInner->LoadComplete(aRequest);
|
||||||
|
if (aType == imgINotificationObserver::DISCARD)
|
||||||
|
return mInner->Discard(aRequest);
|
||||||
|
if (aType == imgINotificationObserver::IS_ANIMATED)
|
||||||
|
return mInner->IsAnimated(aRequest);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
30
image/src/ScriptedNotificationObserver.h
Normal file
30
image/src/ScriptedNotificationObserver.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "imgINotificationObserver.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
|
||||||
|
class imgIScriptedNotificationObserver;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace image {
|
||||||
|
|
||||||
|
class ScriptedNotificationObserver : public imgINotificationObserver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScriptedNotificationObserver(imgIScriptedNotificationObserver* aInner);
|
||||||
|
virtual ~ScriptedNotificationObserver() {}
|
||||||
|
|
||||||
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
|
NS_DECL_IMGINOTIFICATIONOBSERVER
|
||||||
|
NS_DECL_CYCLE_COLLECTION_CLASS(ScriptedNotificationObserver)
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsCOMPtr<imgIScriptedNotificationObserver> mInner;
|
||||||
|
};
|
||||||
|
|
||||||
|
}}
|
@ -681,11 +681,11 @@ VectorImage::OnStopRequest(nsIRequest* aRequest, nsISupports* aCtxt,
|
|||||||
nsCOMPtr<imgIDecoderObserver> observer = do_QueryReferent(mObserver);
|
nsCOMPtr<imgIDecoderObserver> observer = do_QueryReferent(mObserver);
|
||||||
if (observer) {
|
if (observer) {
|
||||||
// NOTE: This signals that width/height are available.
|
// NOTE: This signals that width/height are available.
|
||||||
observer->OnStartContainer(nullptr, this);
|
observer->OnStartContainer();
|
||||||
|
|
||||||
observer->FrameChanged(nullptr, this, &nsIntRect::GetMaxSizedIntRect());
|
observer->FrameChanged(&nsIntRect::GetMaxSizedIntRect());
|
||||||
observer->OnStopFrame(nullptr, 0);
|
observer->OnStopFrame();
|
||||||
observer->OnStopDecode(nullptr, NS_OK, nullptr);
|
observer->OnStopDecode(NS_OK);
|
||||||
}
|
}
|
||||||
EvaluateAnimation();
|
EvaluateAnimation();
|
||||||
|
|
||||||
@ -722,12 +722,12 @@ VectorImage::InvalidateObserver()
|
|||||||
|
|
||||||
nsCOMPtr<imgIContainerObserver> containerObs(do_QueryReferent(mObserver));
|
nsCOMPtr<imgIContainerObserver> containerObs(do_QueryReferent(mObserver));
|
||||||
if (containerObs) {
|
if (containerObs) {
|
||||||
containerObs->FrameChanged(nullptr, this, &nsIntRect::GetMaxSizedIntRect());
|
containerObs->FrameChanged(&nsIntRect::GetMaxSizedIntRect());
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<imgIDecoderObserver> decoderObs(do_QueryReferent(mObserver));
|
nsCOMPtr<imgIDecoderObserver> decoderObs(do_QueryReferent(mObserver));
|
||||||
if (decoderObs) {
|
if (decoderObs) {
|
||||||
decoderObs->OnStopFrame(nullptr, imgIContainer::FRAME_CURRENT);
|
decoderObs->OnStopFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -680,7 +680,7 @@ imgCacheQueue::const_iterator imgCacheQueue::end() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult imgLoader::CreateNewProxyForRequest(imgRequest *aRequest, nsILoadGroup *aLoadGroup,
|
nsresult imgLoader::CreateNewProxyForRequest(imgRequest *aRequest, nsILoadGroup *aLoadGroup,
|
||||||
imgIDecoderObserver *aObserver,
|
imgINotificationObserver *aObserver,
|
||||||
nsLoadFlags aLoadFlags, imgIRequest *aProxyRequest,
|
nsLoadFlags aLoadFlags, imgIRequest *aProxyRequest,
|
||||||
imgIRequest **_retval)
|
imgIRequest **_retval)
|
||||||
{
|
{
|
||||||
@ -708,7 +708,7 @@ nsresult imgLoader::CreateNewProxyForRequest(imgRequest *aRequest, nsILoadGroup
|
|||||||
aRequest->GetURI(getter_AddRefs(uri));
|
aRequest->GetURI(getter_AddRefs(uri));
|
||||||
|
|
||||||
// init adds itself to imgRequest's list of observers
|
// init adds itself to imgRequest's list of observers
|
||||||
nsresult rv = proxyRequest->Init(aRequest, aLoadGroup, aRequest->mImage, uri, aObserver);
|
nsresult rv = proxyRequest->Init(&aRequest->GetStatusTracker(), aLoadGroup, uri, aObserver);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
NS_RELEASE(proxyRequest);
|
NS_RELEASE(proxyRequest);
|
||||||
return rv;
|
return rv;
|
||||||
@ -1162,7 +1162,7 @@ bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
|
|||||||
nsIURI *aInitialDocumentURI,
|
nsIURI *aInitialDocumentURI,
|
||||||
nsIURI *aReferrerURI,
|
nsIURI *aReferrerURI,
|
||||||
nsILoadGroup *aLoadGroup,
|
nsILoadGroup *aLoadGroup,
|
||||||
imgIDecoderObserver *aObserver,
|
imgINotificationObserver *aObserver,
|
||||||
nsISupports *aCX,
|
nsISupports *aCX,
|
||||||
nsLoadFlags aLoadFlags,
|
nsLoadFlags aLoadFlags,
|
||||||
imgIRequest *aExistingRequest,
|
imgIRequest *aExistingRequest,
|
||||||
@ -1284,7 +1284,7 @@ bool imgLoader::ValidateEntry(imgCacheEntry *aEntry,
|
|||||||
nsIURI *aInitialDocumentURI,
|
nsIURI *aInitialDocumentURI,
|
||||||
nsIURI *aReferrerURI,
|
nsIURI *aReferrerURI,
|
||||||
nsILoadGroup *aLoadGroup,
|
nsILoadGroup *aLoadGroup,
|
||||||
imgIDecoderObserver *aObserver,
|
imgINotificationObserver *aObserver,
|
||||||
nsISupports *aCX,
|
nsISupports *aCX,
|
||||||
nsLoadFlags aLoadFlags,
|
nsLoadFlags aLoadFlags,
|
||||||
bool aCanMakeNewChannel,
|
bool aCanMakeNewChannel,
|
||||||
@ -1521,14 +1521,14 @@ nsresult imgLoader::EvictEntries(imgCacheQueue &aQueueToClear)
|
|||||||
nsIRequest::VALIDATE_ONCE_PER_SESSION)
|
nsIRequest::VALIDATE_ONCE_PER_SESSION)
|
||||||
|
|
||||||
|
|
||||||
/* imgIRequest loadImage (in nsIURI aURI, in nsIURI initialDocumentURI, in nsIPrincipal loadingPrincipal, in nsILoadGroup aLoadGroup, in imgIDecoderObserver aObserver, in nsISupports aCX, in nsLoadFlags aLoadFlags, in nsISupports cacheKey, in imgIRequest aRequest); */
|
/* imgIRequest loadImage (in nsIURI aURI, in nsIURI initialDocumentURI, in nsIPrincipal loadingPrincipal, in nsILoadGroup aLoadGroup, in imgINotificationObserver aObserver, in nsISupports aCX, in nsLoadFlags aLoadFlags, in nsISupports cacheKey, in imgIRequest aRequest); */
|
||||||
|
|
||||||
NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
|
NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
|
||||||
nsIURI *aInitialDocumentURI,
|
nsIURI *aInitialDocumentURI,
|
||||||
nsIURI *aReferrerURI,
|
nsIURI *aReferrerURI,
|
||||||
nsIPrincipal* aLoadingPrincipal,
|
nsIPrincipal* aLoadingPrincipal,
|
||||||
nsILoadGroup *aLoadGroup,
|
nsILoadGroup *aLoadGroup,
|
||||||
imgIDecoderObserver *aObserver,
|
imgINotificationObserver *aObserver,
|
||||||
nsISupports *aCX,
|
nsISupports *aCX,
|
||||||
nsLoadFlags aLoadFlags,
|
nsLoadFlags aLoadFlags,
|
||||||
nsISupports *aCacheKey,
|
nsISupports *aCacheKey,
|
||||||
@ -1784,8 +1784,8 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* imgIRequest loadImageWithChannel(in nsIChannel channel, in imgIDecoderObserver aObserver, in nsISupports cx, out nsIStreamListener); */
|
/* imgIRequest loadImageWithChannel(in nsIChannel channel, in imgINotificationObserver aObserver, in nsISupports cx, out nsIStreamListener); */
|
||||||
NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderObserver *aObserver, nsISupports *aCX, nsIStreamListener **listener, imgIRequest **_retval)
|
NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgINotificationObserver *aObserver, nsISupports *aCX, nsIStreamListener **listener, imgIRequest **_retval)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(channel, "imgLoader::LoadImageWithChannel -- NULL channel pointer");
|
NS_ASSERTION(channel, "imgLoader::LoadImageWithChannel -- NULL channel pointer");
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ class imgLoader;
|
|||||||
class imgRequest;
|
class imgRequest;
|
||||||
class imgRequestProxy;
|
class imgRequestProxy;
|
||||||
class imgIRequest;
|
class imgIRequest;
|
||||||
class imgIDecoderObserver;
|
class imgINotificationObserver;
|
||||||
class nsILoadGroup;
|
class nsILoadGroup;
|
||||||
class imgCacheExpirationTracker;
|
class imgCacheExpirationTracker;
|
||||||
class imgMemoryReporter;
|
class imgMemoryReporter;
|
||||||
@ -289,7 +289,7 @@ private: // methods
|
|||||||
bool ValidateEntry(imgCacheEntry *aEntry, nsIURI *aKey,
|
bool ValidateEntry(imgCacheEntry *aEntry, nsIURI *aKey,
|
||||||
nsIURI *aInitialDocumentURI, nsIURI *aReferrerURI,
|
nsIURI *aInitialDocumentURI, nsIURI *aReferrerURI,
|
||||||
nsILoadGroup *aLoadGroup,
|
nsILoadGroup *aLoadGroup,
|
||||||
imgIDecoderObserver *aObserver, nsISupports *aCX,
|
imgINotificationObserver *aObserver, nsISupports *aCX,
|
||||||
nsLoadFlags aLoadFlags, bool aCanMakeNewChannel,
|
nsLoadFlags aLoadFlags, bool aCanMakeNewChannel,
|
||||||
imgIRequest *aExistingRequest,
|
imgIRequest *aExistingRequest,
|
||||||
imgIRequest **aProxyRequest,
|
imgIRequest **aProxyRequest,
|
||||||
@ -300,7 +300,7 @@ private: // methods
|
|||||||
nsIURI *aInitialDocumentURI,
|
nsIURI *aInitialDocumentURI,
|
||||||
nsIURI *aReferrerURI,
|
nsIURI *aReferrerURI,
|
||||||
nsILoadGroup *aLoadGroup,
|
nsILoadGroup *aLoadGroup,
|
||||||
imgIDecoderObserver *aObserver,
|
imgINotificationObserver *aObserver,
|
||||||
nsISupports *aCX, nsLoadFlags aLoadFlags,
|
nsISupports *aCX, nsLoadFlags aLoadFlags,
|
||||||
imgIRequest *aExistingRequest,
|
imgIRequest *aExistingRequest,
|
||||||
imgIRequest **aProxyRequest,
|
imgIRequest **aProxyRequest,
|
||||||
@ -309,7 +309,7 @@ private: // methods
|
|||||||
int32_t aCORSMode);
|
int32_t aCORSMode);
|
||||||
|
|
||||||
nsresult CreateNewProxyForRequest(imgRequest *aRequest, nsILoadGroup *aLoadGroup,
|
nsresult CreateNewProxyForRequest(imgRequest *aRequest, nsILoadGroup *aLoadGroup,
|
||||||
imgIDecoderObserver *aObserver,
|
imgINotificationObserver *aObserver,
|
||||||
nsLoadFlags aLoadFlags, imgIRequest *aRequestProxy,
|
nsLoadFlags aLoadFlags, imgIRequest *aRequestProxy,
|
||||||
imgIRequest **_retval);
|
imgIRequest **_retval);
|
||||||
|
|
||||||
|
@ -71,16 +71,15 @@ InitPrefCaches()
|
|||||||
PRLogModuleInfo *gImgLog = PR_NewLogModule("imgRequest");
|
PRLogModuleInfo *gImgLog = PR_NewLogModule("imgRequest");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS8(imgRequest,
|
NS_IMPL_ISUPPORTS5(imgRequest,
|
||||||
imgIDecoderObserver, imgIContainerObserver,
|
|
||||||
nsIStreamListener, nsIRequestObserver,
|
nsIStreamListener, nsIRequestObserver,
|
||||||
nsISupportsWeakReference,
|
|
||||||
nsIChannelEventSink,
|
nsIChannelEventSink,
|
||||||
nsIInterfaceRequestor,
|
nsIInterfaceRequestor,
|
||||||
nsIAsyncVerifyRedirectCallback)
|
nsIAsyncVerifyRedirectCallback)
|
||||||
|
|
||||||
imgRequest::imgRequest(imgLoader* aLoader)
|
imgRequest::imgRequest(imgLoader* aLoader)
|
||||||
: mLoader(aLoader)
|
: mLoader(aLoader)
|
||||||
|
, mStatusTracker(new imgStatusTracker(nullptr, this))
|
||||||
, mValidator(nullptr)
|
, mValidator(nullptr)
|
||||||
, mImageSniffers("image-sniffing-services")
|
, mImageSniffers("image-sniffing-services")
|
||||||
, mInnerWindowId(0)
|
, mInnerWindowId(0)
|
||||||
@ -89,7 +88,6 @@ imgRequest::imgRequest(imgLoader* aLoader)
|
|||||||
, mIsMultiPartChannel(false)
|
, mIsMultiPartChannel(false)
|
||||||
, mGotData(false)
|
, mGotData(false)
|
||||||
, mIsInCache(false)
|
, mIsInCache(false)
|
||||||
, mBlockingOnload(false)
|
|
||||||
, mResniffMimeType(false)
|
, mResniffMimeType(false)
|
||||||
{
|
{
|
||||||
// Register our pref observers if we haven't yet.
|
// Register our pref observers if we haven't yet.
|
||||||
@ -127,8 +125,6 @@ nsresult imgRequest::Init(nsIURI *aURI,
|
|||||||
|
|
||||||
mProperties = do_CreateInstance("@mozilla.org/properties;1");
|
mProperties = do_CreateInstance("@mozilla.org/properties;1");
|
||||||
|
|
||||||
mStatusTracker = new imgStatusTracker(nullptr);
|
|
||||||
|
|
||||||
mURI = aURI;
|
mURI = aURI;
|
||||||
mCurrentURI = aCurrentURI;
|
mCurrentURI = aCurrentURI;
|
||||||
mRequest = aRequest;
|
mRequest = aRequest;
|
||||||
@ -176,6 +172,13 @@ bool imgRequest::HasCacheEntry() const
|
|||||||
return mCacheEntry != nullptr;
|
return mCacheEntry != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void imgRequest::ResetCacheEntry()
|
||||||
|
{
|
||||||
|
if (HasCacheEntry()) {
|
||||||
|
mCacheEntry->SetDataSize(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void imgRequest::AddProxy(imgRequestProxy *proxy)
|
void imgRequest::AddProxy(imgRequestProxy *proxy)
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(proxy, "null imgRequestProxy passed in");
|
NS_PRECONDITION(proxy, "null imgRequestProxy passed in");
|
||||||
@ -183,21 +186,12 @@ void imgRequest::AddProxy(imgRequestProxy *proxy)
|
|||||||
|
|
||||||
// If we're empty before adding, we have to tell the loader we now have
|
// If we're empty before adding, we have to tell the loader we now have
|
||||||
// proxies.
|
// proxies.
|
||||||
if (mObservers.IsEmpty()) {
|
if (GetStatusTracker().ConsumerCount() == 0) {
|
||||||
NS_ABORT_IF_FALSE(mURI, "Trying to SetHasProxies without key uri.");
|
NS_ABORT_IF_FALSE(mURI, "Trying to SetHasProxies without key uri.");
|
||||||
mLoader->SetHasProxies(mURI);
|
mLoader->SetHasProxies(mURI);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we don't have any current observers, we should restart any animation.
|
GetStatusTracker().AddConsumer(proxy);
|
||||||
if (mImage && !HaveProxyWithObserver(proxy) && proxy->HasObserver()) {
|
|
||||||
LOG_MSG(gImgLog, "imgRequest::AddProxy", "resetting animation");
|
|
||||||
|
|
||||||
mImage->ResetAnimation();
|
|
||||||
}
|
|
||||||
|
|
||||||
proxy->SetPrincipal(mPrincipal);
|
|
||||||
|
|
||||||
mObservers.AppendElementUnlessExists(proxy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult imgRequest::RemoveProxy(imgRequestProxy *proxy, nsresult aStatus)
|
nsresult imgRequest::RemoveProxy(imgRequestProxy *proxy, nsresult aStatus)
|
||||||
@ -209,20 +203,15 @@ nsresult imgRequest::RemoveProxy(imgRequestProxy *proxy, nsresult aStatus)
|
|||||||
// have animation consumers.
|
// have animation consumers.
|
||||||
proxy->ClearAnimationConsumers();
|
proxy->ClearAnimationConsumers();
|
||||||
|
|
||||||
if (!mObservers.RemoveElement(proxy)) {
|
|
||||||
// Not one of our proxies; we're done
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Let the status tracker do its thing before we potentially call Cancel()
|
// Let the status tracker do its thing before we potentially call Cancel()
|
||||||
// below, because Cancel() may result in OnStopRequest being called back
|
// below, because Cancel() may result in OnStopRequest being called back
|
||||||
// before Cancel() returns, leaving the image in a different state then the
|
// before Cancel() returns, leaving the image in a different state then the
|
||||||
// one it was in at this point.
|
// one it was in at this point.
|
||||||
|
|
||||||
imgStatusTracker& statusTracker = GetStatusTracker();
|
imgStatusTracker& statusTracker = GetStatusTracker();
|
||||||
statusTracker.EmulateRequestFinished(proxy, aStatus);
|
if (!statusTracker.RemoveConsumer(proxy, aStatus))
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
if (mObservers.IsEmpty()) {
|
if (statusTracker.ConsumerCount() == 0) {
|
||||||
// If we have no observers, there's nothing holding us alive. If we haven't
|
// If we have no observers, there's nothing holding us alive. If we haven't
|
||||||
// been cancelled and thus removed from the cache, tell the image loader so
|
// been cancelled and thus removed from the cache, tell the image loader so
|
||||||
// we can be evicted from the cache.
|
// we can be evicted from the cache.
|
||||||
@ -242,7 +231,7 @@ nsresult imgRequest::RemoveProxy(imgRequestProxy *proxy, nsresult aStatus)
|
|||||||
/* If |aStatus| is a failure code, then cancel the load if it is still in progress.
|
/* If |aStatus| is a failure code, then cancel the load if it is still in progress.
|
||||||
Otherwise, let the load continue, keeping 'this' in the cache with no observers.
|
Otherwise, let the load continue, keeping 'this' in the cache with no observers.
|
||||||
This way, if a proxy is destroyed without calling cancel on it, it won't leak
|
This way, if a proxy is destroyed without calling cancel on it, it won't leak
|
||||||
and won't leave a bad pointer in mObservers.
|
and won't leave a bad pointer in the observer list.
|
||||||
*/
|
*/
|
||||||
if (statusTracker.IsLoading() && NS_FAILED(aStatus)) {
|
if (statusTracker.IsLoading() && NS_FAILED(aStatus)) {
|
||||||
LOG_MSG(gImgLog, "imgRequest::RemoveProxy", "load in progress. canceling");
|
LOG_MSG(gImgLog, "imgRequest::RemoveProxy", "load in progress. canceling");
|
||||||
@ -285,16 +274,7 @@ void imgRequest::Cancel(nsresult aStatus)
|
|||||||
|
|
||||||
imgStatusTracker& statusTracker = GetStatusTracker();
|
imgStatusTracker& statusTracker = GetStatusTracker();
|
||||||
|
|
||||||
if (mBlockingOnload) {
|
statusTracker.MaybeUnblockOnload();
|
||||||
mBlockingOnload = false;
|
|
||||||
|
|
||||||
statusTracker.RecordUnblockOnload();
|
|
||||||
|
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
statusTracker.SendUnblockOnload(iter.GetNext());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
statusTracker.RecordCancel();
|
statusTracker.RecordCancel();
|
||||||
|
|
||||||
@ -342,24 +322,6 @@ void imgRequest::RemoveFromCache()
|
|||||||
mCacheEntry = nullptr;
|
mCacheEntry = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool imgRequest::HaveProxyWithObserver(imgRequestProxy* aProxyToIgnore) const
|
|
||||||
{
|
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
|
||||||
imgRequestProxy* proxy;
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
proxy = iter.GetNext();
|
|
||||||
if (proxy == aProxyToIgnore) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (proxy->HasObserver()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t imgRequest::Priority() const
|
int32_t imgRequest::Priority() const
|
||||||
{
|
{
|
||||||
int32_t priority = nsISupportsPriority::PRIORITY_NORMAL;
|
int32_t priority = nsISupportsPriority::PRIORITY_NORMAL;
|
||||||
@ -378,7 +340,7 @@ void imgRequest::AdjustPriority(imgRequestProxy *proxy, int32_t delta)
|
|||||||
// concern though is that image loads remain lower priority than other pieces
|
// concern though is that image loads remain lower priority than other pieces
|
||||||
// of content such as link clicks, CSS, and JS.
|
// of content such as link clicks, CSS, and JS.
|
||||||
//
|
//
|
||||||
if (mObservers.SafeElementAt(0, nullptr) != proxy)
|
if (!GetStatusTracker().FirstConsumerIs(proxy))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(mRequest);
|
nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(mRequest);
|
||||||
@ -510,289 +472,6 @@ imgRequest::StartDecoding()
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** imgIContainerObserver methods **/
|
|
||||||
|
|
||||||
/* [noscript] void frameChanged (in imgIRequest request,
|
|
||||||
in imgIContainer container,
|
|
||||||
in nsIntRect dirtyRect); */
|
|
||||||
NS_IMETHODIMP imgRequest::FrameChanged(imgIRequest *request,
|
|
||||||
imgIContainer *container,
|
|
||||||
const nsIntRect *dirtyRect)
|
|
||||||
{
|
|
||||||
LOG_SCOPE(gImgLog, "imgRequest::FrameChanged");
|
|
||||||
NS_ABORT_IF_FALSE(mImage,
|
|
||||||
"FrameChanged callback before we've created our image");
|
|
||||||
|
|
||||||
mImage->GetStatusTracker().RecordFrameChanged(container, dirtyRect);
|
|
||||||
|
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
mImage->GetStatusTracker().SendFrameChanged(iter.GetNext(), container, dirtyRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** imgIDecoderObserver methods **/
|
|
||||||
|
|
||||||
/* void onStartDecode (in imgIRequest request); */
|
|
||||||
NS_IMETHODIMP imgRequest::OnStartDecode(imgIRequest *request)
|
|
||||||
{
|
|
||||||
LOG_SCOPE(gImgLog, "imgRequest::OnStartDecode");
|
|
||||||
NS_ABORT_IF_FALSE(mImage,
|
|
||||||
"OnStartDecode callback before we've created our image");
|
|
||||||
|
|
||||||
|
|
||||||
imgStatusTracker& tracker = mImage->GetStatusTracker();
|
|
||||||
tracker.RecordStartDecode();
|
|
||||||
|
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
tracker.SendStartDecode(iter.GetNext());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mIsMultiPartChannel) {
|
|
||||||
MOZ_ASSERT(!mBlockingOnload);
|
|
||||||
mBlockingOnload = true;
|
|
||||||
|
|
||||||
tracker.RecordBlockOnload();
|
|
||||||
|
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
tracker.SendBlockOnload(iter.GetNext());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In the case of streaming jpegs, it is possible to get multiple OnStartDecodes which
|
|
||||||
indicates the beginning of a new decode.
|
|
||||||
The cache entry's size therefore needs to be reset to 0 here. If we do not do this,
|
|
||||||
the code in imgRequest::OnStopFrame will continue to increase the data size cumulatively.
|
|
||||||
*/
|
|
||||||
if (mCacheEntry)
|
|
||||||
mCacheEntry->SetDataSize(0);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP imgRequest::OnStartRequest(imgIRequest *aRequest)
|
|
||||||
{
|
|
||||||
NS_NOTREACHED("imgRequest(imgIDecoderObserver)::OnStartRequest");
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* void onStartContainer (in imgIRequest request, in imgIContainer image); */
|
|
||||||
NS_IMETHODIMP imgRequest::OnStartContainer(imgIRequest *request, imgIContainer *image)
|
|
||||||
{
|
|
||||||
LOG_SCOPE(gImgLog, "imgRequest::OnStartContainer");
|
|
||||||
|
|
||||||
NS_ASSERTION(image, "imgRequest::OnStartContainer called with a null image!");
|
|
||||||
if (!image) return NS_ERROR_UNEXPECTED;
|
|
||||||
|
|
||||||
NS_ABORT_IF_FALSE(mImage,
|
|
||||||
"OnStartContainer callback before we've created our image");
|
|
||||||
NS_ABORT_IF_FALSE(image == mImage,
|
|
||||||
"OnStartContainer callback from an image we don't own");
|
|
||||||
mImage->GetStatusTracker().RecordStartContainer(image);
|
|
||||||
|
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
mImage->GetStatusTracker().SendStartContainer(iter.GetNext(), image);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* void onStartFrame (in imgIRequest request, in unsigned long frame); */
|
|
||||||
NS_IMETHODIMP imgRequest::OnStartFrame(imgIRequest *request,
|
|
||||||
uint32_t frame)
|
|
||||||
{
|
|
||||||
LOG_SCOPE(gImgLog, "imgRequest::OnStartFrame");
|
|
||||||
NS_ABORT_IF_FALSE(mImage,
|
|
||||||
"OnStartFrame callback before we've created our image");
|
|
||||||
|
|
||||||
mImage->GetStatusTracker().RecordStartFrame(frame);
|
|
||||||
|
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
mImage->GetStatusTracker().SendStartFrame(iter.GetNext(), frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [noscript] void onDataAvailable (in imgIRequest request, in boolean aCurrentFrame, [const] in nsIntRect rect); */
|
|
||||||
NS_IMETHODIMP imgRequest::OnDataAvailable(imgIRequest *request,
|
|
||||||
bool aCurrentFrame,
|
|
||||||
const nsIntRect * rect)
|
|
||||||
{
|
|
||||||
LOG_SCOPE(gImgLog, "imgRequest::OnDataAvailable");
|
|
||||||
NS_ABORT_IF_FALSE(mImage,
|
|
||||||
"OnDataAvailable callback before we've created our image");
|
|
||||||
|
|
||||||
mImage->GetStatusTracker().RecordDataAvailable(aCurrentFrame, rect);
|
|
||||||
|
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
mImage->GetStatusTracker().SendDataAvailable(iter.GetNext(), aCurrentFrame, rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* void onStopFrame (in imgIRequest request, in unsigned long frame); */
|
|
||||||
NS_IMETHODIMP imgRequest::OnStopFrame(imgIRequest *request,
|
|
||||||
uint32_t frame)
|
|
||||||
{
|
|
||||||
LOG_SCOPE(gImgLog, "imgRequest::OnStopFrame");
|
|
||||||
NS_ABORT_IF_FALSE(mImage,
|
|
||||||
"OnStopFrame callback before we've created our image");
|
|
||||||
|
|
||||||
imgStatusTracker& tracker = mImage->GetStatusTracker();
|
|
||||||
tracker.RecordStopFrame(frame);
|
|
||||||
|
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
tracker.SendStopFrame(iter.GetNext(), frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mBlockingOnload) {
|
|
||||||
mBlockingOnload = false;
|
|
||||||
|
|
||||||
tracker.RecordUnblockOnload();
|
|
||||||
|
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
tracker.SendUnblockOnload(iter.GetNext());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* void onStopContainer (in imgIRequest request, in imgIContainer image); */
|
|
||||||
NS_IMETHODIMP imgRequest::OnStopContainer(imgIRequest *request,
|
|
||||||
imgIContainer *image)
|
|
||||||
{
|
|
||||||
LOG_SCOPE(gImgLog, "imgRequest::OnStopContainer");
|
|
||||||
NS_ABORT_IF_FALSE(mImage,
|
|
||||||
"OnDataContainer callback before we've created our image");
|
|
||||||
|
|
||||||
imgStatusTracker& tracker = mImage->GetStatusTracker();
|
|
||||||
tracker.RecordStopContainer(image);
|
|
||||||
|
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
tracker.SendStopContainer(iter.GetNext(), image);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is really hacky. We need to handle the case where we start decoding,
|
|
||||||
// block onload, but then hit an error before we get to our first frame. In
|
|
||||||
// theory we would just hook in at OnStopDecode, but OnStopDecode is broken
|
|
||||||
// until we fix bug 505385. OnStopContainer is actually going away at that
|
|
||||||
// point. So for now we take advantage of the fact that OnStopContainer is
|
|
||||||
// always fired in the decoders at the same time as OnStopDecode.
|
|
||||||
if (mBlockingOnload) {
|
|
||||||
mBlockingOnload = false;
|
|
||||||
|
|
||||||
tracker.RecordUnblockOnload();
|
|
||||||
|
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
tracker.SendUnblockOnload(iter.GetNext());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* void onStopDecode (in imgIRequest request, in nsresult status, in wstring statusArg); */
|
|
||||||
NS_IMETHODIMP imgRequest::OnStopDecode(imgIRequest *aRequest,
|
|
||||||
nsresult aStatus,
|
|
||||||
const PRUnichar *aStatusArg)
|
|
||||||
{
|
|
||||||
LOG_SCOPE(gImgLog, "imgRequest::OnStopDecode");
|
|
||||||
NS_ABORT_IF_FALSE(mImage,
|
|
||||||
"OnDataDecode callback before we've created our image");
|
|
||||||
|
|
||||||
// We finished the decode, and thus have the decoded frames. Update the cache
|
|
||||||
// entry size to take this into account.
|
|
||||||
UpdateCacheEntrySize();
|
|
||||||
|
|
||||||
mImage->GetStatusTracker().RecordStopDecode(aStatus, aStatusArg);
|
|
||||||
|
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
mImage->GetStatusTracker().SendStopDecode(iter.GetNext(), aStatus,
|
|
||||||
aStatusArg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_FAILED(aStatus)) {
|
|
||||||
// Some kind of problem has happened with image decoding.
|
|
||||||
// Report the URI to net:failed-to-process-uri-conent observers.
|
|
||||||
|
|
||||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
|
||||||
if (os)
|
|
||||||
os->NotifyObservers(mURI, "net:failed-to-process-uri-content", nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// RasterImage and everything below it is completely correct and
|
|
||||||
// bulletproof about its handling of decoder notifications.
|
|
||||||
// Unfortunately, here and above we have to make some gross and
|
|
||||||
// inappropriate use of things to get things to work without
|
|
||||||
// completely overhauling the decoder observer interface (this will,
|
|
||||||
// thankfully, happen in bug 505385). From imgRequest and above (for
|
|
||||||
// the time being), OnStopDecode is just a companion to OnStopRequest
|
|
||||||
// that signals success or failure of the _load_ (not the _decode_).
|
|
||||||
// Within imgStatusTracker, we ignore OnStopDecode notifications from the
|
|
||||||
// decoder and RasterImage and generate our own every time we send
|
|
||||||
// OnStopRequest. From within SendStopDecode, we actually send
|
|
||||||
// OnStopContainer. For more information, see bug 435296.
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP imgRequest::OnStopRequest(imgIRequest *aRequest,
|
|
||||||
bool aLastPart)
|
|
||||||
{
|
|
||||||
NS_NOTREACHED("imgRequest(imgIDecoderObserver)::OnStopRequest");
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* void onDiscard (in imgIRequest request); */
|
|
||||||
NS_IMETHODIMP imgRequest::OnDiscard(imgIRequest *aRequest)
|
|
||||||
{
|
|
||||||
NS_ABORT_IF_FALSE(mImage,
|
|
||||||
"OnDiscard callback before we've created our image");
|
|
||||||
|
|
||||||
mImage->GetStatusTracker().RecordDiscard();
|
|
||||||
|
|
||||||
// Update the cache entry size, since we just got rid of frame data
|
|
||||||
UpdateCacheEntrySize();
|
|
||||||
|
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
mImage->GetStatusTracker().SendDiscard(iter.GetNext());
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP imgRequest::OnImageIsAnimated(imgIRequest *aRequest)
|
|
||||||
{
|
|
||||||
NS_ABORT_IF_FALSE(mImage,
|
|
||||||
"OnImageIsAnimated callback before we've created our image");
|
|
||||||
mImage->GetStatusTracker().RecordImageIsAnimated();
|
|
||||||
|
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
mImage->GetStatusTracker().SendImageIsAnimated(iter.GetNext());
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** nsIRequestObserver methods **/
|
/** nsIRequestObserver methods **/
|
||||||
|
|
||||||
/* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */
|
/* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */
|
||||||
@ -838,18 +517,12 @@ NS_IMETHODIMP imgRequest::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt
|
|||||||
mRequest = chan;
|
mRequest = chan;
|
||||||
}
|
}
|
||||||
|
|
||||||
imgStatusTracker& statusTracker = GetStatusTracker();
|
GetStatusTracker().OnStartRequest();
|
||||||
statusTracker.RecordStartRequest();
|
|
||||||
|
|
||||||
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
|
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
|
||||||
if (channel)
|
if (channel)
|
||||||
channel->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
|
channel->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
|
||||||
|
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
statusTracker.SendStartRequest(iter.GetNext());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get our principal */
|
/* Get our principal */
|
||||||
nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
|
nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
|
||||||
if (chan) {
|
if (chan) {
|
||||||
@ -861,19 +534,13 @@ NS_IMETHODIMP imgRequest::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt
|
|||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tell all of our proxies that we have a principal.
|
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
iter.GetNext()->SetPrincipal(mPrincipal);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetCacheValidation(mCacheEntry, aRequest);
|
SetCacheValidation(mCacheEntry, aRequest);
|
||||||
|
|
||||||
// Shouldn't we be dead already if this gets hit? Probably multipart/x-mixed-replace...
|
// Shouldn't we be dead already if this gets hit? Probably multipart/x-mixed-replace...
|
||||||
if (mObservers.IsEmpty()) {
|
if (GetStatusTracker().ConsumerCount() == 0) {
|
||||||
this->Cancel(NS_IMAGELIB_ERROR_FAILURE);
|
this->Cancel(NS_IMAGELIB_ERROR_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -943,11 +610,7 @@ NS_IMETHODIMP imgRequest::OnStopRequest(nsIRequest *aRequest, nsISupports *ctxt,
|
|||||||
this->Cancel(status);
|
this->Cancel(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* notify the kids */
|
GetStatusTracker().OnStopRequest(lastPart, status);
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator srIter(mObservers);
|
|
||||||
while (srIter.HasMore()) {
|
|
||||||
statusTracker.SendStopRequest(srIter.GetNext(), lastPart, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
mTimedChannel = nullptr;
|
mTimedChannel = nullptr;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -1033,7 +696,9 @@ imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt,
|
|||||||
// our own any more.
|
// our own any more.
|
||||||
if (mResniffMimeType) {
|
if (mResniffMimeType) {
|
||||||
NS_ABORT_IF_FALSE(mIsMultiPartChannel, "Resniffing a non-multipart image");
|
NS_ABORT_IF_FALSE(mIsMultiPartChannel, "Resniffing a non-multipart image");
|
||||||
mStatusTracker = new imgStatusTracker(nullptr);
|
imgStatusTracker* freshTracker = new imgStatusTracker(nullptr, this);
|
||||||
|
freshTracker->AdoptConsumers(&GetStatusTracker());
|
||||||
|
mStatusTracker = freshTracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
mResniffMimeType = false;
|
mResniffMimeType = false;
|
||||||
@ -1046,11 +711,7 @@ imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt,
|
|||||||
}
|
}
|
||||||
mImage->SetInnerWindowID(mInnerWindowId);
|
mImage->SetInnerWindowID(mInnerWindowId);
|
||||||
|
|
||||||
// Notify any imgRequestProxys that are observing us that we have an Image.
|
GetStatusTracker().OnDataAvailable();
|
||||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
iter.GetNext()->SetImage(mImage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set our mimetype as a property */
|
/* set our mimetype as a property */
|
||||||
nsCOMPtr<nsISupportsCString> contentType(do_CreateInstance("@mozilla.org/supports-cstring;1"));
|
nsCOMPtr<nsISupportsCString> contentType(do_CreateInstance("@mozilla.org/supports-cstring;1"));
|
||||||
@ -1119,7 +780,8 @@ imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt,
|
|||||||
// Initialize the image that we created above. For RasterImages, this
|
// Initialize the image that we created above. For RasterImages, this
|
||||||
// instantiates a decoder behind the scenes, so if we don't have a decoder
|
// instantiates a decoder behind the scenes, so if we don't have a decoder
|
||||||
// for this mimetype we'll find out about it here.
|
// for this mimetype we'll find out about it here.
|
||||||
rv = mImage->Init(this, mContentType.get(), uriString.get(), imageFlags);
|
rv = mImage->Init(GetStatusTracker().GetDecoderObserver(),
|
||||||
|
mContentType.get(), uriString.get(), imageFlags);
|
||||||
|
|
||||||
// We allow multipart images to fail to initialize without cancelling the
|
// We allow multipart images to fail to initialize without cancelling the
|
||||||
// load because subsequent images might be fine.
|
// load because subsequent images might be fine.
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
#ifndef imgRequest_h__
|
#ifndef imgRequest_h__
|
||||||
#define imgRequest_h__
|
#define imgRequest_h__
|
||||||
|
|
||||||
#include "imgIDecoderObserver.h"
|
|
||||||
|
|
||||||
#include "nsIChannelEventSink.h"
|
#include "nsIChannelEventSink.h"
|
||||||
#include "nsIContentSniffer.h"
|
#include "nsIContentSniffer.h"
|
||||||
#include "nsIInterfaceRequestor.h"
|
#include "nsIInterfaceRequestor.h"
|
||||||
@ -22,8 +20,6 @@
|
|||||||
#include "nsCategoryCache.h"
|
#include "nsCategoryCache.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsStringGlue.h"
|
#include "nsStringGlue.h"
|
||||||
#include "nsTObserverArray.h"
|
|
||||||
#include "nsWeakReference.h"
|
|
||||||
#include "nsError.h"
|
#include "nsError.h"
|
||||||
#include "imgIRequest.h"
|
#include "imgIRequest.h"
|
||||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||||
@ -42,9 +38,7 @@ class Image;
|
|||||||
} // namespace image
|
} // namespace image
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
class imgRequest : public imgIDecoderObserver,
|
class imgRequest : public nsIStreamListener,
|
||||||
public nsIStreamListener,
|
|
||||||
public nsSupportsWeakReference,
|
|
||||||
public nsIChannelEventSink,
|
public nsIChannelEventSink,
|
||||||
public nsIInterfaceRequestor,
|
public nsIInterfaceRequestor,
|
||||||
public nsIAsyncVerifyRedirectCallback
|
public nsIAsyncVerifyRedirectCallback
|
||||||
@ -110,6 +104,22 @@ public:
|
|||||||
return principal.forget();
|
return principal.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the imgStatusTracker associated with this imgRequest. It may live
|
||||||
|
// in |mStatusTracker| or in |mImage.mStatusTracker|, depending on whether
|
||||||
|
// mImage has been instantiated yet.
|
||||||
|
imgStatusTracker& GetStatusTracker();
|
||||||
|
|
||||||
|
// Get the current principal of the image. No AddRefing.
|
||||||
|
inline nsIPrincipal* GetPrincipal() const { return mPrincipal.get(); };
|
||||||
|
|
||||||
|
// Resize the cache entry to 0 if it exists
|
||||||
|
void ResetCacheEntry();
|
||||||
|
|
||||||
|
// Update the cache entry size based on the image container
|
||||||
|
void UpdateCacheEntrySize();
|
||||||
|
|
||||||
|
nsresult GetURI(nsIURI **aURI);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class imgCacheEntry;
|
friend class imgCacheEntry;
|
||||||
friend class imgRequestProxy;
|
friend class imgRequestProxy;
|
||||||
@ -125,7 +135,6 @@ private:
|
|||||||
void Cancel(nsresult aStatus);
|
void Cancel(nsresult aStatus);
|
||||||
void RemoveFromCache();
|
void RemoveFromCache();
|
||||||
|
|
||||||
nsresult GetURI(nsIURI **aURI);
|
|
||||||
nsresult GetSecurityInfo(nsISupports **aSecurityInfo);
|
nsresult GetSecurityInfo(nsISupports **aSecurityInfo);
|
||||||
|
|
||||||
inline const char *GetMimeType() const {
|
inline const char *GetMimeType() const {
|
||||||
@ -135,11 +144,6 @@ private:
|
|||||||
return mProperties;
|
return mProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the imgStatusTracker associated with this imgRequest. It may live
|
|
||||||
// in |mStatusTracker| or in |mImage.mStatusTracker|, depending on whether
|
|
||||||
// mImage has been instantiated yet..
|
|
||||||
imgStatusTracker& GetStatusTracker();
|
|
||||||
|
|
||||||
// Reset the cache entry after we've dropped our reference to it. Used by the
|
// Reset the cache entry after we've dropped our reference to it. Used by the
|
||||||
// imgLoader when our cache entry is re-requested after we've dropped our
|
// imgLoader when our cache entry is re-requested after we've dropped our
|
||||||
// reference to it.
|
// reference to it.
|
||||||
@ -148,10 +152,6 @@ private:
|
|||||||
// Returns whether we've got a reference to the cache entry.
|
// Returns whether we've got a reference to the cache entry.
|
||||||
bool HasCacheEntry() const;
|
bool HasCacheEntry() const;
|
||||||
|
|
||||||
// Return true if at least one of our proxies, excluding
|
|
||||||
// aProxyToIgnore, has an observer. aProxyToIgnore may be null.
|
|
||||||
bool HaveProxyWithObserver(imgRequestProxy* aProxyToIgnore) const;
|
|
||||||
|
|
||||||
// Return the priority of the underlying network request, or return
|
// Return the priority of the underlying network request, or return
|
||||||
// PRIORITY_NORMAL if it doesn't support nsISupportsPriority.
|
// PRIORITY_NORMAL if it doesn't support nsISupportsPriority.
|
||||||
int32_t Priority() const;
|
int32_t Priority() const;
|
||||||
@ -168,12 +168,10 @@ private:
|
|||||||
// try to update or modify the image cache.
|
// try to update or modify the image cache.
|
||||||
void SetIsInCache(bool cacheable);
|
void SetIsInCache(bool cacheable);
|
||||||
|
|
||||||
// Update the cache entry size based on the image container
|
bool IsBlockingOnload() const;
|
||||||
void UpdateCacheEntrySize();
|
void SetBlockingOnload(bool block) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_IMGIDECODEROBSERVER
|
|
||||||
NS_DECL_IMGICONTAINEROBSERVER
|
|
||||||
NS_DECL_NSISTREAMLISTENER
|
NS_DECL_NSISTREAMLISTENER
|
||||||
NS_DECL_NSIREQUESTOBSERVER
|
NS_DECL_NSIREQUESTOBSERVER
|
||||||
NS_DECL_NSICHANNELEVENTSINK
|
NS_DECL_NSICHANNELEVENTSINK
|
||||||
@ -203,8 +201,6 @@ private:
|
|||||||
nsCOMPtr<nsIChannel> mChannel;
|
nsCOMPtr<nsIChannel> mChannel;
|
||||||
nsCOMPtr<nsIInterfaceRequestor> mPrevChannelSink;
|
nsCOMPtr<nsIInterfaceRequestor> mPrevChannelSink;
|
||||||
|
|
||||||
nsTObserverArray<imgRequestProxy*> mObservers;
|
|
||||||
|
|
||||||
nsCOMPtr<nsITimedChannel> mTimedChannel;
|
nsCOMPtr<nsITimedChannel> mTimedChannel;
|
||||||
|
|
||||||
nsCString mContentType;
|
nsCString mContentType;
|
||||||
|
@ -40,8 +40,6 @@ NS_INTERFACE_MAP_END
|
|||||||
imgRequestProxy::imgRequestProxy() :
|
imgRequestProxy::imgRequestProxy() :
|
||||||
mOwner(nullptr),
|
mOwner(nullptr),
|
||||||
mURI(nullptr),
|
mURI(nullptr),
|
||||||
mImage(nullptr),
|
|
||||||
mPrincipal(nullptr),
|
|
||||||
mListener(nullptr),
|
mListener(nullptr),
|
||||||
mLoadFlags(nsIRequest::LOAD_NORMAL),
|
mLoadFlags(nsIRequest::LOAD_NORMAL),
|
||||||
mLockCount(0),
|
mLockCount(0),
|
||||||
@ -51,7 +49,8 @@ imgRequestProxy::imgRequestProxy() :
|
|||||||
mListenerIsStrongRef(false),
|
mListenerIsStrongRef(false),
|
||||||
mDecodeRequested(false),
|
mDecodeRequested(false),
|
||||||
mDeferNotifications(false),
|
mDeferNotifications(false),
|
||||||
mSentStartContainer(false)
|
mSentStartContainer(false),
|
||||||
|
mOwnerHasImage(false)
|
||||||
{
|
{
|
||||||
/* member initializers and constructor code */
|
/* member initializers and constructor code */
|
||||||
|
|
||||||
@ -89,16 +88,18 @@ imgRequestProxy::~imgRequestProxy()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult imgRequestProxy::Init(imgRequest* request, nsILoadGroup* aLoadGroup, Image* aImage,
|
nsresult imgRequestProxy::Init(imgStatusTracker* aStatusTracker,
|
||||||
nsIURI* aURI, imgIDecoderObserver* aObserver)
|
nsILoadGroup* aLoadGroup,
|
||||||
|
nsIURI* aURI, imgINotificationObserver* aObserver)
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(!mOwner && !mListener, "imgRequestProxy is already initialized");
|
NS_PRECONDITION(!mOwner && !mListener, "imgRequestProxy is already initialized");
|
||||||
|
|
||||||
LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequestProxy::Init", "request", request);
|
LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequestProxy::Init", "request", aStatusTracker->GetRequest());
|
||||||
|
|
||||||
NS_ABORT_IF_FALSE(mAnimationConsumers == 0, "Cannot have animation before Init");
|
NS_ABORT_IF_FALSE(mAnimationConsumers == 0, "Cannot have animation before Init");
|
||||||
|
|
||||||
mOwner = request;
|
mOwner = aStatusTracker->GetRequest();
|
||||||
|
mOwnerHasImage = !!aStatusTracker->GetImage();
|
||||||
mListener = aObserver;
|
mListener = aObserver;
|
||||||
// Make sure to addref mListener before the AddProxy call below, since
|
// Make sure to addref mListener before the AddProxy call below, since
|
||||||
// that call might well want to release it if the imgRequest has
|
// that call might well want to release it if the imgRequest has
|
||||||
@ -108,7 +109,6 @@ nsresult imgRequestProxy::Init(imgRequest* request, nsILoadGroup* aLoadGroup, Im
|
|||||||
NS_ADDREF(mListener);
|
NS_ADDREF(mListener);
|
||||||
}
|
}
|
||||||
mLoadGroup = aLoadGroup;
|
mLoadGroup = aLoadGroup;
|
||||||
mImage = aImage;
|
|
||||||
mURI = aURI;
|
mURI = aURI;
|
||||||
|
|
||||||
// Note: AddProxy won't send all the On* notifications immediately
|
// Note: AddProxy won't send all the On* notifications immediately
|
||||||
@ -132,9 +132,9 @@ nsresult imgRequestProxy::ChangeOwner(imgRequest *aNewOwner)
|
|||||||
uint32_t oldAnimationConsumers = mAnimationConsumers;
|
uint32_t oldAnimationConsumers = mAnimationConsumers;
|
||||||
ClearAnimationConsumers();
|
ClearAnimationConsumers();
|
||||||
|
|
||||||
// Even if we are cancelled, we MUST change our image, because the image
|
nsRefPtr<imgRequest> oldOwner = mOwner;
|
||||||
// holds our status, and the status must always be correct.
|
mOwner = aNewOwner;
|
||||||
mImage = aNewOwner->mImage;
|
mOwnerHasImage = !!GetStatusTracker().GetImage();
|
||||||
|
|
||||||
// If we were locked, apply the locks here
|
// If we were locked, apply the locks here
|
||||||
for (uint32_t i = 0; i < oldLockCount; i++)
|
for (uint32_t i = 0; i < oldLockCount; i++)
|
||||||
@ -151,13 +151,12 @@ nsresult imgRequestProxy::ChangeOwner(imgRequest *aNewOwner)
|
|||||||
|
|
||||||
// Were we decoded before?
|
// Were we decoded before?
|
||||||
bool wasDecoded = false;
|
bool wasDecoded = false;
|
||||||
if (mImage &&
|
if (GetImage() &&
|
||||||
(mImage->GetStatusTracker().GetImageStatus() &
|
(GetStatusTracker().GetImageStatus() & imgIRequest::STATUS_FRAME_COMPLETE)) {
|
||||||
imgIRequest::STATUS_FRAME_COMPLETE)) {
|
|
||||||
wasDecoded = true;
|
wasDecoded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
mOwner->RemoveProxy(this, NS_IMAGELIB_CHANGING_OWNER);
|
oldOwner->RemoveProxy(this, NS_IMAGELIB_CHANGING_OWNER);
|
||||||
|
|
||||||
// If we had animation requests, restore them here. Note that we
|
// If we had animation requests, restore them here. Note that we
|
||||||
// do this *after* RemoveProxy, which clears out animation consumers
|
// do this *after* RemoveProxy, which clears out animation consumers
|
||||||
@ -165,8 +164,6 @@ nsresult imgRequestProxy::ChangeOwner(imgRequest *aNewOwner)
|
|||||||
for (uint32_t i = 0; i < oldAnimationConsumers; i++)
|
for (uint32_t i = 0; i < oldAnimationConsumers; i++)
|
||||||
IncrementAnimationConsumers();
|
IncrementAnimationConsumers();
|
||||||
|
|
||||||
mOwner = aNewOwner;
|
|
||||||
|
|
||||||
mOwner->AddProxy(this);
|
mOwner->AddProxy(this);
|
||||||
|
|
||||||
// If we were decoded, or if we'd previously requested a decode, request a
|
// If we were decoded, or if we'd previously requested a decode, request a
|
||||||
@ -329,8 +326,8 @@ NS_IMETHODIMP
|
|||||||
imgRequestProxy::LockImage()
|
imgRequestProxy::LockImage()
|
||||||
{
|
{
|
||||||
mLockCount++;
|
mLockCount++;
|
||||||
if (mImage)
|
if (GetImage())
|
||||||
return mImage->LockImage();
|
return GetImage()->LockImage();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,8 +338,8 @@ imgRequestProxy::UnlockImage()
|
|||||||
NS_ABORT_IF_FALSE(mLockCount > 0, "calling unlock but no locks!");
|
NS_ABORT_IF_FALSE(mLockCount > 0, "calling unlock but no locks!");
|
||||||
|
|
||||||
mLockCount--;
|
mLockCount--;
|
||||||
if (mImage)
|
if (GetImage())
|
||||||
return mImage->UnlockImage();
|
return GetImage()->UnlockImage();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,9 +347,8 @@ imgRequestProxy::UnlockImage()
|
|||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
imgRequestProxy::RequestDiscard()
|
imgRequestProxy::RequestDiscard()
|
||||||
{
|
{
|
||||||
if (mImage) {
|
if (GetImage())
|
||||||
return mImage->RequestDiscard();
|
return GetImage()->RequestDiscard();
|
||||||
}
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,8 +356,8 @@ NS_IMETHODIMP
|
|||||||
imgRequestProxy::IncrementAnimationConsumers()
|
imgRequestProxy::IncrementAnimationConsumers()
|
||||||
{
|
{
|
||||||
mAnimationConsumers++;
|
mAnimationConsumers++;
|
||||||
if (mImage)
|
if (GetImage())
|
||||||
mImage->IncrementAnimationConsumers();
|
GetImage()->IncrementAnimationConsumers();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,8 +372,8 @@ imgRequestProxy::DecrementAnimationConsumers()
|
|||||||
// early, but not the observer.)
|
// early, but not the observer.)
|
||||||
if (mAnimationConsumers > 0) {
|
if (mAnimationConsumers > 0) {
|
||||||
mAnimationConsumers--;
|
mAnimationConsumers--;
|
||||||
if (mImage)
|
if (GetImage())
|
||||||
mImage->DecrementAnimationConsumers();
|
GetImage()->DecrementAnimationConsumers();
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -434,7 +430,7 @@ NS_IMETHODIMP imgRequestProxy::GetImage(imgIContainer * *aImage)
|
|||||||
// that'll happen if we get Canceled before the owner instantiates its image
|
// that'll happen if we get Canceled before the owner instantiates its image
|
||||||
// (because Canceling unregisters us as a listener on mOwner). If we're
|
// (because Canceling unregisters us as a listener on mOwner). If we're
|
||||||
// in that situation, just grab the image off of mOwner.
|
// in that situation, just grab the image off of mOwner.
|
||||||
imgIContainer* imageToReturn = mImage ? mImage : mOwner->mImage;
|
imgIContainer* imageToReturn = GetImage() ? GetImage() : mOwner->mImage.get();
|
||||||
|
|
||||||
if (!imageToReturn)
|
if (!imageToReturn)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
@ -463,11 +459,11 @@ NS_IMETHODIMP imgRequestProxy::GetURI(nsIURI **aURI)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* readonly attribute imgIDecoderObserver decoderObserver; */
|
/* readonly attribute imgINotificationObserver notificationObserver; */
|
||||||
NS_IMETHODIMP imgRequestProxy::GetDecoderObserver(imgIDecoderObserver **aDecoderObserver)
|
NS_IMETHODIMP imgRequestProxy::GetNotificationObserver(imgINotificationObserver **aObserver)
|
||||||
{
|
{
|
||||||
*aDecoderObserver = mListener;
|
*aObserver = mListener;
|
||||||
NS_IF_ADDREF(*aDecoderObserver);
|
NS_IF_ADDREF(*aObserver);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,7 +482,27 @@ NS_IMETHODIMP imgRequestProxy::GetMimeType(char **aMimeType)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP imgRequestProxy::Clone(imgIDecoderObserver* aObserver,
|
static imgRequestProxy* NewProxy(imgRequestProxy* /*aThis*/)
|
||||||
|
{
|
||||||
|
return new imgRequestProxy();
|
||||||
|
}
|
||||||
|
|
||||||
|
imgRequestProxy* NewStaticProxy(imgRequestProxy* aThis)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIPrincipal> currentPrincipal;
|
||||||
|
aThis->GetImagePrincipal(getter_AddRefs(currentPrincipal));
|
||||||
|
return new imgRequestProxyStatic(
|
||||||
|
static_cast<imgRequestProxyStatic*>(aThis)->mImage, currentPrincipal);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP imgRequestProxy::Clone(imgINotificationObserver* aObserver,
|
||||||
|
imgIRequest** aClone)
|
||||||
|
{
|
||||||
|
return PerformClone(aObserver, NewProxy, aClone);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult imgRequestProxy::PerformClone(imgINotificationObserver* aObserver,
|
||||||
|
imgRequestProxy* (aAllocFn)(imgRequestProxy*),
|
||||||
imgIRequest** aClone)
|
imgIRequest** aClone)
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aClone, "Null out param");
|
NS_PRECONDITION(aClone, "Null out param");
|
||||||
@ -494,7 +510,7 @@ NS_IMETHODIMP imgRequestProxy::Clone(imgIDecoderObserver* aObserver,
|
|||||||
LOG_SCOPE(gImgLog, "imgRequestProxy::Clone");
|
LOG_SCOPE(gImgLog, "imgRequestProxy::Clone");
|
||||||
|
|
||||||
*aClone = nullptr;
|
*aClone = nullptr;
|
||||||
nsRefPtr<imgRequestProxy> clone = new imgRequestProxy();
|
nsRefPtr<imgRequestProxy> clone = aAllocFn(this);
|
||||||
|
|
||||||
// It is important to call |SetLoadFlags()| before calling |Init()| because
|
// It is important to call |SetLoadFlags()| before calling |Init()| because
|
||||||
// |Init()| adds the request to the loadgroup.
|
// |Init()| adds the request to the loadgroup.
|
||||||
@ -503,14 +519,10 @@ NS_IMETHODIMP imgRequestProxy::Clone(imgIDecoderObserver* aObserver,
|
|||||||
// XXXldb That's not true anymore. Stuff from imgLoader adds the
|
// XXXldb That's not true anymore. Stuff from imgLoader adds the
|
||||||
// request to the loadgroup.
|
// request to the loadgroup.
|
||||||
clone->SetLoadFlags(mLoadFlags);
|
clone->SetLoadFlags(mLoadFlags);
|
||||||
nsresult rv = clone->Init(mOwner, mLoadGroup,
|
nsresult rv = clone->Init(&GetStatusTracker(), mLoadGroup, mURI, aObserver);
|
||||||
mImage ? mImage : mOwner->mImage,
|
|
||||||
mURI, aObserver);
|
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
clone->SetPrincipal(mPrincipal);
|
|
||||||
|
|
||||||
// Assign to *aClone before calling Notify so that if the caller expects to
|
// Assign to *aClone before calling Notify so that if the caller expects to
|
||||||
// only be notified for requests it's already holding pointers to it won't be
|
// only be notified for requests it's already holding pointers to it won't be
|
||||||
// surprised.
|
// surprised.
|
||||||
@ -526,11 +538,10 @@ NS_IMETHODIMP imgRequestProxy::Clone(imgIDecoderObserver* aObserver,
|
|||||||
/* readonly attribute nsIPrincipal imagePrincipal; */
|
/* readonly attribute nsIPrincipal imagePrincipal; */
|
||||||
NS_IMETHODIMP imgRequestProxy::GetImagePrincipal(nsIPrincipal **aPrincipal)
|
NS_IMETHODIMP imgRequestProxy::GetImagePrincipal(nsIPrincipal **aPrincipal)
|
||||||
{
|
{
|
||||||
if (!mPrincipal)
|
if (!mOwner)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
NS_ADDREF(*aPrincipal = mPrincipal);
|
NS_ADDREF(*aPrincipal = mOwner->GetPrincipal());
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -601,102 +612,55 @@ NS_IMETHODIMP imgRequestProxy::GetHasTransferredData(bool* hasData)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** imgIContainerObserver methods **/
|
|
||||||
|
|
||||||
void imgRequestProxy::FrameChanged(imgIContainer *container,
|
|
||||||
const nsIntRect *dirtyRect)
|
|
||||||
{
|
|
||||||
LOG_FUNC(gImgLog, "imgRequestProxy::FrameChanged");
|
|
||||||
|
|
||||||
if (mListener && !mCanceled) {
|
|
||||||
// Hold a ref to the listener while we call it, just in case.
|
|
||||||
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
|
||||||
mListener->FrameChanged(this, container, dirtyRect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** imgIDecoderObserver methods **/
|
/** imgIDecoderObserver methods **/
|
||||||
|
|
||||||
void imgRequestProxy::OnStartDecode()
|
void imgRequestProxy::OnStartContainer()
|
||||||
{
|
|
||||||
LOG_FUNC(gImgLog, "imgRequestProxy::OnStartDecode");
|
|
||||||
|
|
||||||
if (mListener && !mCanceled) {
|
|
||||||
// Hold a ref to the listener while we call it, just in case.
|
|
||||||
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
|
||||||
mListener->OnStartDecode(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void imgRequestProxy::OnStartContainer(imgIContainer *image)
|
|
||||||
{
|
{
|
||||||
LOG_FUNC(gImgLog, "imgRequestProxy::OnStartContainer");
|
LOG_FUNC(gImgLog, "imgRequestProxy::OnStartContainer");
|
||||||
|
|
||||||
if (mListener && !mCanceled && !mSentStartContainer) {
|
if (mListener && !mCanceled && !mSentStartContainer) {
|
||||||
// Hold a ref to the listener while we call it, just in case.
|
// Hold a ref to the listener while we call it, just in case.
|
||||||
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
|
||||||
mListener->OnStartContainer(this, image);
|
mListener->Notify(this, imgINotificationObserver::SIZE_AVAILABLE, nullptr);
|
||||||
mSentStartContainer = true;
|
mSentStartContainer = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void imgRequestProxy::OnStartFrame(uint32_t frame)
|
void imgRequestProxy::OnFrameUpdate(const nsIntRect * rect)
|
||||||
{
|
|
||||||
LOG_FUNC(gImgLog, "imgRequestProxy::OnStartFrame");
|
|
||||||
|
|
||||||
if (mListener && !mCanceled) {
|
|
||||||
// Hold a ref to the listener while we call it, just in case.
|
|
||||||
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
|
||||||
mListener->OnStartFrame(this, frame);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void imgRequestProxy::OnDataAvailable(bool aCurrentFrame, const nsIntRect * rect)
|
|
||||||
{
|
{
|
||||||
LOG_FUNC(gImgLog, "imgRequestProxy::OnDataAvailable");
|
LOG_FUNC(gImgLog, "imgRequestProxy::OnDataAvailable");
|
||||||
|
|
||||||
if (mListener && !mCanceled) {
|
if (mListener && !mCanceled) {
|
||||||
// Hold a ref to the listener while we call it, just in case.
|
// Hold a ref to the listener while we call it, just in case.
|
||||||
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
|
||||||
mListener->OnDataAvailable(this, aCurrentFrame, rect);
|
mListener->Notify(this, imgINotificationObserver::FRAME_UPDATE, rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void imgRequestProxy::OnStopFrame(uint32_t frame)
|
void imgRequestProxy::OnStopFrame()
|
||||||
{
|
{
|
||||||
LOG_FUNC(gImgLog, "imgRequestProxy::OnStopFrame");
|
LOG_FUNC(gImgLog, "imgRequestProxy::OnStopFrame");
|
||||||
|
|
||||||
if (mListener && !mCanceled) {
|
if (mListener && !mCanceled) {
|
||||||
// Hold a ref to the listener while we call it, just in case.
|
// Hold a ref to the listener while we call it, just in case.
|
||||||
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
|
||||||
mListener->OnStopFrame(this, frame);
|
mListener->Notify(this, imgINotificationObserver::FRAME_COMPLETE, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void imgRequestProxy::OnStopContainer(imgIContainer *image)
|
void imgRequestProxy::OnStopDecode()
|
||||||
{
|
|
||||||
LOG_FUNC(gImgLog, "imgRequestProxy::OnStopContainer");
|
|
||||||
|
|
||||||
if (mListener && !mCanceled) {
|
|
||||||
// Hold a ref to the listener while we call it, just in case.
|
|
||||||
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
|
||||||
mListener->OnStopContainer(this, image);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Multipart needs reset for next OnStartContainer
|
|
||||||
if (mOwner && mOwner->GetMultipart())
|
|
||||||
mSentStartContainer = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void imgRequestProxy::OnStopDecode(nsresult status, const PRUnichar *statusArg)
|
|
||||||
{
|
{
|
||||||
LOG_FUNC(gImgLog, "imgRequestProxy::OnStopDecode");
|
LOG_FUNC(gImgLog, "imgRequestProxy::OnStopDecode");
|
||||||
|
|
||||||
if (mListener && !mCanceled) {
|
if (mListener && !mCanceled) {
|
||||||
// Hold a ref to the listener while we call it, just in case.
|
// Hold a ref to the listener while we call it, just in case.
|
||||||
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
|
||||||
mListener->OnStopDecode(this, status, statusArg);
|
mListener->Notify(this, imgINotificationObserver::DECODE_COMPLETE, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Multipart needs reset for next OnStartContainer
|
||||||
|
if (mOwner && mOwner->GetMultipart())
|
||||||
|
mSentStartContainer = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void imgRequestProxy::OnDiscard()
|
void imgRequestProxy::OnDiscard()
|
||||||
@ -705,8 +669,8 @@ void imgRequestProxy::OnDiscard()
|
|||||||
|
|
||||||
if (mListener && !mCanceled) {
|
if (mListener && !mCanceled) {
|
||||||
// Hold a ref to the listener while we call it, just in case.
|
// Hold a ref to the listener while we call it, just in case.
|
||||||
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
|
||||||
mListener->OnDiscard(this);
|
mListener->Notify(this, imgINotificationObserver::DISCARD, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -715,8 +679,8 @@ void imgRequestProxy::OnImageIsAnimated()
|
|||||||
LOG_FUNC(gImgLog, "imgRequestProxy::OnImageIsAnimated");
|
LOG_FUNC(gImgLog, "imgRequestProxy::OnImageIsAnimated");
|
||||||
if (mListener && !mCanceled) {
|
if (mListener && !mCanceled) {
|
||||||
// Hold a ref to the listener while we call it, just in case.
|
// Hold a ref to the listener while we call it, just in case.
|
||||||
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
|
||||||
mListener->OnImageIsAnimated(this);
|
mListener->Notify(this, imgINotificationObserver::IS_ANIMATED, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -727,14 +691,6 @@ void imgRequestProxy::OnStartRequest()
|
|||||||
GetName(name);
|
GetName(name);
|
||||||
LOG_FUNC_WITH_PARAM(gImgLog, "imgRequestProxy::OnStartRequest", "name", name.get());
|
LOG_FUNC_WITH_PARAM(gImgLog, "imgRequestProxy::OnStartRequest", "name", name.get());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Notify even if mCanceled, since OnStartRequest is guaranteed by the
|
|
||||||
// nsIStreamListener contract so it makes sense to do the same here.
|
|
||||||
if (mListener) {
|
|
||||||
// Hold a ref to the listener while we call it, just in case.
|
|
||||||
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
|
||||||
mListener->OnStartRequest(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void imgRequestProxy::OnStopRequest(bool lastPart)
|
void imgRequestProxy::OnStopRequest(bool lastPart)
|
||||||
@ -751,8 +707,8 @@ void imgRequestProxy::OnStopRequest(bool lastPart)
|
|||||||
|
|
||||||
if (mListener) {
|
if (mListener) {
|
||||||
// Hold a ref to the listener while we call it, just in case.
|
// Hold a ref to the listener while we call it, just in case.
|
||||||
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
|
||||||
mListener->OnStopRequest(this, lastPart);
|
mListener->Notify(this, imgINotificationObserver::LOAD_COMPLETE, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're expecting more data from a multipart channel, re-add ourself
|
// If we're expecting more data from a multipart channel, re-add ourself
|
||||||
@ -774,7 +730,7 @@ void imgRequestProxy::OnStopRequest(bool lastPart)
|
|||||||
// Drop our strong ref to the listener now that we're done with
|
// Drop our strong ref to the listener now that we're done with
|
||||||
// everything. Note that this can cancel us and other fun things
|
// everything. Note that this can cancel us and other fun things
|
||||||
// like that. Don't add anything in this method after this point.
|
// like that. Don't add anything in this method after this point.
|
||||||
imgIDecoderObserver* obs = mListener;
|
imgINotificationObserver* obs = mListener;
|
||||||
mListenerIsStrongRef = false;
|
mListenerIsStrongRef = false;
|
||||||
NS_RELEASE(obs);
|
NS_RELEASE(obs);
|
||||||
}
|
}
|
||||||
@ -816,7 +772,7 @@ void imgRequestProxy::NullOutListener()
|
|||||||
|
|
||||||
if (mListenerIsStrongRef) {
|
if (mListenerIsStrongRef) {
|
||||||
// Releasing could do weird reentery stuff, so just play it super-safe
|
// Releasing could do weird reentery stuff, so just play it super-safe
|
||||||
nsCOMPtr<imgIDecoderObserver> obs;
|
nsCOMPtr<imgINotificationObserver> obs;
|
||||||
obs.swap(mListener);
|
obs.swap(mListener);
|
||||||
mListenerIsStrongRef = false;
|
mListenerIsStrongRef = false;
|
||||||
} else {
|
} else {
|
||||||
@ -828,9 +784,10 @@ NS_IMETHODIMP
|
|||||||
imgRequestProxy::GetStaticRequest(imgIRequest** aReturn)
|
imgRequestProxy::GetStaticRequest(imgIRequest** aReturn)
|
||||||
{
|
{
|
||||||
*aReturn = nullptr;
|
*aReturn = nullptr;
|
||||||
|
mozilla::image::Image* image = GetImage();
|
||||||
|
|
||||||
bool animated;
|
bool animated;
|
||||||
if (!mImage || (NS_SUCCEEDED(mImage->GetAnimated(&animated)) && !animated)) {
|
if (!image || (NS_SUCCEEDED(image->GetAnimated(&animated)) && !animated)) {
|
||||||
// Early exit - we're not animated, so we don't have to do anything.
|
// Early exit - we're not animated, so we don't have to do anything.
|
||||||
NS_ADDREF(*aReturn = this);
|
NS_ADDREF(*aReturn = this);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -839,11 +796,11 @@ imgRequestProxy::GetStaticRequest(imgIRequest** aReturn)
|
|||||||
// We are animated. We need to extract the current frame from this image.
|
// We are animated. We need to extract the current frame from this image.
|
||||||
int32_t w = 0;
|
int32_t w = 0;
|
||||||
int32_t h = 0;
|
int32_t h = 0;
|
||||||
mImage->GetWidth(&w);
|
image->GetWidth(&w);
|
||||||
mImage->GetHeight(&h);
|
image->GetHeight(&h);
|
||||||
nsIntRect rect(0, 0, w, h);
|
nsIntRect rect(0, 0, w, h);
|
||||||
nsCOMPtr<imgIContainer> currentFrame;
|
nsCOMPtr<imgIContainer> currentFrame;
|
||||||
nsresult rv = mImage->ExtractFrame(imgIContainer::FRAME_CURRENT, rect,
|
nsresult rv = image->ExtractFrame(imgIContainer::FRAME_CURRENT, rect,
|
||||||
imgIContainer::FLAG_SYNC_DECODE,
|
imgIContainer::FLAG_SYNC_DECODE,
|
||||||
getter_AddRefs(currentFrame));
|
getter_AddRefs(currentFrame));
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
@ -852,20 +809,16 @@ imgRequestProxy::GetStaticRequest(imgIRequest** aReturn)
|
|||||||
nsRefPtr<Image> frame = static_cast<Image*>(currentFrame.get());
|
nsRefPtr<Image> frame = static_cast<Image*>(currentFrame.get());
|
||||||
|
|
||||||
// Create a static imgRequestProxy with our new extracted frame.
|
// Create a static imgRequestProxy with our new extracted frame.
|
||||||
nsRefPtr<imgRequestProxy> req = new imgRequestProxy();
|
nsCOMPtr<nsIPrincipal> currentPrincipal;
|
||||||
req->Init(nullptr, nullptr, frame, mURI, nullptr);
|
GetImagePrincipal(getter_AddRefs(currentPrincipal));
|
||||||
req->SetPrincipal(mPrincipal);
|
nsRefPtr<imgRequestProxy> req = new imgRequestProxyStatic(frame, currentPrincipal);
|
||||||
|
req->Init(&frame->GetStatusTracker(), nullptr, mURI, nullptr);
|
||||||
|
|
||||||
NS_ADDREF(*aReturn = req);
|
NS_ADDREF(*aReturn = req);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void imgRequestProxy::SetPrincipal(nsIPrincipal *aPrincipal)
|
|
||||||
{
|
|
||||||
mPrincipal = aPrincipal;
|
|
||||||
}
|
|
||||||
|
|
||||||
void imgRequestProxy::NotifyListener()
|
void imgRequestProxy::NotifyListener()
|
||||||
{
|
{
|
||||||
// It would be nice to notify the observer directly in the status tracker
|
// It would be nice to notify the observer directly in the status tracker
|
||||||
@ -879,9 +832,9 @@ void imgRequestProxy::NotifyListener()
|
|||||||
} else {
|
} else {
|
||||||
// We don't have an imgRequest, so we can only notify the clone of our
|
// We don't have an imgRequest, so we can only notify the clone of our
|
||||||
// current state, but we still have to do that asynchronously.
|
// current state, but we still have to do that asynchronously.
|
||||||
NS_ABORT_IF_FALSE(mImage,
|
NS_ABORT_IF_FALSE(GetImage(),
|
||||||
"if we have no imgRequest, we should have an Image");
|
"if we have no imgRequest, we should have an Image");
|
||||||
mImage->GetStatusTracker().NotifyCurrentState(this);
|
GetStatusTracker().NotifyCurrentState(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -896,25 +849,23 @@ void imgRequestProxy::SyncNotifyListener()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
imgRequestProxy::SetImage(Image* aImage)
|
imgRequestProxy::SetHasImage()
|
||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(aImage, "Setting null image");
|
Image* image = GetStatusTracker().GetImage();
|
||||||
NS_ABORT_IF_FALSE(!mImage || mOwner->GetMultipart(),
|
|
||||||
"Setting image when we already have one");
|
|
||||||
|
|
||||||
mImage = aImage;
|
mOwnerHasImage = true;
|
||||||
|
|
||||||
// Apply any locks we have
|
// Apply any locks we have
|
||||||
for (uint32_t i = 0; i < mLockCount; ++i)
|
for (uint32_t i = 0; i < mLockCount; ++i)
|
||||||
mImage->LockImage();
|
image->LockImage();
|
||||||
|
|
||||||
// Apply any animation consumers we have
|
// Apply any animation consumers we have
|
||||||
for (uint32_t i = 0; i < mAnimationConsumers; i++)
|
for (uint32_t i = 0; i < mAnimationConsumers; i++)
|
||||||
mImage->IncrementAnimationConsumers();
|
image->IncrementAnimationConsumers();
|
||||||
}
|
}
|
||||||
|
|
||||||
imgStatusTracker&
|
imgStatusTracker&
|
||||||
imgRequestProxy::GetStatusTracker()
|
imgRequestProxy::GetStatusTracker() const
|
||||||
{
|
{
|
||||||
// NOTE: It's possible that our mOwner has an Image that it didn't notify
|
// NOTE: It's possible that our mOwner has an Image that it didn't notify
|
||||||
// us about, if we were Canceled before its Image was constructed.
|
// us about, if we were Canceled before its Image was constructed.
|
||||||
@ -922,5 +873,44 @@ imgRequestProxy::GetStatusTracker()
|
|||||||
// That's why this method uses mOwner->GetStatusTracker() instead of just
|
// That's why this method uses mOwner->GetStatusTracker() instead of just
|
||||||
// mOwner->mStatusTracker -- we might have a null mImage and yet have an
|
// mOwner->mStatusTracker -- we might have a null mImage and yet have an
|
||||||
// mOwner with a non-null mImage (and a null mStatusTracker pointer).
|
// mOwner with a non-null mImage (and a null mStatusTracker pointer).
|
||||||
return mImage ? mImage->GetStatusTracker() : mOwner->GetStatusTracker();
|
return mOwner->GetStatusTracker();
|
||||||
|
}
|
||||||
|
|
||||||
|
mozilla::image::Image*
|
||||||
|
imgRequestProxy::GetImage() const
|
||||||
|
{
|
||||||
|
if (!mOwnerHasImage)
|
||||||
|
return nullptr;
|
||||||
|
return GetStatusTracker().GetImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////// imgRequestProxyStatic methods
|
||||||
|
|
||||||
|
NS_IMETHODIMP imgRequestProxyStatic::GetImagePrincipal(nsIPrincipal **aPrincipal)
|
||||||
|
{
|
||||||
|
if (!mPrincipal)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
NS_ADDREF(*aPrincipal = mPrincipal);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
mozilla::image::Image*
|
||||||
|
imgRequestProxyStatic::GetImage() const
|
||||||
|
{
|
||||||
|
return mImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
imgStatusTracker&
|
||||||
|
imgRequestProxyStatic::GetStatusTracker() const
|
||||||
|
{
|
||||||
|
return mImage->GetStatusTracker();
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
imgRequestProxyStatic::Clone(imgINotificationObserver* aObserver,
|
||||||
|
imgIRequest** aClone)
|
||||||
|
{
|
||||||
|
return PerformClone(aObserver, NewStaticProxy, aClone);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#define imgRequestProxy_h__
|
#define imgRequestProxy_h__
|
||||||
|
|
||||||
#include "imgIRequest.h"
|
#include "imgIRequest.h"
|
||||||
#include "imgIDecoderObserver.h"
|
#include "imgINotificationObserver.h"
|
||||||
#include "nsISecurityInfoProvider.h"
|
#include "nsISecurityInfoProvider.h"
|
||||||
|
|
||||||
#include "nsIRequestObserver.h"
|
#include "nsIRequestObserver.h"
|
||||||
@ -57,9 +57,9 @@ public:
|
|||||||
|
|
||||||
// Callers to Init or ChangeOwner are required to call NotifyListener after
|
// Callers to Init or ChangeOwner are required to call NotifyListener after
|
||||||
// (although not immediately after) doing so.
|
// (although not immediately after) doing so.
|
||||||
nsresult Init(imgRequest *request, nsILoadGroup *aLoadGroup,
|
nsresult Init(imgStatusTracker* aStatusTracker,
|
||||||
mozilla::image::Image* aImage,
|
nsILoadGroup *aLoadGroup,
|
||||||
nsIURI* aURI, imgIDecoderObserver *aObserver);
|
nsIURI* aURI, imgINotificationObserver *aObserver);
|
||||||
|
|
||||||
nsresult ChangeOwner(imgRequest *aNewOwner); // this will change mOwner. Do not call this if the previous
|
nsresult ChangeOwner(imgRequest *aNewOwner); // this will change mOwner. Do not call this if the previous
|
||||||
// owner has already sent notifications out!
|
// owner has already sent notifications out!
|
||||||
@ -71,8 +71,6 @@ public:
|
|||||||
return mListener != nullptr;
|
return mListener != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPrincipal(nsIPrincipal *aPrincipal);
|
|
||||||
|
|
||||||
// Asynchronously notify this proxy's listener of the current state of the
|
// Asynchronously notify this proxy's listener of the current state of the
|
||||||
// image, and, if we have an imgRequest mOwner, any status changes that
|
// image, and, if we have an imgRequest mOwner, any status changes that
|
||||||
// happen between the time this function is called and the time the
|
// happen between the time this function is called and the time the
|
||||||
@ -95,9 +93,8 @@ public:
|
|||||||
mDeferNotifications = aDeferNotifications;
|
mDeferNotifications = aDeferNotifications;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setter for our |mImage| pointer, for imgRequest to use, once it
|
// XXXbholley - This eventually gets folded into the new notification API.
|
||||||
// instantiates an Image.
|
void SetHasImage();
|
||||||
void SetImage(mozilla::image::Image* aImage);
|
|
||||||
|
|
||||||
// Removes all animation consumers that were created with
|
// Removes all animation consumers that were created with
|
||||||
// IncrementAnimationConsumers. This is necessary since we need
|
// IncrementAnimationConsumers. This is necessary since we need
|
||||||
@ -135,20 +132,13 @@ protected:
|
|||||||
// notifications.
|
// notifications.
|
||||||
|
|
||||||
/* non-virtual imgIDecoderObserver methods */
|
/* non-virtual imgIDecoderObserver methods */
|
||||||
void OnStartDecode ();
|
void OnStartContainer ();
|
||||||
void OnStartContainer (imgIContainer *aContainer);
|
void OnFrameUpdate (const nsIntRect * aRect);
|
||||||
void OnStartFrame (uint32_t aFrame);
|
void OnStopFrame ();
|
||||||
void OnDataAvailable (bool aCurrentFrame, const nsIntRect * aRect);
|
void OnStopDecode ();
|
||||||
void OnStopFrame (uint32_t aFrame);
|
|
||||||
void OnStopContainer (imgIContainer *aContainer);
|
|
||||||
void OnStopDecode (nsresult status, const PRUnichar *statusArg);
|
|
||||||
void OnDiscard ();
|
void OnDiscard ();
|
||||||
void OnImageIsAnimated ();
|
void OnImageIsAnimated ();
|
||||||
|
|
||||||
/* non-virtual imgIContainerObserver methods */
|
|
||||||
void FrameChanged(imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect);
|
|
||||||
|
|
||||||
/* non-virtual sort-of-nsIRequestObserver methods */
|
/* non-virtual sort-of-nsIRequestObserver methods */
|
||||||
void OnStartRequest();
|
void OnStartRequest();
|
||||||
void OnStopRequest(bool aLastPart);
|
void OnStopRequest(bool aLastPart);
|
||||||
@ -171,7 +161,7 @@ protected:
|
|||||||
// live either on mOwner or mImage, depending on whether
|
// live either on mOwner or mImage, depending on whether
|
||||||
// (a) we have an mOwner at all
|
// (a) we have an mOwner at all
|
||||||
// (b) whether mOwner has instantiated its image yet
|
// (b) whether mOwner has instantiated its image yet
|
||||||
imgStatusTracker& GetStatusTracker();
|
virtual imgStatusTracker& GetStatusTracker() const;
|
||||||
|
|
||||||
nsITimedChannel* TimedChannel()
|
nsITimedChannel* TimedChannel()
|
||||||
{
|
{
|
||||||
@ -180,6 +170,12 @@ protected:
|
|||||||
return mOwner->mTimedChannel;
|
return mOwner->mTimedChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual mozilla::image::Image* GetImage() const;
|
||||||
|
|
||||||
|
nsresult PerformClone(imgINotificationObserver* aObserver,
|
||||||
|
imgRequestProxy* (aAllocFn)(imgRequestProxy*),
|
||||||
|
imgIRequest** aClone);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_FORWARD_SAFE_NSITIMEDCHANNEL(TimedChannel())
|
NS_FORWARD_SAFE_NSITIMEDCHANNEL(TimedChannel())
|
||||||
|
|
||||||
@ -197,18 +193,10 @@ private:
|
|||||||
// The URI of our request.
|
// The URI of our request.
|
||||||
nsCOMPtr<nsIURI> mURI;
|
nsCOMPtr<nsIURI> mURI;
|
||||||
|
|
||||||
// The image we represent. Is null until data has been received, and is then
|
|
||||||
// set by imgRequest.
|
|
||||||
nsRefPtr<mozilla::image::Image> mImage;
|
|
||||||
|
|
||||||
// Our principal. Is null until data has been received from the channel, and
|
|
||||||
// is then set by imgRequest.
|
|
||||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
|
||||||
|
|
||||||
// mListener is only promised to be a weak ref (see imgILoader.idl),
|
// mListener is only promised to be a weak ref (see imgILoader.idl),
|
||||||
// but we actually keep a strong ref to it until we've seen our
|
// but we actually keep a strong ref to it until we've seen our
|
||||||
// first OnStopRequest.
|
// first OnStopRequest.
|
||||||
imgIDecoderObserver* mListener;
|
imgINotificationObserver* mListener;
|
||||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||||
|
|
||||||
nsLoadFlags mLoadFlags;
|
nsLoadFlags mLoadFlags;
|
||||||
@ -226,6 +214,44 @@ private:
|
|||||||
// We only want to send OnStartContainer once for each proxy, but we might
|
// We only want to send OnStartContainer once for each proxy, but we might
|
||||||
// get multiple OnStartContainer calls.
|
// get multiple OnStartContainer calls.
|
||||||
bool mSentStartContainer;
|
bool mSentStartContainer;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool mOwnerHasImage;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Used for static image proxies for which no requests are available, so
|
||||||
|
// certain behaviours must be overridden to compensate.
|
||||||
|
class imgRequestProxyStatic : public imgRequestProxy
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
imgRequestProxyStatic(mozilla::image::Image* aImage,
|
||||||
|
nsIPrincipal* aPrincipal)
|
||||||
|
: mImage(aImage)
|
||||||
|
, mPrincipal(aPrincipal)
|
||||||
|
{
|
||||||
|
mOwnerHasImage = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_IMETHOD GetImagePrincipal(nsIPrincipal** aPrincipal) MOZ_OVERRIDE;
|
||||||
|
virtual imgStatusTracker& GetStatusTracker() const MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
NS_IMETHOD Clone(imgINotificationObserver* aObserver,
|
||||||
|
imgIRequest** aClone) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend imgRequestProxy* NewStaticProxy(imgRequestProxy*);
|
||||||
|
|
||||||
|
// Our image. We have to hold a strong reference here, because that's normally
|
||||||
|
// the job of the underlying request.
|
||||||
|
nsRefPtr<mozilla::image::Image> mImage;
|
||||||
|
|
||||||
|
// Our principal. We have to cache it, rather than accessing the underlying
|
||||||
|
// request on-demand, because static proxies don't have an underlying request.
|
||||||
|
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||||
|
|
||||||
|
mozilla::image::Image* GetImage() const MOZ_OVERRIDE;
|
||||||
|
using imgRequestProxy::GetImage;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // imgRequestProxy_h__
|
#endif // imgRequestProxy_h__
|
||||||
|
@ -12,31 +12,230 @@
|
|||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
#include "ImageLogging.h"
|
#include "ImageLogging.h"
|
||||||
#include "RasterImage.h"
|
#include "RasterImage.h"
|
||||||
|
#include "nsIObserverService.h"
|
||||||
|
|
||||||
|
#include "mozilla/Util.h"
|
||||||
|
#include "mozilla/Assertions.h"
|
||||||
|
#include "mozilla/Services.h"
|
||||||
|
|
||||||
using namespace mozilla::image;
|
using namespace mozilla::image;
|
||||||
|
|
||||||
static nsresult
|
NS_IMPL_ISUPPORTS3(imgStatusTrackerObserver,
|
||||||
GetResultFromImageStatus(uint32_t aStatus)
|
imgIDecoderObserver,
|
||||||
|
imgIContainerObserver,
|
||||||
|
nsISupportsWeakReference)
|
||||||
|
|
||||||
|
/** imgIContainerObserver methods **/
|
||||||
|
|
||||||
|
/* [noscript] void frameChanged (in nsIntRect dirtyRect); */
|
||||||
|
NS_IMETHODIMP imgStatusTrackerObserver::FrameChanged(const nsIntRect *dirtyRect)
|
||||||
{
|
{
|
||||||
if (aStatus & imgIRequest::STATUS_ERROR)
|
LOG_SCOPE(gImgLog, "imgStatusTrackerObserver::FrameChanged");
|
||||||
return NS_IMAGELIB_ERROR_FAILURE;
|
NS_ABORT_IF_FALSE(mTracker->GetImage(),
|
||||||
if (aStatus & imgIRequest::STATUS_LOAD_COMPLETE)
|
"FrameChanged callback before we've created our image");
|
||||||
return NS_IMAGELIB_SUCCESS_LOAD_FINISHED;
|
|
||||||
|
mTracker->RecordFrameChanged(dirtyRect);
|
||||||
|
|
||||||
|
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
|
||||||
|
while (iter.HasMore()) {
|
||||||
|
mTracker->SendFrameChanged(iter.GetNext(), dirtyRect);
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
imgStatusTracker::imgStatusTracker(Image* aImage)
|
/** imgIDecoderObserver methods **/
|
||||||
|
|
||||||
|
NS_IMETHODIMP imgStatusTrackerObserver::OnStartDecode()
|
||||||
|
{
|
||||||
|
LOG_SCOPE(gImgLog, "imgStatusTrackerObserver::OnStartDecode");
|
||||||
|
NS_ABORT_IF_FALSE(mTracker->GetImage(),
|
||||||
|
"OnStartDecode callback before we've created our image");
|
||||||
|
|
||||||
|
if (!mTracker->GetRequest()->GetMultipart()) {
|
||||||
|
MOZ_ASSERT(!mTracker->mBlockingOnload);
|
||||||
|
mTracker->mBlockingOnload = true;
|
||||||
|
|
||||||
|
mTracker->RecordBlockOnload();
|
||||||
|
|
||||||
|
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
|
||||||
|
while (iter.HasMore()) {
|
||||||
|
mTracker->SendBlockOnload(iter.GetNext());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In the case of streaming jpegs, it is possible to get multiple OnStartDecodes which
|
||||||
|
indicates the beginning of a new decode.
|
||||||
|
The cache entry's size therefore needs to be reset to 0 here. If we do not do this,
|
||||||
|
the code in imgStatusTrackerObserver::OnStopFrame will continue to increase the data size cumulatively.
|
||||||
|
*/
|
||||||
|
mTracker->GetRequest()->ResetCacheEntry();
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP imgStatusTrackerObserver::OnStartRequest()
|
||||||
|
{
|
||||||
|
NS_NOTREACHED("imgRequest(imgIDecoderObserver)::OnStartRequest");
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* void onStartContainer (); */
|
||||||
|
NS_IMETHODIMP imgStatusTrackerObserver::OnStartContainer()
|
||||||
|
{
|
||||||
|
LOG_SCOPE(gImgLog, "imgStatusTrackerObserver::OnStartContainer");
|
||||||
|
|
||||||
|
NS_ABORT_IF_FALSE(mTracker->GetImage(),
|
||||||
|
"OnStartContainer callback before we've created our image");
|
||||||
|
mTracker->RecordStartContainer(mTracker->GetImage());
|
||||||
|
|
||||||
|
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
|
||||||
|
while (iter.HasMore()) {
|
||||||
|
mTracker->SendStartContainer(iter.GetNext());
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [noscript] void onDataAvailable ([const] in nsIntRect rect); */
|
||||||
|
NS_IMETHODIMP imgStatusTrackerObserver::OnDataAvailable(const nsIntRect * rect)
|
||||||
|
{
|
||||||
|
LOG_SCOPE(gImgLog, "imgStatusTrackerObserver::OnDataAvailable");
|
||||||
|
NS_ABORT_IF_FALSE(mTracker->GetImage(),
|
||||||
|
"OnDataAvailable callback before we've created our image");
|
||||||
|
|
||||||
|
mTracker->RecordDataAvailable();
|
||||||
|
|
||||||
|
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
|
||||||
|
while (iter.HasMore()) {
|
||||||
|
mTracker->SendDataAvailable(iter.GetNext(), rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* void onStopFrame (); */
|
||||||
|
NS_IMETHODIMP imgStatusTrackerObserver::OnStopFrame()
|
||||||
|
{
|
||||||
|
LOG_SCOPE(gImgLog, "imgStatusTrackerObserver::OnStopFrame");
|
||||||
|
NS_ABORT_IF_FALSE(mTracker->GetImage(),
|
||||||
|
"OnStopFrame callback before we've created our image");
|
||||||
|
|
||||||
|
mTracker->RecordStopFrame();
|
||||||
|
|
||||||
|
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
|
||||||
|
while (iter.HasMore()) {
|
||||||
|
mTracker->SendStopFrame(iter.GetNext());
|
||||||
|
}
|
||||||
|
|
||||||
|
mTracker->MaybeUnblockOnload();
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
FireFailureNotification(imgRequest* aRequest)
|
||||||
|
{
|
||||||
|
// Some kind of problem has happened with image decoding.
|
||||||
|
// Report the URI to net:failed-to-process-uri-conent observers.
|
||||||
|
|
||||||
|
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||||
|
if (os) {
|
||||||
|
nsCOMPtr<nsIURI> uri;
|
||||||
|
aRequest->GetURI(getter_AddRefs(uri));
|
||||||
|
os->NotifyObservers(uri, "net:failed-to-process-uri-content", nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* void onStopDecode (in nsresult status); */
|
||||||
|
NS_IMETHODIMP imgStatusTrackerObserver::OnStopDecode(nsresult aStatus)
|
||||||
|
{
|
||||||
|
LOG_SCOPE(gImgLog, "imgStatusTrackerObserver::OnStopDecode");
|
||||||
|
NS_ABORT_IF_FALSE(mTracker->GetImage(),
|
||||||
|
"OnStopDecode callback before we've created our image");
|
||||||
|
|
||||||
|
// We finished the decode, and thus have the decoded frames. Update the cache
|
||||||
|
// entry size to take this into account.
|
||||||
|
mTracker->GetRequest()->UpdateCacheEntrySize();
|
||||||
|
|
||||||
|
bool preexistingError = mTracker->GetImageStatus() == imgIRequest::STATUS_ERROR;
|
||||||
|
|
||||||
|
mTracker->RecordStopDecode(aStatus);
|
||||||
|
|
||||||
|
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
|
||||||
|
while (iter.HasMore()) {
|
||||||
|
mTracker->SendStopDecode(iter.GetNext(), aStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is really hacky. We need to handle the case where we start decoding,
|
||||||
|
// block onload, but then hit an error before we get to our first frame.
|
||||||
|
mTracker->MaybeUnblockOnload();
|
||||||
|
|
||||||
|
if (NS_FAILED(aStatus) && !preexistingError) {
|
||||||
|
FireFailureNotification(mTracker->GetRequest());
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP imgStatusTrackerObserver::OnStopRequest(bool aLastPart)
|
||||||
|
{
|
||||||
|
NS_NOTREACHED("imgRequest(imgIDecoderObserver)::OnStopRequest");
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* void onDiscard (); */
|
||||||
|
NS_IMETHODIMP imgStatusTrackerObserver::OnDiscard()
|
||||||
|
{
|
||||||
|
NS_ABORT_IF_FALSE(mTracker->GetImage(),
|
||||||
|
"OnDiscard callback before we've created our image");
|
||||||
|
|
||||||
|
mTracker->RecordDiscard();
|
||||||
|
|
||||||
|
// Update the cache entry size, since we just got rid of frame data
|
||||||
|
mTracker->GetRequest()->UpdateCacheEntrySize();
|
||||||
|
|
||||||
|
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
|
||||||
|
while (iter.HasMore()) {
|
||||||
|
mTracker->SendDiscard(iter.GetNext());
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP imgStatusTrackerObserver::OnImageIsAnimated()
|
||||||
|
{
|
||||||
|
NS_ABORT_IF_FALSE(mTracker->GetImage(),
|
||||||
|
"OnImageIsAnimated callback before we've created our image");
|
||||||
|
mTracker->RecordImageIsAnimated();
|
||||||
|
|
||||||
|
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
|
||||||
|
while (iter.HasMore()) {
|
||||||
|
mTracker->SendImageIsAnimated(iter.GetNext());
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// imgStatusTracker methods
|
||||||
|
|
||||||
|
imgStatusTracker::imgStatusTracker(Image* aImage, imgRequest* aRequest)
|
||||||
: mImage(aImage),
|
: mImage(aImage),
|
||||||
|
mRequest(aRequest),
|
||||||
mState(0),
|
mState(0),
|
||||||
mImageStatus(imgIRequest::STATUS_NONE),
|
mImageStatus(imgIRequest::STATUS_NONE),
|
||||||
mHadLastPart(false)
|
mHadLastPart(false),
|
||||||
|
mBlockingOnload(false),
|
||||||
|
mTrackerObserver(new imgStatusTrackerObserver(this))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
imgStatusTracker::imgStatusTracker(const imgStatusTracker& aOther)
|
imgStatusTracker::imgStatusTracker(const imgStatusTracker& aOther)
|
||||||
: mImage(aOther.mImage),
|
: mImage(aOther.mImage),
|
||||||
|
mRequest(aOther.mRequest),
|
||||||
mState(aOther.mState),
|
mState(aOther.mState),
|
||||||
mImageStatus(aOther.mImageStatus),
|
mImageStatus(aOther.mImageStatus),
|
||||||
mHadLastPart(aOther.mHadLastPart)
|
mHadLastPart(aOther.mHadLastPart),
|
||||||
|
mBlockingOnload(aOther.mBlockingOnload)
|
||||||
// Note: we explicitly don't copy mRequestRunnable, because it won't be
|
// Note: we explicitly don't copy mRequestRunnable, because it won't be
|
||||||
// nulled out when the mRequestRunnable's Run function eventually gets
|
// nulled out when the mRequestRunnable's Run function eventually gets
|
||||||
// called.
|
// called.
|
||||||
@ -194,11 +393,7 @@ imgStatusTracker::SyncNotify(imgRequestProxy* proxy)
|
|||||||
|
|
||||||
// OnStartContainer
|
// OnStartContainer
|
||||||
if (mState & stateHasSize)
|
if (mState & stateHasSize)
|
||||||
proxy->OnStartContainer(mImage);
|
proxy->OnStartContainer();
|
||||||
|
|
||||||
// OnStartDecode
|
|
||||||
if (mState & stateDecodeStarted)
|
|
||||||
proxy->OnStartDecode();
|
|
||||||
|
|
||||||
// BlockOnload
|
// BlockOnload
|
||||||
if (mState & stateBlockingOnload)
|
if (mState & stateBlockingOnload)
|
||||||
@ -206,24 +401,19 @@ imgStatusTracker::SyncNotify(imgRequestProxy* proxy)
|
|||||||
|
|
||||||
if (mImage) {
|
if (mImage) {
|
||||||
int16_t imageType = mImage->GetType();
|
int16_t imageType = mImage->GetType();
|
||||||
// Send frame messages (OnStartFrame, OnDataAvailable, OnStopFrame)
|
// Send frame messages (OnDataAvailable, OnStopFrame)
|
||||||
if (imageType == imgIContainer::TYPE_VECTOR ||
|
if (imageType == imgIContainer::TYPE_VECTOR ||
|
||||||
static_cast<RasterImage*>(mImage)->GetNumFrames() > 0) {
|
static_cast<RasterImage*>(mImage)->GetNumFrames() > 0) {
|
||||||
|
|
||||||
uint32_t frame = (imageType == imgIContainer::TYPE_VECTOR) ?
|
|
||||||
0 : static_cast<RasterImage*>(mImage)->GetCurrentFrameIndex();
|
|
||||||
|
|
||||||
proxy->OnStartFrame(frame);
|
|
||||||
|
|
||||||
// OnDataAvailable
|
// OnDataAvailable
|
||||||
// XXX - Should only send partial rects here, but that needs to
|
// XXX - Should only send partial rects here, but that needs to
|
||||||
// wait until we fix up the observer interface
|
// wait until we fix up the observer interface
|
||||||
nsIntRect r;
|
nsIntRect r;
|
||||||
mImage->GetCurrentFrameRect(r);
|
mImage->GetCurrentFrameRect(r);
|
||||||
proxy->OnDataAvailable(frame, &r);
|
proxy->OnFrameUpdate(&r);
|
||||||
|
|
||||||
if (mState & stateFrameStopped)
|
if (mState & stateFrameStopped)
|
||||||
proxy->OnStopFrame(frame);
|
proxy->OnStopFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnImageIsAnimated
|
// OnImageIsAnimated
|
||||||
@ -235,16 +425,12 @@ imgStatusTracker::SyncNotify(imgRequestProxy* proxy)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// See bug 505385 and imgRequest::OnStopDecode for more information on why we
|
|
||||||
// call OnStopContainer based on stateDecodeStopped, and why OnStopDecode is
|
|
||||||
// called with OnStopRequest.
|
|
||||||
if (mState & stateDecodeStopped) {
|
if (mState & stateDecodeStopped) {
|
||||||
NS_ABORT_IF_FALSE(mImage, "stopped decoding without ever having an image?");
|
NS_ABORT_IF_FALSE(mImage, "stopped decoding without ever having an image?");
|
||||||
proxy->OnStopContainer(mImage);
|
proxy->OnStopDecode();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mState & stateRequestStopped) {
|
if (mState & stateRequestStopped) {
|
||||||
proxy->OnStopDecode(GetResultFromImageStatus(mImageStatus), nullptr);
|
|
||||||
proxy->OnStopRequest(mHadLastPart);
|
proxy->OnStopRequest(mHadLastPart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,6 +441,12 @@ imgStatusTracker::EmulateRequestFinished(imgRequestProxy* aProxy,
|
|||||||
{
|
{
|
||||||
nsCOMPtr<imgIRequest> kungFuDeathGrip(aProxy);
|
nsCOMPtr<imgIRequest> kungFuDeathGrip(aProxy);
|
||||||
|
|
||||||
|
// In certain cases the request might not have started yet.
|
||||||
|
// We still need to fulfill the contract.
|
||||||
|
if (!(mState & stateRequestStarted)) {
|
||||||
|
aProxy->OnStartRequest();
|
||||||
|
}
|
||||||
|
|
||||||
if (mState & stateBlockingOnload) {
|
if (mState & stateBlockingOnload) {
|
||||||
aProxy->UnblockOnload();
|
aProxy->UnblockOnload();
|
||||||
}
|
}
|
||||||
@ -264,6 +456,26 @@ imgStatusTracker::EmulateRequestFinished(imgRequestProxy* aProxy,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
imgStatusTracker::AddConsumer(imgRequestProxy* aConsumer)
|
||||||
|
{
|
||||||
|
mConsumers.AppendElementUnlessExists(aConsumer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX - The last argument should go away.
|
||||||
|
bool
|
||||||
|
imgStatusTracker::RemoveConsumer(imgRequestProxy* aConsumer, nsresult aStatus)
|
||||||
|
{
|
||||||
|
// Remove the proxy from the list.
|
||||||
|
bool removed = mConsumers.RemoveElement(aConsumer);
|
||||||
|
|
||||||
|
// Consumers can get confused if they don't get all the proper teardown
|
||||||
|
// notifications. Part ways on good terms.
|
||||||
|
if (removed)
|
||||||
|
EmulateRequestFinished(aConsumer, aStatus);
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
imgStatusTracker::RecordCancel()
|
imgStatusTracker::RecordCancel()
|
||||||
{
|
{
|
||||||
@ -284,25 +496,10 @@ void
|
|||||||
imgStatusTracker::RecordDecoded()
|
imgStatusTracker::RecordDecoded()
|
||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(mImage, "RecordDecoded called before we have an Image");
|
NS_ABORT_IF_FALSE(mImage, "RecordDecoded called before we have an Image");
|
||||||
mState |= stateDecodeStarted | stateDecodeStopped | stateFrameStopped;
|
mState |= stateDecodeStopped | stateFrameStopped;
|
||||||
mImageStatus |= imgIRequest::STATUS_FRAME_COMPLETE | imgIRequest::STATUS_DECODE_COMPLETE;
|
mImageStatus |= imgIRequest::STATUS_FRAME_COMPLETE | imgIRequest::STATUS_DECODE_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* non-virtual imgIDecoderObserver methods */
|
|
||||||
void
|
|
||||||
imgStatusTracker::RecordStartDecode()
|
|
||||||
{
|
|
||||||
NS_ABORT_IF_FALSE(mImage, "RecordStartDecode without an Image");
|
|
||||||
mState |= stateDecodeStarted;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
imgStatusTracker::SendStartDecode(imgRequestProxy* aProxy)
|
|
||||||
{
|
|
||||||
if (!aProxy->NotificationsDeferred())
|
|
||||||
aProxy->OnStartDecode();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
imgStatusTracker::RecordStartContainer(imgIContainer* aContainer)
|
imgStatusTracker::RecordStartContainer(imgIContainer* aContainer)
|
||||||
{
|
{
|
||||||
@ -315,29 +512,14 @@ imgStatusTracker::RecordStartContainer(imgIContainer* aContainer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
imgStatusTracker::SendStartContainer(imgRequestProxy* aProxy, imgIContainer* aContainer)
|
imgStatusTracker::SendStartContainer(imgRequestProxy* aProxy)
|
||||||
{
|
{
|
||||||
if (!aProxy->NotificationsDeferred())
|
if (!aProxy->NotificationsDeferred())
|
||||||
aProxy->OnStartContainer(aContainer);
|
aProxy->OnStartContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
imgStatusTracker::RecordStartFrame(uint32_t aFrame)
|
imgStatusTracker::RecordDataAvailable()
|
||||||
{
|
|
||||||
NS_ABORT_IF_FALSE(mImage, "RecordStartFrame called before we have an Image");
|
|
||||||
// no bookkeeping necessary here - this is implied by imgIContainer's number
|
|
||||||
// of frames
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
imgStatusTracker::SendStartFrame(imgRequestProxy* aProxy, uint32_t aFrame)
|
|
||||||
{
|
|
||||||
if (!aProxy->NotificationsDeferred())
|
|
||||||
aProxy->OnStartFrame(aFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
imgStatusTracker::RecordDataAvailable(bool aCurrentFrame, const nsIntRect* aRect)
|
|
||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(mImage,
|
NS_ABORT_IF_FALSE(mImage,
|
||||||
"RecordDataAvailable called before we have an Image");
|
"RecordDataAvailable called before we have an Image");
|
||||||
@ -346,16 +528,16 @@ imgStatusTracker::RecordDataAvailable(bool aCurrentFrame, const nsIntRect* aRect
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
imgStatusTracker::SendDataAvailable(imgRequestProxy* aProxy, bool aCurrentFrame,
|
imgStatusTracker::SendDataAvailable(imgRequestProxy* aProxy,
|
||||||
const nsIntRect* aRect)
|
const nsIntRect* aRect)
|
||||||
{
|
{
|
||||||
if (!aProxy->NotificationsDeferred())
|
if (!aProxy->NotificationsDeferred())
|
||||||
aProxy->OnDataAvailable(aCurrentFrame, aRect);
|
aProxy->OnFrameUpdate(aRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
imgStatusTracker::RecordStopFrame(uint32_t aFrame)
|
imgStatusTracker::RecordStopFrame()
|
||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(mImage, "RecordStopFrame called before we have an Image");
|
NS_ABORT_IF_FALSE(mImage, "RecordStopFrame called before we have an Image");
|
||||||
mState |= stateFrameStopped;
|
mState |= stateFrameStopped;
|
||||||
@ -363,34 +545,20 @@ imgStatusTracker::RecordStopFrame(uint32_t aFrame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
imgStatusTracker::SendStopFrame(imgRequestProxy* aProxy, uint32_t aFrame)
|
imgStatusTracker::SendStopFrame(imgRequestProxy* aProxy)
|
||||||
{
|
{
|
||||||
if (!aProxy->NotificationsDeferred())
|
if (!aProxy->NotificationsDeferred())
|
||||||
aProxy->OnStopFrame(aFrame);
|
aProxy->OnStopFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
imgStatusTracker::RecordStopContainer(imgIContainer* aContainer)
|
imgStatusTracker::RecordStopDecode(nsresult aStatus)
|
||||||
{
|
|
||||||
NS_ABORT_IF_FALSE(mImage,
|
|
||||||
"RecordStopContainer called before we have an Image");
|
|
||||||
// No-op: see imgRequest::OnStopDecode for more information
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
imgStatusTracker::SendStopContainer(imgRequestProxy* aProxy, imgIContainer* aContainer)
|
|
||||||
{
|
|
||||||
// No-op: see imgRequest::OnStopDecode for more information
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
imgStatusTracker::RecordStopDecode(nsresult aStatus, const PRUnichar* statusArg)
|
|
||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(mImage,
|
NS_ABORT_IF_FALSE(mImage,
|
||||||
"RecordStopDecode called before we have an Image");
|
"RecordStopDecode called before we have an Image");
|
||||||
mState |= stateDecodeStopped;
|
mState |= stateDecodeStopped;
|
||||||
|
|
||||||
if (NS_SUCCEEDED(aStatus))
|
if (NS_SUCCEEDED(aStatus) && mImageStatus != imgIRequest::STATUS_ERROR)
|
||||||
mImageStatus |= imgIRequest::STATUS_DECODE_COMPLETE;
|
mImageStatus |= imgIRequest::STATUS_DECODE_COMPLETE;
|
||||||
// If we weren't successful, clear all success status bits and set error.
|
// If we weren't successful, clear all success status bits and set error.
|
||||||
else
|
else
|
||||||
@ -398,14 +566,11 @@ imgStatusTracker::RecordStopDecode(nsresult aStatus, const PRUnichar* statusArg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
imgStatusTracker::SendStopDecode(imgRequestProxy* aProxy, nsresult aStatus,
|
imgStatusTracker::SendStopDecode(imgRequestProxy* aProxy,
|
||||||
const PRUnichar* statusArg)
|
nsresult aStatus)
|
||||||
{
|
{
|
||||||
// See imgRequest::OnStopDecode for more information on why we call
|
|
||||||
// OnStopContainer from here this, and why imgRequestProxy::OnStopDecode() is
|
|
||||||
// called from OnStopRequest() and SyncNotify().
|
|
||||||
if (!aProxy->NotificationsDeferred())
|
if (!aProxy->NotificationsDeferred())
|
||||||
aProxy->OnStopContainer(mImage);
|
aProxy->OnStopDecode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -414,7 +579,7 @@ imgStatusTracker::RecordDiscard()
|
|||||||
NS_ABORT_IF_FALSE(mImage,
|
NS_ABORT_IF_FALSE(mImage,
|
||||||
"RecordDiscard called before we have an Image");
|
"RecordDiscard called before we have an Image");
|
||||||
// Clear the state bits we no longer deserve.
|
// Clear the state bits we no longer deserve.
|
||||||
uint32_t stateBitsToClear = stateDecodeStarted | stateDecodeStopped;
|
uint32_t stateBitsToClear = stateDecodeStopped;
|
||||||
mState &= ~stateBitsToClear;
|
mState &= ~stateBitsToClear;
|
||||||
|
|
||||||
// Clear the status bits we no longer deserve.
|
// Clear the status bits we no longer deserve.
|
||||||
@ -450,8 +615,7 @@ imgStatusTracker::SendDiscard(imgRequestProxy* aProxy)
|
|||||||
|
|
||||||
/* non-virtual imgIContainerObserver methods */
|
/* non-virtual imgIContainerObserver methods */
|
||||||
void
|
void
|
||||||
imgStatusTracker::RecordFrameChanged(imgIContainer* aContainer,
|
imgStatusTracker::RecordFrameChanged(const nsIntRect* aDirtyRect)
|
||||||
const nsIntRect* aDirtyRect)
|
|
||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(mImage,
|
NS_ABORT_IF_FALSE(mImage,
|
||||||
"RecordFrameChanged called before we have an Image");
|
"RecordFrameChanged called before we have an Image");
|
||||||
@ -460,11 +624,11 @@ imgStatusTracker::RecordFrameChanged(imgIContainer* aContainer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
imgStatusTracker::SendFrameChanged(imgRequestProxy* aProxy, imgIContainer* aContainer,
|
imgStatusTracker::SendFrameChanged(imgRequestProxy* aProxy,
|
||||||
const nsIntRect* aDirtyRect)
|
const nsIntRect* aDirtyRect)
|
||||||
{
|
{
|
||||||
if (!aProxy->NotificationsDeferred())
|
if (!aProxy->NotificationsDeferred())
|
||||||
aProxy->FrameChanged(aContainer, aDirtyRect);
|
aProxy->OnFrameUpdate(aDirtyRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* non-virtual sort-of-nsIRequestObserver methods */
|
/* non-virtual sort-of-nsIRequestObserver methods */
|
||||||
@ -477,7 +641,6 @@ imgStatusTracker::RecordStartRequest()
|
|||||||
mImageStatus &= ~imgIRequest::STATUS_LOAD_COMPLETE;
|
mImageStatus &= ~imgIRequest::STATUS_LOAD_COMPLETE;
|
||||||
mImageStatus &= ~imgIRequest::STATUS_FRAME_COMPLETE;
|
mImageStatus &= ~imgIRequest::STATUS_FRAME_COMPLETE;
|
||||||
mState &= ~stateRequestStarted;
|
mState &= ~stateRequestStarted;
|
||||||
mState &= ~stateDecodeStarted;
|
|
||||||
mState &= ~stateDecodeStopped;
|
mState &= ~stateDecodeStopped;
|
||||||
mState &= ~stateRequestStopped;
|
mState &= ~stateRequestStopped;
|
||||||
mState &= ~stateBlockingOnload;
|
mState &= ~stateBlockingOnload;
|
||||||
@ -493,27 +656,67 @@ imgStatusTracker::SendStartRequest(imgRequestProxy* aProxy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
imgStatusTracker::RecordStopRequest(bool aLastPart, nsresult aStatus)
|
imgStatusTracker::OnStartRequest()
|
||||||
|
{
|
||||||
|
RecordStartRequest();
|
||||||
|
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mConsumers);
|
||||||
|
while (iter.HasMore()) {
|
||||||
|
SendStartRequest(iter.GetNext());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
imgStatusTracker::RecordStopRequest(bool aLastPart,
|
||||||
|
nsresult aStatus)
|
||||||
{
|
{
|
||||||
mHadLastPart = aLastPart;
|
mHadLastPart = aLastPart;
|
||||||
mState |= stateRequestStopped;
|
mState |= stateRequestStopped;
|
||||||
|
|
||||||
// If we were successful in loading, note that the image is complete.
|
// If we were successful in loading, note that the image is complete.
|
||||||
if (NS_SUCCEEDED(aStatus))
|
if (NS_SUCCEEDED(aStatus) && mImageStatus != imgIRequest::STATUS_ERROR)
|
||||||
mImageStatus |= imgIRequest::STATUS_LOAD_COMPLETE;
|
mImageStatus |= imgIRequest::STATUS_LOAD_COMPLETE;
|
||||||
|
else
|
||||||
|
mImageStatus = imgIRequest::STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
imgStatusTracker::SendStopRequest(imgRequestProxy* aProxy, bool aLastPart, nsresult aStatus)
|
imgStatusTracker::SendStopRequest(imgRequestProxy* aProxy,
|
||||||
|
bool aLastPart,
|
||||||
|
nsresult aStatus)
|
||||||
{
|
{
|
||||||
// See bug 505385 and imgRequest::OnStopDecode for more information on why
|
|
||||||
// OnStopDecode is called with OnStopRequest.
|
|
||||||
if (!aProxy->NotificationsDeferred()) {
|
if (!aProxy->NotificationsDeferred()) {
|
||||||
aProxy->OnStopDecode(GetResultFromImageStatus(mImageStatus), nullptr);
|
|
||||||
aProxy->OnStopRequest(aLastPart);
|
aProxy->OnStopRequest(aLastPart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
imgStatusTracker::OnStopRequest(bool aLastPart,
|
||||||
|
nsresult aStatus)
|
||||||
|
{
|
||||||
|
bool preexistingError = mImageStatus == imgIRequest::STATUS_ERROR;
|
||||||
|
|
||||||
|
RecordStopRequest(aLastPart, aStatus);
|
||||||
|
/* notify the kids */
|
||||||
|
nsTObserverArray<imgRequestProxy*>::ForwardIterator srIter(mConsumers);
|
||||||
|
while (srIter.HasMore()) {
|
||||||
|
SendStopRequest(srIter.GetNext(), aLastPart, aStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NS_FAILED(aStatus) && !preexistingError) {
|
||||||
|
FireFailureNotification(GetRequest());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
imgStatusTracker::OnDataAvailable()
|
||||||
|
{
|
||||||
|
// Notify any imgRequestProxys that are observing us that we have an Image.
|
||||||
|
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mConsumers);
|
||||||
|
while (iter.HasMore()) {
|
||||||
|
iter.GetNext()->SetHasImage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
imgStatusTracker::RecordBlockOnload()
|
imgStatusTracker::RecordBlockOnload()
|
||||||
{
|
{
|
||||||
@ -543,3 +746,20 @@ imgStatusTracker::SendUnblockOnload(imgRequestProxy* aProxy)
|
|||||||
aProxy->UnblockOnload();
|
aProxy->UnblockOnload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
imgStatusTracker::MaybeUnblockOnload()
|
||||||
|
{
|
||||||
|
if (!mBlockingOnload) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mBlockingOnload = false;
|
||||||
|
|
||||||
|
RecordUnblockOnload();
|
||||||
|
|
||||||
|
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mConsumers);
|
||||||
|
while (iter.HasMore()) {
|
||||||
|
SendUnblockOnload(iter.GetNext());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -12,6 +12,7 @@ class imgRequest;
|
|||||||
class imgRequestProxy;
|
class imgRequestProxy;
|
||||||
class imgStatusNotifyRunnable;
|
class imgStatusNotifyRunnable;
|
||||||
class imgRequestNotifyRunnable;
|
class imgRequestNotifyRunnable;
|
||||||
|
class imgStatusTracker;
|
||||||
struct nsIntRect;
|
struct nsIntRect;
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace image {
|
namespace image {
|
||||||
@ -21,19 +22,43 @@ class Image;
|
|||||||
|
|
||||||
|
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsTObserverArray.h"
|
||||||
#include "nsIRunnable.h"
|
#include "nsIRunnable.h"
|
||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
|
#include "nsWeakReference.h"
|
||||||
|
#include "imgIDecoderObserver.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
stateRequestStarted = PR_BIT(0),
|
stateRequestStarted = PR_BIT(0),
|
||||||
stateHasSize = PR_BIT(1),
|
stateHasSize = PR_BIT(1),
|
||||||
stateDecodeStarted = PR_BIT(2),
|
|
||||||
stateDecodeStopped = PR_BIT(3),
|
stateDecodeStopped = PR_BIT(3),
|
||||||
stateFrameStopped = PR_BIT(4),
|
stateFrameStopped = PR_BIT(4),
|
||||||
stateRequestStopped = PR_BIT(5),
|
stateRequestStopped = PR_BIT(5),
|
||||||
stateBlockingOnload = PR_BIT(6)
|
stateBlockingOnload = PR_BIT(6)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class imgStatusTrackerObserver : public imgIDecoderObserver,
|
||||||
|
public nsSupportsWeakReference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_IMGIDECODEROBSERVER
|
||||||
|
NS_DECL_IMGICONTAINEROBSERVER
|
||||||
|
|
||||||
|
imgStatusTrackerObserver(imgStatusTracker* aTracker)
|
||||||
|
: mTracker(aTracker) {}
|
||||||
|
|
||||||
|
virtual ~imgStatusTrackerObserver() {}
|
||||||
|
|
||||||
|
void SetTracker(imgStatusTracker* aTracker) {
|
||||||
|
mTracker = aTracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
imgStatusTracker* mTracker;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The image status tracker is a class that encapsulates all the loading and
|
* The image status tracker is a class that encapsulates all the loading and
|
||||||
* decoding status about an Image, and makes it possible to send notifications
|
* decoding status about an Image, and makes it possible to send notifications
|
||||||
@ -51,7 +76,7 @@ public:
|
|||||||
// aImage is the image that this status tracker will pass to the
|
// aImage is the image that this status tracker will pass to the
|
||||||
// imgRequestProxys in SyncNotify() and EmulateRequestFinished(), and must be
|
// imgRequestProxys in SyncNotify() and EmulateRequestFinished(), and must be
|
||||||
// alive as long as this instance is, because we hold a weak reference to it.
|
// alive as long as this instance is, because we hold a weak reference to it.
|
||||||
imgStatusTracker(mozilla::image::Image* aImage);
|
imgStatusTracker(mozilla::image::Image* aImage, imgRequest* aRequest);
|
||||||
imgStatusTracker(const imgStatusTracker& aOther);
|
imgStatusTracker(const imgStatusTracker& aOther);
|
||||||
|
|
||||||
// Image-setter, for imgStatusTrackers created by imgRequest::Init, which
|
// Image-setter, for imgStatusTrackers created by imgRequest::Init, which
|
||||||
@ -85,6 +110,21 @@ public:
|
|||||||
// OnStopRequest and UnblockOnload, and only if necessary.
|
// OnStopRequest and UnblockOnload, and only if necessary.
|
||||||
void EmulateRequestFinished(imgRequestProxy* proxy, nsresult aStatus);
|
void EmulateRequestFinished(imgRequestProxy* proxy, nsresult aStatus);
|
||||||
|
|
||||||
|
// We manage a set of consumers that are using an image and thus concerned
|
||||||
|
// with its status. Weak pointers.
|
||||||
|
void AddConsumer(imgRequestProxy* aConsumer);
|
||||||
|
bool RemoveConsumer(imgRequestProxy* aConsumer, nsresult aStatus);
|
||||||
|
size_t ConsumerCount() const { return mConsumers.Length(); };
|
||||||
|
|
||||||
|
// This is intentionally non-general because its sole purpose is to support an
|
||||||
|
// some obscure network priority logic in imgRequest. That stuff could probably
|
||||||
|
// be improved, but it's too scary to mess with at the moment.
|
||||||
|
bool FirstConsumerIs(imgRequestProxy* aConsumer) {
|
||||||
|
return mConsumers.SafeElementAt(0, nullptr) == aConsumer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdoptConsumers(imgStatusTracker* aTracker) { mConsumers = aTracker->mConsumers; }
|
||||||
|
|
||||||
// Returns whether we are in the process of loading; that is, whether we have
|
// Returns whether we are in the process of loading; that is, whether we have
|
||||||
// not received OnStopRequest.
|
// not received OnStopRequest.
|
||||||
bool IsLoading() const;
|
bool IsLoading() const;
|
||||||
@ -104,34 +144,26 @@ public:
|
|||||||
void RecordLoaded();
|
void RecordLoaded();
|
||||||
|
|
||||||
// Shorthand for recording all the decode notifications: StartDecode,
|
// Shorthand for recording all the decode notifications: StartDecode,
|
||||||
// StartFrame, DataAvailable, StopFrame, StopContainer, StopDecode.
|
// StartFrame, DataAvailable, StopFrame, StopDecode.
|
||||||
void RecordDecoded();
|
void RecordDecoded();
|
||||||
|
|
||||||
/* non-virtual imgIDecoderObserver methods */
|
/* non-virtual imgIDecoderObserver methods */
|
||||||
void RecordStartDecode();
|
|
||||||
void SendStartDecode(imgRequestProxy* aProxy);
|
|
||||||
void RecordStartContainer(imgIContainer* aContainer);
|
void RecordStartContainer(imgIContainer* aContainer);
|
||||||
void SendStartContainer(imgRequestProxy* aProxy, imgIContainer* aContainer);
|
void SendStartContainer(imgRequestProxy* aProxy);
|
||||||
void RecordStartFrame(uint32_t aFrame);
|
void RecordDataAvailable();
|
||||||
void SendStartFrame(imgRequestProxy* aProxy, uint32_t aFrame);
|
void SendDataAvailable(imgRequestProxy* aProxy, const nsIntRect* aRect);
|
||||||
void RecordDataAvailable(bool aCurrentFrame, const nsIntRect* aRect);
|
void RecordStopFrame();
|
||||||
void SendDataAvailable(imgRequestProxy* aProxy, bool aCurrentFrame, const nsIntRect* aRect);
|
void SendStopFrame(imgRequestProxy* aProxy);
|
||||||
void RecordStopFrame(uint32_t aFrame);
|
void RecordStopDecode(nsresult statusg);
|
||||||
void SendStopFrame(imgRequestProxy* aProxy, uint32_t aFrame);
|
void SendStopDecode(imgRequestProxy* aProxy, nsresult aStatus);
|
||||||
void RecordStopContainer(imgIContainer* aContainer);
|
|
||||||
void SendStopContainer(imgRequestProxy* aProxy, imgIContainer* aContainer);
|
|
||||||
void RecordStopDecode(nsresult status, const PRUnichar* statusArg);
|
|
||||||
void SendStopDecode(imgRequestProxy* aProxy, nsresult aStatus, const PRUnichar* statusArg);
|
|
||||||
void RecordDiscard();
|
void RecordDiscard();
|
||||||
void SendDiscard(imgRequestProxy* aProxy);
|
void SendDiscard(imgRequestProxy* aProxy);
|
||||||
void RecordImageIsAnimated();
|
void RecordImageIsAnimated();
|
||||||
void SendImageIsAnimated(imgRequestProxy *aProxy);
|
void SendImageIsAnimated(imgRequestProxy *aProxy);
|
||||||
|
|
||||||
/* non-virtual imgIContainerObserver methods */
|
/* non-virtual imgIContainerObserver methods */
|
||||||
void RecordFrameChanged(imgIContainer* aContainer,
|
void RecordFrameChanged(const nsIntRect* aDirtyRect);
|
||||||
const nsIntRect* aDirtyRect);
|
void SendFrameChanged(imgRequestProxy* aProxy, const nsIntRect* aDirtyRect);
|
||||||
void SendFrameChanged(imgRequestProxy* aProxy, imgIContainer* aContainer,
|
|
||||||
const nsIntRect* aDirtyRect);
|
|
||||||
|
|
||||||
/* non-virtual sort-of-nsIRequestObserver methods */
|
/* non-virtual sort-of-nsIRequestObserver methods */
|
||||||
void RecordStartRequest();
|
void RecordStartRequest();
|
||||||
@ -139,6 +171,10 @@ public:
|
|||||||
void RecordStopRequest(bool aLastPart, nsresult aStatus);
|
void RecordStopRequest(bool aLastPart, nsresult aStatus);
|
||||||
void SendStopRequest(imgRequestProxy* aProxy, bool aLastPart, nsresult aStatus);
|
void SendStopRequest(imgRequestProxy* aProxy, bool aLastPart, nsresult aStatus);
|
||||||
|
|
||||||
|
void OnStartRequest();
|
||||||
|
void OnDataAvailable();
|
||||||
|
void OnStopRequest(bool aLastPart, nsresult aStatus);
|
||||||
|
|
||||||
/* non-virtual imgIOnloadBlocker methods */
|
/* non-virtual imgIOnloadBlocker methods */
|
||||||
// NB: If UnblockOnload is sent, and then we are asked to replay the
|
// NB: If UnblockOnload is sent, and then we are asked to replay the
|
||||||
// notifications, we will not send a BlockOnload/UnblockOnload pair. This
|
// notifications, we will not send a BlockOnload/UnblockOnload pair. This
|
||||||
@ -148,18 +184,35 @@ public:
|
|||||||
void RecordUnblockOnload();
|
void RecordUnblockOnload();
|
||||||
void SendUnblockOnload(imgRequestProxy* aProxy);
|
void SendUnblockOnload(imgRequestProxy* aProxy);
|
||||||
|
|
||||||
|
void MaybeUnblockOnload();
|
||||||
|
|
||||||
|
// Weak pointer getters - no AddRefs.
|
||||||
|
inline mozilla::image::Image* GetImage() const { return mImage; };
|
||||||
|
inline imgRequest* GetRequest() const { return mRequest; };
|
||||||
|
|
||||||
|
inline imgIDecoderObserver* GetDecoderObserver() { return mTrackerObserver.get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class imgStatusNotifyRunnable;
|
friend class imgStatusNotifyRunnable;
|
||||||
friend class imgRequestNotifyRunnable;
|
friend class imgRequestNotifyRunnable;
|
||||||
|
friend class imgStatusTrackerObserver;
|
||||||
|
|
||||||
nsCOMPtr<nsIRunnable> mRequestRunnable;
|
nsCOMPtr<nsIRunnable> mRequestRunnable;
|
||||||
|
|
||||||
// A weak pointer to the Image, because it owns us, and we
|
// Weak pointers to the image and request. The request owns the image, and
|
||||||
// can't create a cycle.
|
// the image (or the request, if there's no image) owns the status tracker.
|
||||||
mozilla::image::Image* mImage;
|
mozilla::image::Image* mImage;
|
||||||
|
imgRequest* mRequest;
|
||||||
uint32_t mState;
|
uint32_t mState;
|
||||||
uint32_t mImageStatus;
|
uint32_t mImageStatus;
|
||||||
bool mHadLastPart;
|
bool mHadLastPart;
|
||||||
|
bool mBlockingOnload;
|
||||||
|
|
||||||
|
// List of proxies attached to the image. Each proxy represents a consumer
|
||||||
|
// using the image.
|
||||||
|
nsTObserverArray<imgRequestProxy*> mConsumers;
|
||||||
|
|
||||||
|
nsRefPtr<imgStatusTrackerObserver> mTrackerObserver;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "RasterImage.h"
|
#include "RasterImage.h"
|
||||||
|
#include "ScriptedNotificationObserver.h"
|
||||||
|
#include "imgIScriptedNotificationObserver.h"
|
||||||
|
|
||||||
using namespace mozilla::image;
|
using namespace mozilla::image;
|
||||||
|
|
||||||
@ -276,6 +278,13 @@ NS_IMETHODIMP imgTools::GetFirstImageFrame(imgIContainer *aContainer,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP imgTools::CreateScriptedObserver(imgIScriptedNotificationObserver* aInner,
|
||||||
|
imgINotificationObserver** aObserver)
|
||||||
|
{
|
||||||
|
NS_ADDREF(*aObserver = new ScriptedNotificationObserver(aInner));
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
imgTools::GetImgLoaderForDocument(nsIDOMDocument* aDoc, imgILoader** aLoader)
|
imgTools::GetImgLoaderForDocument(nsIDOMDocument* aDoc, imgILoader** aLoader)
|
||||||
{
|
{
|
||||||
|
@ -121,15 +121,14 @@ function getImagePref(pref)
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// JS implementation of imgIDecoderObserver with stubs for all of its methods.
|
// JS implementation of imgIScriptedNotificationObserver with stubs for all of its methods.
|
||||||
function ImageDecoderObserverStub()
|
function ImageDecoderObserverStub()
|
||||||
{
|
{
|
||||||
this.onStartRequest = function onStartRequest(aRequest) {}
|
this.sizeAvailable = function sizeAvailable(aRequest) {}
|
||||||
this.onStartDecode = function onStartDecode(aRequest) {}
|
this.frameComplete = function frameComplete(aRequest) {}
|
||||||
this.onStartContainer = function onStartContainer(aRequest, aContainer) {}
|
this.decodeComplete = function decodeComplete(aRequest) {}
|
||||||
this.onStartFrame = function onStartFrame(aRequest, aFrame) {}
|
this.loadComplete = function loadComplete(aRequest) {}
|
||||||
this.onStopFrame = function onStopFrame(aRequest, aFrame) {}
|
this.frameUpdate = function frameUpdate(aRequest) {}
|
||||||
this.onStopContainer = function onStopContainer(aRequest, aContainer) {}
|
this.discard = function discard(aRequest) {}
|
||||||
this.onStopDecode = function onStopDecode(aRequest, status, statusArg) {}
|
this.isAnimated = function isAnimated(aRequest) {}
|
||||||
this.onStopRequest = function onStopRequest(aRequest, aIsLastPart) {}
|
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ SimpleTest.waitForExplicitFinish();
|
|||||||
|
|
||||||
const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
|
const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
|
||||||
|
|
||||||
|
const Cc = Components.classes;
|
||||||
const Ci = Components.interfaces;
|
const Ci = Components.interfaces;
|
||||||
const gImg = document.getElementsByTagName("img")[0];
|
const gImg = document.getElementsByTagName("img")[0];
|
||||||
|
|
||||||
@ -53,7 +54,7 @@ function takeReferenceSnapshot() {
|
|||||||
"reference div should disappear when it becomes display:none");
|
"reference div should disappear when it becomes display:none");
|
||||||
}
|
}
|
||||||
|
|
||||||
function myOnStopFrame(aRequest, aFrame) {
|
function myOnStopFrame(aRequest) {
|
||||||
gOnStopFrameCounter++;
|
gOnStopFrameCounter++;
|
||||||
ok(true, "myOnStopFrame called");
|
ok(true, "myOnStopFrame called");
|
||||||
let currentSnapshot = snapshotWindow(window, false);
|
let currentSnapshot = snapshotWindow(window, false);
|
||||||
@ -89,8 +90,11 @@ function main() {
|
|||||||
takeReferenceSnapshot();
|
takeReferenceSnapshot();
|
||||||
|
|
||||||
// Create, customize & attach decoder observer
|
// Create, customize & attach decoder observer
|
||||||
gMyDecoderObserver = new ImageDecoderObserverStub();
|
observer = new ImageDecoderObserverStub();
|
||||||
gMyDecoderObserver.onStopFrame = myOnStopFrame;
|
observer.frameComplete = myOnStopFrame;
|
||||||
|
gMyDecoderObserver =
|
||||||
|
Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
|
||||||
|
.createScriptedObserver(observer);
|
||||||
let imgLoadingContent = gImg.QueryInterface(Ci.nsIImageLoadingContent);
|
let imgLoadingContent = gImg.QueryInterface(Ci.nsIImageLoadingContent);
|
||||||
imgLoadingContent.addObserver(gMyDecoderObserver);
|
imgLoadingContent.addObserver(gMyDecoderObserver);
|
||||||
|
|
||||||
|
@ -45,12 +45,18 @@ function checkClone(other_listener, aRequest)
|
|||||||
// For as long as clone notification is synchronous, we can't test the clone state reliably.
|
// For as long as clone notification is synchronous, we can't test the clone state reliably.
|
||||||
var listener = new ImageListener(null, function(foo, bar) { do_test_finished(); } /*getCloneStopCallback(other_listener)*/);
|
var listener = new ImageListener(null, function(foo, bar) { do_test_finished(); } /*getCloneStopCallback(other_listener)*/);
|
||||||
listener.synchronous = false;
|
listener.synchronous = false;
|
||||||
var clone = aRequest.clone(listener);
|
var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
|
||||||
|
.createScriptedObserver(listener);
|
||||||
|
var clone = aRequest.clone(outer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that all the callbacks were called on aRequest.
|
// Ensure that all the callbacks were called on aRequest.
|
||||||
function checkAllCallbacks(listener, aRequest)
|
function checkAllCallbacks(listener, aRequest)
|
||||||
{
|
{
|
||||||
|
do_check_neq(listener.state & SIZE_AVAILABLE, 0);
|
||||||
|
do_check_neq(listener.state & FRAME_COMPLETE, 0);
|
||||||
|
do_check_neq(listener.state & DECODE_COMPLETE, 0);
|
||||||
|
do_check_neq(listener.state & LOAD_COMPLETE, 0);
|
||||||
do_check_eq(listener.state, ALL_BITS);
|
do_check_eq(listener.state, ALL_BITS);
|
||||||
|
|
||||||
do_test_finished();
|
do_test_finished();
|
||||||
@ -67,7 +73,9 @@ function secondLoadDone(oldlistener, aRequest)
|
|||||||
// clone state reliably.
|
// clone state reliably.
|
||||||
var listener = new ImageListener(null, checkAllCallbacks);
|
var listener = new ImageListener(null, checkAllCallbacks);
|
||||||
listener.synchronous = false;
|
listener.synchronous = false;
|
||||||
var staticrequestclone = staticrequest.clone(listener);
|
var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
|
||||||
|
.createScriptedObserver(listener);
|
||||||
|
var staticrequestclone = staticrequest.clone(outer);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
// We can't create a static request. Most likely the request we started
|
// We can't create a static request. Most likely the request we started
|
||||||
// with didn't load successfully.
|
// with didn't load successfully.
|
||||||
@ -86,7 +94,9 @@ function checkSecondLoad()
|
|||||||
do_test_pending();
|
do_test_pending();
|
||||||
|
|
||||||
var listener = new ImageListener(checkClone, secondLoadDone);
|
var listener = new ImageListener(checkClone, secondLoadDone);
|
||||||
requests.push(gCurrentLoader.loadImage(uri, null, null, null, null, listener, null, 0, null, null, null));
|
var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
|
||||||
|
.createScriptedObserver(listener);
|
||||||
|
requests.push(gCurrentLoader.loadImage(uri, null, null, null, null, outer, null, 0, null, null, null));
|
||||||
listener.synchronous = false;
|
listener.synchronous = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,10 +112,10 @@ function firstLoadDone(oldlistener, aRequest)
|
|||||||
function getChannelLoadImageStartCallback(streamlistener)
|
function getChannelLoadImageStartCallback(streamlistener)
|
||||||
{
|
{
|
||||||
return function channelLoadStart(imglistener, aRequest) {
|
return function channelLoadStart(imglistener, aRequest) {
|
||||||
// We must not have received any status before we get this start callback.
|
// We must not have received all status before we get this start callback.
|
||||||
// If we have, we've broken people's expectations by delaying events from a
|
// If we have, we've broken people's expectations by delaying events from a
|
||||||
// channel we were given.
|
// channel we were given.
|
||||||
do_check_eq(streamlistener.requestStatus, 0);
|
do_check_eq(streamlistener.requestStatus & STOP_REQUEST, 0);
|
||||||
|
|
||||||
checkClone(imglistener, aRequest);
|
checkClone(imglistener, aRequest);
|
||||||
}
|
}
|
||||||
@ -141,8 +151,10 @@ function checkSecondChannelLoad()
|
|||||||
var listener = new ImageListener(getChannelLoadImageStartCallback(channellistener),
|
var listener = new ImageListener(getChannelLoadImageStartCallback(channellistener),
|
||||||
getChannelLoadImageStopCallback(channellistener,
|
getChannelLoadImageStopCallback(channellistener,
|
||||||
all_done_callback));
|
all_done_callback));
|
||||||
|
var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
|
||||||
|
.createScriptedObserver(listener);
|
||||||
var outlistener = {};
|
var outlistener = {};
|
||||||
requests.push(gCurrentLoader.loadImageWithChannel(channel, listener, null, outlistener));
|
requests.push(gCurrentLoader.loadImageWithChannel(channel, outer, null, outlistener));
|
||||||
channellistener.outputListener = outlistener.value;
|
channellistener.outputListener = outlistener.value;
|
||||||
|
|
||||||
listener.synchronous = false;
|
listener.synchronous = false;
|
||||||
@ -163,8 +175,10 @@ function run_loadImageWithChannel_tests()
|
|||||||
var listener = new ImageListener(getChannelLoadImageStartCallback(channellistener),
|
var listener = new ImageListener(getChannelLoadImageStartCallback(channellistener),
|
||||||
getChannelLoadImageStopCallback(channellistener,
|
getChannelLoadImageStopCallback(channellistener,
|
||||||
checkSecondChannelLoad));
|
checkSecondChannelLoad));
|
||||||
|
var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
|
||||||
|
.createScriptedObserver(listener);
|
||||||
var outlistener = {};
|
var outlistener = {};
|
||||||
requests.push(gCurrentLoader.loadImageWithChannel(channel, listener, null, outlistener));
|
requests.push(gCurrentLoader.loadImageWithChannel(channel, outer, null, outlistener));
|
||||||
channellistener.outputListener = outlistener.value;
|
channellistener.outputListener = outlistener.value;
|
||||||
|
|
||||||
listener.synchronous = false;
|
listener.synchronous = false;
|
||||||
@ -182,7 +196,9 @@ function startImageCallback(otherCb)
|
|||||||
// Make sure we can load the same image immediately out of the cache.
|
// Make sure we can load the same image immediately out of the cache.
|
||||||
do_test_pending();
|
do_test_pending();
|
||||||
var listener2 = new ImageListener(null, function(foo, bar) { do_test_finished(); });
|
var listener2 = new ImageListener(null, function(foo, bar) { do_test_finished(); });
|
||||||
requests.push(gCurrentLoader.loadImage(uri, null, null, null, null, listener2, null, 0, null, null, null));
|
var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
|
||||||
|
.createScriptedObserver(listener2);
|
||||||
|
requests.push(gCurrentLoader.loadImage(uri, null, null, null, null, outer, null, 0, null, null, null));
|
||||||
listener2.synchronous = false;
|
listener2.synchronous = false;
|
||||||
|
|
||||||
// Now that we've started another load, chain to the callback.
|
// Now that we've started another load, chain to the callback.
|
||||||
@ -198,7 +214,9 @@ function run_test()
|
|||||||
|
|
||||||
do_test_pending();
|
do_test_pending();
|
||||||
var listener = new ImageListener(startImageCallback(checkClone), firstLoadDone);
|
var listener = new ImageListener(startImageCallback(checkClone), firstLoadDone);
|
||||||
var req = gCurrentLoader.loadImage(uri, null, null, null, null, listener, null, 0, null, null, null);
|
var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
|
||||||
|
.createScriptedObserver(listener);
|
||||||
|
var req = gCurrentLoader.loadImage(uri, null, null, null, null, outer, null, 0, null, null, null);
|
||||||
requests.push(req);
|
requests.push(req);
|
||||||
|
|
||||||
// Ensure that we don't cause any mayhem when we lock an image.
|
// Ensure that we don't cause any mayhem when we lock an image.
|
||||||
|
@ -2,86 +2,65 @@
|
|||||||
* Helper structures to track callbacks from image and channel loads.
|
* Helper structures to track callbacks from image and channel loads.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// One bit per callback that imageListener below implements. Stored in
|
// START_REQUEST and STOP_REQUEST are used by ChannelListener, and
|
||||||
// ImageListener.state.
|
|
||||||
// START_REQUEST and STOP_REQUEST are also reused by ChannelListener, and
|
|
||||||
// stored in ChannelListener.requestStatus.
|
// stored in ChannelListener.requestStatus.
|
||||||
const START_REQUEST = 0x01;
|
const START_REQUEST = 0x01;
|
||||||
const START_DECODE = 0x02;
|
const STOP_REQUEST = 0x02;
|
||||||
const START_CONTAINER = 0x04;
|
const DATA_AVAILABLE = 0x04;
|
||||||
const START_FRAME = 0x08;
|
|
||||||
const STOP_FRAME = 0x10;
|
// One bit per callback that imageListener below implements. Stored in
|
||||||
const STOP_CONTAINER = 0x20;
|
// ImageListener.state.
|
||||||
const STOP_DECODE = 0x40;
|
const SIZE_AVAILABLE = 0x01;
|
||||||
const STOP_REQUEST = 0x80;
|
const FRAME_UPDATE = 0x02;
|
||||||
const ALL_BITS = 0xFF;
|
const FRAME_COMPLETE = 0x04;
|
||||||
|
const LOAD_COMPLETE = 0x08;
|
||||||
|
const DECODE_COMPLETE = 0x10;
|
||||||
|
const ALL_BITS = SIZE_AVAILABLE | FRAME_COMPLETE | DECODE_COMPLETE | LOAD_COMPLETE;
|
||||||
|
|
||||||
// An implementation of imgIDecoderObserver with the ability to call specified
|
// An implementation of imgIDecoderObserver with the ability to call specified
|
||||||
// functions on onStartRequest and onStopRequest.
|
// functions on onStartRequest and onStopRequest.
|
||||||
function ImageListener(start_callback, stop_callback)
|
function ImageListener(start_callback, stop_callback)
|
||||||
{
|
{
|
||||||
this.onStartRequest = function onStartRequest(aRequest)
|
this.sizeAvailable = function onSizeAvailable(aRequest)
|
||||||
{
|
{
|
||||||
do_check_false(this.synchronous);
|
do_check_false(this.synchronous);
|
||||||
|
|
||||||
this.state |= START_REQUEST;
|
this.state |= SIZE_AVAILABLE;
|
||||||
|
|
||||||
if (this.start_callback)
|
if (this.start_callback)
|
||||||
this.start_callback(this, aRequest);
|
this.start_callback(this, aRequest);
|
||||||
}
|
}
|
||||||
this.onStartDecode = function onStartDecode(aRequest)
|
this.frameComplete = function onFrameComplete(aRequest)
|
||||||
{
|
{
|
||||||
do_check_false(this.synchronous);
|
do_check_false(this.synchronous);
|
||||||
|
|
||||||
this.state |= START_DECODE;
|
this.state |= FRAME_COMPLETE;
|
||||||
}
|
}
|
||||||
this.onStartContainer = function onStartContainer(aRequest, aContainer)
|
this.decodeComplete = function onDecodeComplete(aRequest)
|
||||||
{
|
{
|
||||||
do_check_false(this.synchronous);
|
do_check_false(this.synchronous);
|
||||||
|
|
||||||
this.state |= START_CONTAINER;
|
this.state |= DECODE_COMPLETE;
|
||||||
}
|
}
|
||||||
this.onStartFrame = function onStartFrame(aRequest, aFrame)
|
this.loadComplete = function onLoadcomplete(aRequest)
|
||||||
{
|
{
|
||||||
do_check_false(this.synchronous);
|
do_check_false(this.synchronous);
|
||||||
|
|
||||||
this.state |= START_FRAME;
|
|
||||||
}
|
|
||||||
this.onStopFrame = function onStopFrame(aRequest, aFrame)
|
|
||||||
{
|
|
||||||
do_check_false(this.synchronous);
|
|
||||||
|
|
||||||
this.state |= STOP_FRAME;
|
|
||||||
}
|
|
||||||
this.onStopContainer = function onStopContainer(aRequest, aContainer)
|
|
||||||
{
|
|
||||||
do_check_false(this.synchronous);
|
|
||||||
|
|
||||||
this.state |= STOP_CONTAINER;
|
|
||||||
}
|
|
||||||
this.onStopDecode = function onStopDecode(aRequest, status, statusArg)
|
|
||||||
{
|
|
||||||
do_check_false(this.synchronous);
|
|
||||||
|
|
||||||
this.state |= STOP_DECODE;
|
|
||||||
}
|
|
||||||
this.onStopRequest = function onStopRequest(aRequest, aIsLastPart)
|
|
||||||
{
|
|
||||||
do_check_false(this.synchronous);
|
|
||||||
|
|
||||||
// onStopDecode must always be called before, and with, onStopRequest. See
|
|
||||||
// imgRequest::OnStopDecode for more information.
|
|
||||||
do_check_true(!!(this.state & STOP_DECODE));
|
|
||||||
|
|
||||||
// We have to cancel the request when we're done with it to break any
|
// We have to cancel the request when we're done with it to break any
|
||||||
// reference loops!
|
// reference loops!
|
||||||
aRequest.cancelAndForgetObserver(0);
|
aRequest.cancelAndForgetObserver(0);
|
||||||
|
|
||||||
this.state |= STOP_REQUEST;
|
this.state |= LOAD_COMPLETE;
|
||||||
|
|
||||||
if (this.stop_callback)
|
if (this.stop_callback)
|
||||||
this.stop_callback(this, aRequest);
|
this.stop_callback(this, aRequest);
|
||||||
}
|
}
|
||||||
|
this.frameUpdate = function onFrameUpdate(aRequest)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
this.isAnimated = function onIsAnimated()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize the synchronous flag to true to start. This must be set to
|
// Initialize the synchronous flag to true to start. This must be set to
|
||||||
// false before exiting to the event loop!
|
// false before exiting to the event loop!
|
||||||
@ -118,6 +97,8 @@ function ChannelListener()
|
|||||||
{
|
{
|
||||||
if (this.outputListener)
|
if (this.outputListener)
|
||||||
this.outputListener.onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount);
|
this.outputListener.onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount);
|
||||||
|
|
||||||
|
this.requestStatus |= DATA_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onStopRequest = function onStopRequest(aRequest, aContext, aStatusCode)
|
this.onStopRequest = function onStopRequest(aRequest, aContext, aStatusCode)
|
||||||
|
@ -55,21 +55,25 @@ function setup_chan(path, isPrivate, callback) {
|
|||||||
chan.asyncOpen(channelListener, null);
|
chan.asyncOpen(channelListener, null);
|
||||||
|
|
||||||
var listener = new ImageListener(null, callback);
|
var listener = new ImageListener(null, callback);
|
||||||
listeners.push(listener);
|
|
||||||
var outlistener = {};
|
var outlistener = {};
|
||||||
var loader = isPrivate ? gPrivateLoader : gPublicLoader;
|
var loader = isPrivate ? gPrivateLoader : gPublicLoader;
|
||||||
requests.push(loader.loadImageWithChannel(chan, listener, null, outlistener));
|
var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
|
||||||
|
.createScriptedObserver(listener);
|
||||||
|
listeners.push(outer);
|
||||||
|
requests.push(loader.loadImageWithChannel(chan, outer, null, outlistener));
|
||||||
channelListener.outputListener = outlistener.value;
|
channelListener.outputListener = outlistener.value;
|
||||||
listener.synchronous = false;
|
listener.synchronous = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadImage(isPrivate, callback) {
|
function loadImage(isPrivate, callback) {
|
||||||
var listener = new ImageListener(null, callback);
|
var listener = new ImageListener(null, callback);
|
||||||
|
var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
|
||||||
|
.createScriptedObserver(listener);
|
||||||
var uri = gIoService.newURI(gImgPath, null, null);
|
var uri = gIoService.newURI(gImgPath, null, null);
|
||||||
var loadGroup = Cc["@mozilla.org/network/load-group;1"].createInstance(Ci.nsILoadGroup);
|
var loadGroup = Cc["@mozilla.org/network/load-group;1"].createInstance(Ci.nsILoadGroup);
|
||||||
loadGroup.notificationCallbacks = new NotificationCallbacks(isPrivate);
|
loadGroup.notificationCallbacks = new NotificationCallbacks(isPrivate);
|
||||||
var loader = isPrivate ? gPrivateLoader : gPublicLoader;
|
var loader = isPrivate ? gPrivateLoader : gPublicLoader;
|
||||||
requests.push(loader.loadImage(uri, null, null, null, loadGroup, listener, null, 0, null, null, null));
|
requests.push(loader.loadImage(uri, null, null, null, loadGroup, outer, null, 0, null, null, null));
|
||||||
listener.synchronous = false;
|
listener.synchronous = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ struct RuntimeSizes
|
|||||||
, ionCode(0)
|
, ionCode(0)
|
||||||
, regexpCode(0)
|
, regexpCode(0)
|
||||||
, unusedCode(0)
|
, unusedCode(0)
|
||||||
, stackCommitted(0)
|
, stack(0)
|
||||||
, gcMarker(0)
|
, gcMarker(0)
|
||||||
, mathCache(0)
|
, mathCache(0)
|
||||||
, scriptFilenames(0)
|
, scriptFilenames(0)
|
||||||
@ -69,7 +69,7 @@ struct RuntimeSizes
|
|||||||
size_t ionCode;
|
size_t ionCode;
|
||||||
size_t regexpCode;
|
size_t regexpCode;
|
||||||
size_t unusedCode;
|
size_t unusedCode;
|
||||||
size_t stackCommitted;
|
size_t stack;
|
||||||
size_t gcMarker;
|
size_t gcMarker;
|
||||||
size_t mathCache;
|
size_t mathCache;
|
||||||
size_t scriptFilenames;
|
size_t scriptFilenames;
|
||||||
|
@ -125,7 +125,7 @@ JSRuntime::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf, RuntimeSizes *rtS
|
|||||||
rtSizes->unusedCode = 0;
|
rtSizes->unusedCode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtSizes->stackCommitted = stackSpace.sizeOfCommitted();
|
rtSizes->stack = stackSpace.sizeOf();
|
||||||
|
|
||||||
rtSizes->gcMarker = gcMarker.sizeOfExcludingThis(mallocSizeOf);
|
rtSizes->gcMarker = gcMarker.sizeOfExcludingThis(mallocSizeOf);
|
||||||
|
|
||||||
@ -139,12 +139,15 @@ JSRuntime::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf, RuntimeSizes *rtS
|
|||||||
size_t
|
size_t
|
||||||
JSRuntime::sizeOfExplicitNonHeap()
|
JSRuntime::sizeOfExplicitNonHeap()
|
||||||
{
|
{
|
||||||
if (!execAlloc_)
|
size_t size = stackSpace.sizeOf();
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
if (execAlloc_) {
|
||||||
size_t jaegerCode, ionCode, regexpCode, unusedCode;
|
size_t jaegerCode, ionCode, regexpCode, unusedCode;
|
||||||
execAlloc_->sizeOfCode(&jaegerCode, &ionCode, ®expCode, &unusedCode);
|
execAlloc_->sizeOfCode(&jaegerCode, &ionCode, ®expCode, &unusedCode);
|
||||||
return jaegerCode + ionCode + regexpCode + unusedCode + stackSpace.sizeOfCommitted();
|
size += jaegerCode + ionCode + regexpCode + unusedCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -810,11 +810,58 @@ StackSpace::tryBumpLimit(JSContext *cx, Value *from, unsigned nvals, Value **lim
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
StackSpace::sizeOfCommitted()
|
StackSpace::sizeOf()
|
||||||
{
|
{
|
||||||
#ifdef XP_WIN
|
#if defined(XP_UNIX)
|
||||||
|
/*
|
||||||
|
* Measure how many of our pages are resident in RAM using mincore, and
|
||||||
|
* return that as our size. This is slow, but hopefully nobody expects
|
||||||
|
* this method to be fast.
|
||||||
|
*
|
||||||
|
* Note that using mincore means that we don't count pages of the stack
|
||||||
|
* which are swapped out to disk. We really should, but what we have here
|
||||||
|
* is better than counting the whole stack!
|
||||||
|
*/
|
||||||
|
|
||||||
|
const int pageSize = getpagesize();
|
||||||
|
size_t numBytes = (trustedEnd_ - base_) * sizeof(Value);
|
||||||
|
size_t numPages = (numBytes + pageSize - 1) / pageSize;
|
||||||
|
|
||||||
|
// On Linux, mincore's third argument has type unsigned char*. On Mac, it
|
||||||
|
// has type char*.
|
||||||
|
#if defined(XP_MACOSX)
|
||||||
|
typedef char MincoreArgType;
|
||||||
|
#else
|
||||||
|
typedef unsigned char MincoreArgType;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MincoreArgType *vec = (MincoreArgType *) js_malloc(numPages);
|
||||||
|
int result = mincore(base_, numBytes, vec);
|
||||||
|
if (result) {
|
||||||
|
js_free(vec);
|
||||||
|
/*
|
||||||
|
* If mincore fails us, return the vsize (like we do below if we're not
|
||||||
|
* on Windows or Unix).
|
||||||
|
*/
|
||||||
|
return (trustedEnd_ - base_) * sizeof(Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t residentBytes = 0;
|
||||||
|
for (size_t i = 0; i < numPages; i++) {
|
||||||
|
/* vec[i] has its least-significant bit set iff page i is in RAM. */
|
||||||
|
if (vec[i] & 0x1)
|
||||||
|
residentBytes += pageSize;
|
||||||
|
}
|
||||||
|
js_free(vec);
|
||||||
|
return residentBytes;
|
||||||
|
|
||||||
|
#elif defined(XP_WIN)
|
||||||
return (commitEnd_ - base_) * sizeof(Value);
|
return (commitEnd_ - base_) * sizeof(Value);
|
||||||
#else
|
#else
|
||||||
|
/*
|
||||||
|
* Return the stack's virtual size, which is at least an upper bound on its
|
||||||
|
* resident size.
|
||||||
|
*/
|
||||||
return (trustedEnd_ - base_) * sizeof(Value);
|
return (trustedEnd_ - base_) * sizeof(Value);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1439,8 +1439,12 @@ class StackSpace
|
|||||||
/* Called during GC: sets active flag on compartments with active frames. */
|
/* Called during GC: sets active flag on compartments with active frames. */
|
||||||
void markActiveCompartments();
|
void markActiveCompartments();
|
||||||
|
|
||||||
/* We only report the committed size; uncommitted size is uninteresting. */
|
/*
|
||||||
JS_FRIEND_API(size_t) sizeOfCommitted();
|
* On Windows, report the committed size; on *nix, we report the resident
|
||||||
|
* size (which means that if part of the stack is swapped to disk, we say
|
||||||
|
* it's shrunk).
|
||||||
|
*/
|
||||||
|
JS_FRIEND_API(size_t) sizeOf();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/* Only used in assertion of debuggers API. */
|
/* Only used in assertion of debuggers API. */
|
||||||
|
@ -770,8 +770,7 @@ mozJSComponentLoader::GlobalForLocation(nsIFile *aComponentFile,
|
|||||||
// Make sure the file map is closed, no matter how we return.
|
// Make sure the file map is closed, no matter how we return.
|
||||||
FileMapAutoCloser mapCloser(map);
|
FileMapAutoCloser mapCloser(map);
|
||||||
|
|
||||||
uint32_t fileSize32;
|
uint32_t fileSize32 = fileSize;
|
||||||
LL_L2UI(fileSize32, fileSize);
|
|
||||||
|
|
||||||
char *buf = static_cast<char*>(PR_MemMap(map, 0, fileSize32));
|
char *buf = static_cast<char*>(PR_MemMap(map, 0, fileSize32));
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
|
@ -1743,11 +1743,15 @@ ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
|
|||||||
"Memory allocated by one of the JITs to hold the "
|
"Memory allocated by one of the JITs to hold the "
|
||||||
"runtime's code, but which is currently unused.");
|
"runtime's code, but which is currently unused.");
|
||||||
|
|
||||||
RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/stack-committed"),
|
RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/stack"),
|
||||||
nsIMemoryReporter::KIND_NONHEAP, rtStats.runtime.stackCommitted,
|
nsIMemoryReporter::KIND_NONHEAP, rtStats.runtime.stack,
|
||||||
"Memory used for the JS call stack. This is the committed "
|
"Memory used for the JS call stack. This is the committed "
|
||||||
"portion of the stack; the uncommitted portion is not "
|
"portion of the stack on Windows; on *nix, it is the resident "
|
||||||
"measured because it hardly costs anything.");
|
"portion of the stack. Therefore, on *nix, if part of the "
|
||||||
|
"stack is swapped out to disk, we do not count it here.\n\n"
|
||||||
|
"Note that debug builds usually have stack poisoning enabled, "
|
||||||
|
"which causes the whole stack to be committed (and likely "
|
||||||
|
"resident).");
|
||||||
|
|
||||||
RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/gc-marker"),
|
RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/gc-marker"),
|
||||||
nsIMemoryReporter::KIND_HEAP, rtStats.runtime.gcMarker,
|
nsIMemoryReporter::KIND_HEAP, rtStats.runtime.gcMarker,
|
||||||
|
@ -57,8 +57,7 @@ members = [
|
|||||||
|
|
||||||
# dom/interfaces/canvas
|
# dom/interfaces/canvas
|
||||||
#
|
#
|
||||||
# nsIDOMCanvasRenderingContext2D and friends
|
# canvas friends
|
||||||
'nsIDOMCanvasRenderingContext2D.*',
|
|
||||||
'nsIDOMTextMetrics.*',
|
'nsIDOMTextMetrics.*',
|
||||||
'nsIDOMCanvasGradient.*',
|
'nsIDOMCanvasGradient.*',
|
||||||
'nsIDOMCanvasPattern.*',
|
'nsIDOMCanvasPattern.*',
|
||||||
@ -489,10 +488,6 @@ customIncludes = [
|
|||||||
'mozilla/dom/ImageData.h'
|
'mozilla/dom/ImageData.h'
|
||||||
]
|
]
|
||||||
|
|
||||||
customQuickStubs = [
|
|
||||||
'CustomQS_Canvas2D.h'
|
|
||||||
]
|
|
||||||
|
|
||||||
customReturnInterfaces = [
|
customReturnInterfaces = [
|
||||||
'nsIDOMCanvasPattern',
|
'nsIDOMCanvasPattern',
|
||||||
'nsIDOMCanvasGradient',
|
'nsIDOMCanvasGradient',
|
||||||
@ -649,10 +644,6 @@ customMethodCalls = {
|
|||||||
'nsIDOMStorage_Clear': {
|
'nsIDOMStorage_Clear': {
|
||||||
'code': nsIDOMStorage_Clear_customMethodCallCode
|
'code': nsIDOMStorage_Clear_customMethodCallCode
|
||||||
},
|
},
|
||||||
'nsIDOMCanvasRenderingContext2D_StrokeStyle': { 'skipgen': True },
|
|
||||||
'nsIDOMCanvasRenderingContext2D_StrokeStyle': { 'skipgen': True },
|
|
||||||
'nsIDOMCanvasRenderingContext2D_FillStyle': { 'skipgen': True },
|
|
||||||
'nsIDOMCanvasRenderingContext2D_FillStyle': { 'skipgen': True },
|
|
||||||
'nsIDOMCSS2Properties_': {
|
'nsIDOMCSS2Properties_': {
|
||||||
'thisType': 'nsICSSDeclaration',
|
'thisType': 'nsICSSDeclaration',
|
||||||
'additionalArguments': 'const nsCSSProperty prop',
|
'additionalArguments': 'const nsCSSProperty prop',
|
||||||
@ -971,13 +962,6 @@ customMethodCalls = {
|
|||||||
'thisType' : 'nsIDOMWindow',
|
'thisType' : 'nsIDOMWindow',
|
||||||
'unwrapThisFailureFatal' : False
|
'unwrapThisFailureFatal' : False
|
||||||
},
|
},
|
||||||
# Canvas 2D
|
|
||||||
'nsIDOMCanvasRenderingContext2D_CreateImageData': CUSTOM_QS,
|
|
||||||
'nsIDOMCanvasRenderingContext2D_PutImageData': CUSTOM_QS,
|
|
||||||
# Nasty hack to make the ordering of |arc| and |arcTo| correct.
|
|
||||||
# |arc| is not traceable because it has an optional argument.
|
|
||||||
'nsIDOMCanvasRenderingContext2D_ArcTo' : { 'traceable' : False },
|
|
||||||
|
|
||||||
'nsIDOMImageData_GetWidth': {
|
'nsIDOMImageData_GetWidth': {
|
||||||
'thisType': 'nsIDOMImageData',
|
'thisType': 'nsIDOMImageData',
|
||||||
'code': 'uint32_t result = static_cast<mozilla::dom::ImageData*>(self)->GetWidth();',
|
'code': 'uint32_t result = static_cast<mozilla::dom::ImageData*>(self)->GetWidth();',
|
||||||
@ -992,4 +976,3 @@ customMethodCalls = {
|
|||||||
'canFail': False
|
'canFail': False
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,7 +433,6 @@ nsresult NS_NewTreeBoxObject(nsIBoxObject** aResult);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsresult NS_NewCanvasRenderingContext2D(nsIDOMCanvasRenderingContext2D** aResult);
|
nsresult NS_NewCanvasRenderingContext2D(nsIDOMCanvasRenderingContext2D** aResult);
|
||||||
nsresult NS_NewCanvasRenderingContext2DThebes(nsIDOMCanvasRenderingContext2D** aResult);
|
|
||||||
nsresult NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** aResult);
|
nsresult NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** aResult);
|
||||||
|
|
||||||
nsresult NS_NewDomSelection(nsISelection** aResult);
|
nsresult NS_NewDomSelection(nsISelection** aResult);
|
||||||
@ -555,7 +554,6 @@ MAKE_CTOR(CreateVideoDocument, nsIDocument, NS_NewVid
|
|||||||
MAKE_CTOR(CreateFocusManager, nsIFocusManager, NS_NewFocusManager)
|
MAKE_CTOR(CreateFocusManager, nsIFocusManager, NS_NewFocusManager)
|
||||||
|
|
||||||
MAKE_CTOR(CreateCanvasRenderingContext2D, nsIDOMCanvasRenderingContext2D, NS_NewCanvasRenderingContext2D)
|
MAKE_CTOR(CreateCanvasRenderingContext2D, nsIDOMCanvasRenderingContext2D, NS_NewCanvasRenderingContext2D)
|
||||||
MAKE_CTOR(CreateCanvasRenderingContext2DThebes, nsIDOMCanvasRenderingContext2D, NS_NewCanvasRenderingContext2DThebes)
|
|
||||||
MAKE_CTOR(CreateCanvasRenderingContextWebGL, nsIDOMWebGLRenderingContext, NS_NewCanvasRenderingContextWebGL)
|
MAKE_CTOR(CreateCanvasRenderingContextWebGL, nsIDOMWebGLRenderingContext, NS_NewCanvasRenderingContextWebGL)
|
||||||
|
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsStyleSheetService, Init)
|
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsStyleSheetService, Init)
|
||||||
@ -718,7 +716,6 @@ NS_DEFINE_NAMED_CID(NS_HTMLOPTIONELEMENT_CID);
|
|||||||
NS_DEFINE_NAMED_CID(NS_HTMLAUDIOELEMENT_CID);
|
NS_DEFINE_NAMED_CID(NS_HTMLAUDIOELEMENT_CID);
|
||||||
#endif
|
#endif
|
||||||
NS_DEFINE_NAMED_CID(NS_CANVASRENDERINGCONTEXT2D_CID);
|
NS_DEFINE_NAMED_CID(NS_CANVASRENDERINGCONTEXT2D_CID);
|
||||||
NS_DEFINE_NAMED_CID(NS_CANVASRENDERINGCONTEXT2DTHEBES_CID);
|
|
||||||
NS_DEFINE_NAMED_CID(NS_CANVASRENDERINGCONTEXTWEBGL_CID);
|
NS_DEFINE_NAMED_CID(NS_CANVASRENDERINGCONTEXTWEBGL_CID);
|
||||||
NS_DEFINE_NAMED_CID(NS_TEXT_ENCODER_CID);
|
NS_DEFINE_NAMED_CID(NS_TEXT_ENCODER_CID);
|
||||||
NS_DEFINE_NAMED_CID(NS_HTMLCOPY_TEXT_ENCODER_CID);
|
NS_DEFINE_NAMED_CID(NS_HTMLCOPY_TEXT_ENCODER_CID);
|
||||||
@ -1000,7 +997,6 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
|
|||||||
#ifdef MOZ_MEDIA
|
#ifdef MOZ_MEDIA
|
||||||
{ &kNS_HTMLAUDIOELEMENT_CID, false, NULL, CreateHTMLAudioElement },
|
{ &kNS_HTMLAUDIOELEMENT_CID, false, NULL, CreateHTMLAudioElement },
|
||||||
#endif
|
#endif
|
||||||
{ &kNS_CANVASRENDERINGCONTEXT2DTHEBES_CID, false, NULL, CreateCanvasRenderingContext2DThebes },
|
|
||||||
{ &kNS_CANVASRENDERINGCONTEXT2D_CID, false, NULL, CreateCanvasRenderingContext2D },
|
{ &kNS_CANVASRENDERINGCONTEXT2D_CID, false, NULL, CreateCanvasRenderingContext2D },
|
||||||
{ &kNS_CANVASRENDERINGCONTEXTWEBGL_CID, false, NULL, CreateCanvasRenderingContextWebGL },
|
{ &kNS_CANVASRENDERINGCONTEXTWEBGL_CID, false, NULL, CreateCanvasRenderingContextWebGL },
|
||||||
{ &kNS_TEXT_ENCODER_CID, false, NULL, CreateTextEncoder },
|
{ &kNS_TEXT_ENCODER_CID, false, NULL, CreateTextEncoder },
|
||||||
@ -1146,7 +1142,6 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
|
|||||||
{ NS_HTMLAUDIOELEMENT_CONTRACTID, &kNS_HTMLAUDIOELEMENT_CID },
|
{ NS_HTMLAUDIOELEMENT_CONTRACTID, &kNS_HTMLAUDIOELEMENT_CID },
|
||||||
#endif
|
#endif
|
||||||
{ "@mozilla.org/content/canvas-rendering-context;1?id=2d", &kNS_CANVASRENDERINGCONTEXT2D_CID },
|
{ "@mozilla.org/content/canvas-rendering-context;1?id=2d", &kNS_CANVASRENDERINGCONTEXT2D_CID },
|
||||||
{ "@mozilla.org/content/2dthebes-canvas-rendering-context;1", &kNS_CANVASRENDERINGCONTEXT2DTHEBES_CID },
|
|
||||||
{ "@mozilla.org/content/canvas-rendering-context;1?id=moz-webgl", &kNS_CANVASRENDERINGCONTEXTWEBGL_CID },
|
{ "@mozilla.org/content/canvas-rendering-context;1?id=moz-webgl", &kNS_CANVASRENDERINGCONTEXTWEBGL_CID },
|
||||||
{ "@mozilla.org/content/canvas-rendering-context;1?id=experimental-webgl", &kNS_CANVASRENDERINGCONTEXTWEBGL_CID },
|
{ "@mozilla.org/content/canvas-rendering-context;1?id=experimental-webgl", &kNS_CANVASRENDERINGCONTEXTWEBGL_CID },
|
||||||
{ NS_DOC_ENCODER_CONTRACTID_BASE "text/xml", &kNS_TEXT_ENCODER_CID },
|
{ NS_DOC_ENCODER_CONTRACTID_BASE "text/xml", &kNS_TEXT_ENCODER_CID },
|
||||||
|
@ -1236,7 +1236,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
int32_t numLines = mLines.size();
|
int32_t numLines = mLines.size();
|
||||||
if (!numLines) numLines = 1;
|
if (!numLines) numLines = 1;
|
||||||
PRTime delta, perLineDelta, lines;
|
PRTime delta, perLineDelta, lines;
|
||||||
LL_I2L(lines, numLines);
|
lines = int64_t(numLines);
|
||||||
delta = end - start;
|
delta = end - start;
|
||||||
perLineDelta = delta / lines;
|
perLineDelta = delta / lines;
|
||||||
|
|
||||||
@ -6207,7 +6207,7 @@ nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||||||
int32_t numLines = mLines.size();
|
int32_t numLines = mLines.size();
|
||||||
if (!numLines) numLines = 1;
|
if (!numLines) numLines = 1;
|
||||||
PRTime lines, deltaPerLine, delta;
|
PRTime lines, deltaPerLine, delta;
|
||||||
LL_I2L(lines, numLines);
|
lines = int64_t(numLines);
|
||||||
delta = end - start;
|
delta = end - start;
|
||||||
deltaPerLine = delta / lines;
|
deltaPerLine = delta / lines;
|
||||||
|
|
||||||
|
@ -1431,8 +1431,35 @@ nsBulletFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
|
|||||||
return metrics.width;
|
return metrics.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsBulletFrame::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData)
|
||||||
|
{
|
||||||
|
if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
|
||||||
|
nsCOMPtr<imgIContainer> image;
|
||||||
|
aRequest->GetImage(getter_AddRefs(image));
|
||||||
|
return OnStartContainer(aRequest, image);
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsBulletFrame::OnStartContainer(imgIRequest *aRequest,
|
if (aType == imgINotificationObserver::FRAME_UPDATE) {
|
||||||
|
// The image has changed.
|
||||||
|
// Invalidate the entire content area. Maybe it's not optimal but it's simple and
|
||||||
|
// always correct, and I'll be a stunned mullet if it ever matters for performance
|
||||||
|
InvalidateFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::IS_ANIMATED) {
|
||||||
|
// Register the image request with the refresh driver now that we know it's
|
||||||
|
// animated.
|
||||||
|
if (aRequest == mImageRequest) {
|
||||||
|
nsLayoutUtils::RegisterImageRequest(PresContext(), mImageRequest,
|
||||||
|
&mRequestRegistered);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsBulletFrame::OnStartContainer(imgIRequest *aRequest,
|
||||||
imgIContainer *aImage)
|
imgIContainer *aImage)
|
||||||
{
|
{
|
||||||
if (!aImage) return NS_ERROR_INVALID_ARG;
|
if (!aImage) return NS_ERROR_INVALID_ARG;
|
||||||
@ -1475,60 +1502,6 @@ NS_IMETHODIMP nsBulletFrame::OnStartContainer(imgIRequest *aRequest,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsBulletFrame::OnDataAvailable(imgIRequest *aRequest,
|
|
||||||
bool aCurrentFrame,
|
|
||||||
const nsIntRect *aRect)
|
|
||||||
{
|
|
||||||
// The image has changed.
|
|
||||||
// Invalidate the entire content area. Maybe it's not optimal but it's simple and
|
|
||||||
// always correct, and I'll be a stunned mullet if it ever matters for performance
|
|
||||||
InvalidateFrame();
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsBulletFrame::OnStopDecode(imgIRequest *aRequest,
|
|
||||||
nsresult aStatus,
|
|
||||||
const PRUnichar *aStatusArg)
|
|
||||||
{
|
|
||||||
// XXX should the bulletframe do anything if the image failed to load?
|
|
||||||
// it didn't in the old code...
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (NS_FAILED(aStatus)) {
|
|
||||||
// We failed to load the image. Notify the pres shell
|
|
||||||
if (NS_FAILED(aStatus) && (mImageRequest == aRequest || !mImageRequest)) {
|
|
||||||
imageFailed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsBulletFrame::OnImageIsAnimated(imgIRequest* aRequest)
|
|
||||||
{
|
|
||||||
// Register the image request with the refresh driver now that we know it's
|
|
||||||
// animated.
|
|
||||||
if (aRequest == mImageRequest) {
|
|
||||||
nsLayoutUtils::RegisterImageRequest(PresContext(), mImageRequest,
|
|
||||||
&mRequestRegistered);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsBulletFrame::FrameChanged(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect)
|
|
||||||
{
|
|
||||||
// Invalidate the entire content area. Maybe it's not optimal but it's simple and
|
|
||||||
// always correct.
|
|
||||||
InvalidateFrame();
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsBulletFrame::GetLoadGroup(nsPresContext *aPresContext, nsILoadGroup **aLoadGroup)
|
nsBulletFrame::GetLoadGroup(nsPresContext *aPresContext, nsILoadGroup **aLoadGroup)
|
||||||
{
|
{
|
||||||
@ -1624,7 +1597,7 @@ nsBulletFrame::GetBaseline() const
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS2(nsBulletListener, imgIDecoderObserver, imgIContainerObserver)
|
NS_IMPL_ISUPPORTS1(nsBulletListener, imgINotificationObserver)
|
||||||
|
|
||||||
nsBulletListener::nsBulletListener() :
|
nsBulletListener::nsBulletListener() :
|
||||||
mFrame(nullptr)
|
mFrame(nullptr)
|
||||||
@ -1635,49 +1608,10 @@ nsBulletListener::~nsBulletListener()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsBulletListener::OnStartContainer(imgIRequest *aRequest,
|
NS_IMETHODIMP
|
||||||
imgIContainer *aImage)
|
nsBulletListener::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData)
|
||||||
{
|
{
|
||||||
if (!mFrame)
|
if (!mFrame)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
return mFrame->Notify(aRequest, aType, aData);
|
||||||
return mFrame->OnStartContainer(aRequest, aImage);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsBulletListener::OnDataAvailable(imgIRequest *aRequest,
|
|
||||||
bool aCurrentFrame,
|
|
||||||
const nsIntRect *aRect)
|
|
||||||
{
|
|
||||||
if (!mFrame)
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
return mFrame->OnDataAvailable(aRequest, aCurrentFrame, aRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsBulletListener::OnStopDecode(imgIRequest *aRequest,
|
|
||||||
nsresult status,
|
|
||||||
const PRUnichar *statusArg)
|
|
||||||
{
|
|
||||||
if (!mFrame)
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
return mFrame->OnStopDecode(aRequest, status, statusArg);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsBulletListener::OnImageIsAnimated(imgIRequest *aRequest)
|
|
||||||
{
|
|
||||||
if (!mFrame)
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
return mFrame->OnImageIsAnimated(aRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsBulletListener::FrameChanged(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect)
|
|
||||||
{
|
|
||||||
if (!mFrame)
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
return mFrame->FrameChanged(aRequest, aContainer, aDirtyRect);
|
|
||||||
}
|
}
|
||||||
|
@ -14,32 +14,21 @@
|
|||||||
|
|
||||||
#include "imgIRequest.h"
|
#include "imgIRequest.h"
|
||||||
#include "imgIDecoderObserver.h"
|
#include "imgIDecoderObserver.h"
|
||||||
#include "nsStubImageDecoderObserver.h"
|
#include "imgINotificationObserver.h"
|
||||||
|
|
||||||
#define BULLET_FRAME_IMAGE_LOADING NS_FRAME_STATE_BIT(63)
|
#define BULLET_FRAME_IMAGE_LOADING NS_FRAME_STATE_BIT(63)
|
||||||
#define BULLET_FRAME_HAS_FONT_INFLATION NS_FRAME_STATE_BIT(62)
|
#define BULLET_FRAME_HAS_FONT_INFLATION NS_FRAME_STATE_BIT(62)
|
||||||
|
|
||||||
class nsBulletFrame;
|
class nsBulletFrame;
|
||||||
|
|
||||||
class nsBulletListener : public nsStubImageDecoderObserver
|
class nsBulletListener : public imgINotificationObserver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsBulletListener();
|
nsBulletListener();
|
||||||
virtual ~nsBulletListener();
|
virtual ~nsBulletListener();
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
// imgIDecoderObserver (override nsStubImageDecoderObserver)
|
NS_DECL_IMGINOTIFICATIONOBSERVER
|
||||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
|
||||||
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, bool aCurrentFrame,
|
|
||||||
const nsIntRect *aRect);
|
|
||||||
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
|
|
||||||
const PRUnichar *statusArg);
|
|
||||||
NS_IMETHOD OnImageIsAnimated(imgIRequest *aRequest);
|
|
||||||
|
|
||||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
|
||||||
NS_IMETHOD FrameChanged(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *dirtyRect);
|
|
||||||
|
|
||||||
void SetFrame(nsBulletFrame *frame) { mFrame = frame; }
|
void SetFrame(nsBulletFrame *frame) { mFrame = frame; }
|
||||||
|
|
||||||
@ -61,6 +50,8 @@ public:
|
|||||||
}
|
}
|
||||||
virtual ~nsBulletFrame();
|
virtual ~nsBulletFrame();
|
||||||
|
|
||||||
|
NS_IMETHOD Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData);
|
||||||
|
|
||||||
// nsIFrame
|
// nsIFrame
|
||||||
virtual void DestroyFrom(nsIFrame* aDestructRoot);
|
virtual void DestroyFrom(nsIFrame* aDestructRoot);
|
||||||
NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||||
@ -85,18 +76,6 @@ public:
|
|||||||
int32_t aIncrement);
|
int32_t aIncrement);
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
|
||||||
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest,
|
|
||||||
bool aCurrentFrame,
|
|
||||||
const nsIntRect *aRect);
|
|
||||||
NS_IMETHOD OnStopDecode(imgIRequest *aRequest,
|
|
||||||
nsresult aStatus,
|
|
||||||
const PRUnichar *aStatusArg);
|
|
||||||
NS_IMETHOD OnImageIsAnimated(imgIRequest *aRequest);
|
|
||||||
NS_IMETHOD FrameChanged(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect);
|
|
||||||
|
|
||||||
/* get list item text, without '.' */
|
/* get list item text, without '.' */
|
||||||
static bool AppendCounterText(int32_t aListStyleType,
|
static bool AppendCounterText(int32_t aListStyleType,
|
||||||
int32_t aOrdinal,
|
int32_t aOrdinal,
|
||||||
@ -120,6 +99,8 @@ public:
|
|||||||
void SetFontSizeInflation(float aInflation);
|
void SetFontSizeInflation(float aInflation);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
nsresult OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
||||||
|
|
||||||
void GetDesiredSize(nsPresContext* aPresContext,
|
void GetDesiredSize(nsPresContext* aPresContext,
|
||||||
nsRenderingContext *aRenderingContext,
|
nsRenderingContext *aRenderingContext,
|
||||||
nsHTMLReflowMetrics& aMetrics,
|
nsHTMLReflowMetrics& aMetrics,
|
||||||
|
@ -140,7 +140,8 @@ nsImageFrame::nsImageFrame(nsStyleContext* aContext) :
|
|||||||
ImageFrameSuper(aContext),
|
ImageFrameSuper(aContext),
|
||||||
mComputedSize(0, 0),
|
mComputedSize(0, 0),
|
||||||
mIntrinsicRatio(0, 0),
|
mIntrinsicRatio(0, 0),
|
||||||
mDisplayingIcon(false)
|
mDisplayingIcon(false),
|
||||||
|
mFirstFrameComplete(false)
|
||||||
{
|
{
|
||||||
// We assume our size is not constrained and we haven't gotten an
|
// We assume our size is not constrained and we haven't gotten an
|
||||||
// initial reflow yet, so don't touch those flags.
|
// initial reflow yet, so don't touch those flags.
|
||||||
@ -525,6 +526,34 @@ nsImageFrame::ShouldCreateImageFrameFor(Element* aElement,
|
|||||||
return useSizedBox;
|
return useSizedBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsImageFrame::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* aData)
|
||||||
|
{
|
||||||
|
if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
|
||||||
|
nsCOMPtr<imgIContainer> image;
|
||||||
|
aRequest->GetImage(getter_AddRefs(image));
|
||||||
|
return OnStartContainer(aRequest, image);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::FRAME_UPDATE) {
|
||||||
|
return OnDataAvailable(aRequest, aData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::FRAME_COMPLETE) {
|
||||||
|
mFirstFrameComplete = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::LOAD_COMPLETE) {
|
||||||
|
uint32_t imgStatus;
|
||||||
|
aRequest->GetImageStatus(&imgStatus);
|
||||||
|
nsresult status =
|
||||||
|
imgStatus & imgIRequest::STATUS_ERROR ? NS_ERROR_FAILURE : NS_OK;
|
||||||
|
return OnStopRequest(aRequest, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsImageFrame::OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage)
|
nsImageFrame::OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage)
|
||||||
{
|
{
|
||||||
@ -564,9 +593,14 @@ nsImageFrame::OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage)
|
|||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsImageFrame::OnDataAvailable(imgIRequest *aRequest,
|
nsImageFrame::OnDataAvailable(imgIRequest *aRequest,
|
||||||
bool aCurrentFrame,
|
|
||||||
const nsIntRect *aRect)
|
const nsIntRect *aRect)
|
||||||
{
|
{
|
||||||
|
if (mFirstFrameComplete) {
|
||||||
|
nsCOMPtr<imgIContainer> container;
|
||||||
|
aRequest->GetImage(getter_AddRefs(container));
|
||||||
|
return FrameChanged(aRequest, container);
|
||||||
|
}
|
||||||
|
|
||||||
// XXX do we need to make sure that the reflow from the
|
// XXX do we need to make sure that the reflow from the
|
||||||
// OnStartContainer has been processed before we start calling
|
// OnStartContainer has been processed before we start calling
|
||||||
// invalidate?
|
// invalidate?
|
||||||
@ -583,11 +617,6 @@ nsImageFrame::OnDataAvailable(imgIRequest *aRequest,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't invalidate if the current visible frame isn't the one the data is
|
|
||||||
// from
|
|
||||||
if (!aCurrentFrame)
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
#ifdef DEBUG_decode
|
#ifdef DEBUG_decode
|
||||||
printf("Source rect (%d,%d,%d,%d)\n",
|
printf("Source rect (%d,%d,%d,%d)\n",
|
||||||
aRect->x, aRect->y, aRect->width, aRect->height);
|
aRect->x, aRect->y, aRect->width, aRect->height);
|
||||||
@ -606,9 +635,8 @@ nsImageFrame::OnDataAvailable(imgIRequest *aRequest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsImageFrame::OnStopDecode(imgIRequest *aRequest,
|
nsImageFrame::OnStopRequest(imgIRequest *aRequest,
|
||||||
nsresult aStatus,
|
nsresult aStatus)
|
||||||
const PRUnichar *aStatusArg)
|
|
||||||
{
|
{
|
||||||
// Check what request type we're dealing with
|
// Check what request type we're dealing with
|
||||||
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
|
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
|
||||||
@ -667,8 +695,7 @@ nsImageFrame::NotifyNewCurrentRequest(imgIRequest *aRequest,
|
|||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsImageFrame::FrameChanged(imgIRequest *aRequest,
|
nsImageFrame::FrameChanged(imgIRequest *aRequest,
|
||||||
imgIContainer *aContainer,
|
imgIContainer *aContainer)
|
||||||
const nsIntRect *aDirtyRect)
|
|
||||||
{
|
{
|
||||||
if (!GetStyleVisibility()->IsVisible()) {
|
if (!GetStyleVisibility()->IsVisible()) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -1894,7 +1921,7 @@ nsresult nsImageFrame::LoadIcons(nsPresContext *aPresContext)
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS2(nsImageFrame::IconLoad, nsIObserver,
|
NS_IMPL_ISUPPORTS2(nsImageFrame::IconLoad, nsIObserver,
|
||||||
imgIDecoderObserver)
|
imgINotificationObserver)
|
||||||
|
|
||||||
static const char* kIconLoadPrefs[] = {
|
static const char* kIconLoadPrefs[] = {
|
||||||
"browser.display.force_inline_alttext",
|
"browser.display.force_inline_alttext",
|
||||||
@ -1951,74 +1978,14 @@ void nsImageFrame::IconLoad::GetPrefs()
|
|||||||
Preferences::GetBool("browser.display.show_image_placeholders", true);
|
Preferences::GetBool("browser.display.show_image_placeholders", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsImageFrame::IconLoad::OnStartRequest(imgIRequest *aRequest)
|
nsImageFrame::IconLoad::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData)
|
||||||
{
|
{
|
||||||
|
if (aType != imgINotificationObserver::LOAD_COMPLETE &&
|
||||||
|
aType != imgINotificationObserver::FRAME_UPDATE) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageFrame::IconLoad::OnStartDecode(imgIRequest *aRequest)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageFrame::IconLoad::OnStartContainer(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageFrame::IconLoad::OnStartFrame(imgIRequest *aRequest,
|
|
||||||
uint32_t aFrame)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageFrame::IconLoad::OnDataAvailable(imgIRequest *aRequest,
|
|
||||||
bool aCurrentFrame,
|
|
||||||
const nsIntRect * aRect)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageFrame::IconLoad::OnStopFrame(imgIRequest *aRequest,
|
|
||||||
uint32_t aFrame)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageFrame::IconLoad::OnStopContainer(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageFrame::IconLoad::OnStopDecode(imgIRequest *aRequest,
|
|
||||||
nsresult status,
|
|
||||||
const PRUnichar *statusArg)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageFrame::IconLoad::OnImageIsAnimated(imgIRequest *aRequest)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageFrame::IconLoad::OnStopRequest(imgIRequest *aRequest,
|
|
||||||
bool aIsLastPart)
|
|
||||||
{
|
|
||||||
nsTObserverArray<nsImageFrame*>::ForwardIterator iter(mIconObservers);
|
nsTObserverArray<nsImageFrame*>::ForwardIterator iter(mIconObservers);
|
||||||
nsImageFrame *frame;
|
nsImageFrame *frame;
|
||||||
while (iter.HasMore()) {
|
while (iter.HasMore()) {
|
||||||
@ -2029,30 +1996,7 @@ nsImageFrame::IconLoad::OnStopRequest(imgIRequest *aRequest,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMPL_ISUPPORTS1(nsImageListener, imgINotificationObserver)
|
||||||
nsImageFrame::IconLoad::OnDiscard(imgIRequest *aRequest)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsImageFrame::IconLoad::FrameChanged(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect)
|
|
||||||
{
|
|
||||||
nsTObserverArray<nsImageFrame*>::ForwardIterator iter(mIconObservers);
|
|
||||||
nsImageFrame *frame;
|
|
||||||
while (iter.HasMore()) {
|
|
||||||
frame = iter.GetNext();
|
|
||||||
frame->InvalidateFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS2(nsImageListener, imgIDecoderObserver, imgIContainerObserver)
|
|
||||||
|
|
||||||
nsImageListener::nsImageListener(nsImageFrame *aFrame) :
|
nsImageListener::nsImageListener(nsImageFrame *aFrame) :
|
||||||
mFrame(aFrame)
|
mFrame(aFrame)
|
||||||
@ -2063,43 +2007,13 @@ nsImageListener::~nsImageListener()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsImageListener::OnStartContainer(imgIRequest *aRequest,
|
NS_IMETHODIMP
|
||||||
imgIContainer *aImage)
|
nsImageListener::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData)
|
||||||
{
|
{
|
||||||
if (!mFrame)
|
if (!mFrame)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
return mFrame->OnStartContainer(aRequest, aImage);
|
return mFrame->Notify(aRequest, aType, aData);
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsImageListener::OnDataAvailable(imgIRequest *aRequest,
|
|
||||||
bool aCurrentFrame,
|
|
||||||
const nsIntRect *aRect)
|
|
||||||
{
|
|
||||||
if (!mFrame)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
return mFrame->OnDataAvailable(aRequest, aCurrentFrame, aRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsImageListener::OnStopDecode(imgIRequest *aRequest,
|
|
||||||
nsresult status,
|
|
||||||
const PRUnichar *statusArg)
|
|
||||||
{
|
|
||||||
if (!mFrame)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
return mFrame->OnStopDecode(aRequest, status, statusArg);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsImageListener::FrameChanged(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect)
|
|
||||||
{
|
|
||||||
if (!mFrame)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
return mFrame->FrameChanged(aRequest, aContainer, aDirtyRect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -12,8 +12,7 @@
|
|||||||
#include "nsIIOService.h"
|
#include "nsIIOService.h"
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
|
|
||||||
#include "nsStubImageDecoderObserver.h"
|
#include "imgINotificationObserver.h"
|
||||||
#include "imgIDecoderObserver.h"
|
|
||||||
|
|
||||||
#include "nsDisplayList.h"
|
#include "nsDisplayList.h"
|
||||||
#include "imgIContainer.h"
|
#include "imgIContainer.h"
|
||||||
@ -40,23 +39,14 @@ namespace layers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class nsImageListener : public nsStubImageDecoderObserver
|
class nsImageListener : public imgINotificationObserver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsImageListener(nsImageFrame *aFrame);
|
nsImageListener(nsImageFrame *aFrame);
|
||||||
virtual ~nsImageListener();
|
virtual ~nsImageListener();
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
// imgIDecoderObserver (override nsStubImageDecoderObserver)
|
NS_DECL_IMGINOTIFICATIONOBSERVER
|
||||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
|
||||||
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, bool aCurrentFrame,
|
|
||||||
const nsIntRect *aRect);
|
|
||||||
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
|
|
||||||
const PRUnichar *statusArg);
|
|
||||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
|
||||||
NS_IMETHOD FrameChanged(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *dirtyRect);
|
|
||||||
|
|
||||||
void SetFrame(nsImageFrame *frame) { mFrame = frame; }
|
void SetFrame(nsImageFrame *frame) { mFrame = frame; }
|
||||||
|
|
||||||
@ -137,6 +127,8 @@ public:
|
|||||||
NS_IF_RELEASE(sIOService);
|
NS_IF_RELEASE(sIOService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to test whether aContent, which has aStyleContext as its style,
|
* Function to test whether aContent, which has aStyleContext as its style,
|
||||||
* should get an image frame. Note that this method is only used by the
|
* should get an image frame. Note that this method is only used by the
|
||||||
@ -221,14 +213,11 @@ protected:
|
|||||||
friend class nsImageListener;
|
friend class nsImageListener;
|
||||||
friend class nsImageLoadingContent;
|
friend class nsImageLoadingContent;
|
||||||
nsresult OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
nsresult OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
||||||
nsresult OnDataAvailable(imgIRequest *aRequest, bool aCurrentFrame,
|
nsresult OnDataAvailable(imgIRequest *aRequest, const nsIntRect *rect);
|
||||||
const nsIntRect *rect);
|
nsresult OnStopRequest(imgIRequest *aRequest,
|
||||||
nsresult OnStopDecode(imgIRequest *aRequest,
|
nsresult aStatus);
|
||||||
nsresult aStatus,
|
|
||||||
const PRUnichar *aStatusArg);
|
|
||||||
nsresult FrameChanged(imgIRequest *aRequest,
|
nsresult FrameChanged(imgIRequest *aRequest,
|
||||||
imgIContainer *aContainer,
|
imgIContainer *aContainer);
|
||||||
const nsIntRect *aDirtyRect);
|
|
||||||
/**
|
/**
|
||||||
* Notification that aRequest will now be the current request.
|
* Notification that aRequest will now be the current request.
|
||||||
*/
|
*/
|
||||||
@ -288,13 +277,14 @@ private:
|
|||||||
|
|
||||||
nsImageMap* mImageMap;
|
nsImageMap* mImageMap;
|
||||||
|
|
||||||
nsCOMPtr<imgIDecoderObserver> mListener;
|
nsCOMPtr<imgINotificationObserver> mListener;
|
||||||
|
|
||||||
nsSize mComputedSize;
|
nsSize mComputedSize;
|
||||||
nsIFrame::IntrinsicSize mIntrinsicSize;
|
nsIFrame::IntrinsicSize mIntrinsicSize;
|
||||||
nsSize mIntrinsicRatio;
|
nsSize mIntrinsicRatio;
|
||||||
|
|
||||||
bool mDisplayingIcon;
|
bool mDisplayingIcon;
|
||||||
|
bool mFirstFrameComplete;
|
||||||
|
|
||||||
static nsIIOService* sIOService;
|
static nsIIOService* sIOService;
|
||||||
|
|
||||||
@ -311,7 +301,7 @@ private:
|
|||||||
imgIRequest **aRequest);
|
imgIRequest **aRequest);
|
||||||
|
|
||||||
class IconLoad MOZ_FINAL : public nsIObserver,
|
class IconLoad MOZ_FINAL : public nsIObserver,
|
||||||
public imgIDecoderObserver {
|
public imgINotificationObserver {
|
||||||
// private class that wraps the data and logic needed for
|
// private class that wraps the data and logic needed for
|
||||||
// broken image and loading image icons
|
// broken image and loading image icons
|
||||||
public:
|
public:
|
||||||
@ -321,8 +311,7 @@ private:
|
|||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIOBSERVER
|
NS_DECL_NSIOBSERVER
|
||||||
NS_DECL_IMGICONTAINEROBSERVER
|
NS_DECL_IMGINOTIFICATIONOBSERVER
|
||||||
NS_DECL_IMGIDECODEROBSERVER
|
|
||||||
|
|
||||||
void AddIconObserver(nsImageFrame *frame) {
|
void AddIconObserver(nsImageFrame *frame) {
|
||||||
NS_ABORT_IF_FALSE(!mIconObservers.Contains(frame),
|
NS_ABORT_IF_FALSE(!mIconObservers.Contains(frame),
|
||||||
|
@ -56,8 +56,8 @@ ImageLoader::AssociateRequestToFrame(imgIRequest* aRequest,
|
|||||||
mFrameToRequestMap.IsInitialized() &&
|
mFrameToRequestMap.IsInitialized() &&
|
||||||
mImages.IsInitialized());
|
mImages.IsInitialized());
|
||||||
|
|
||||||
nsCOMPtr<imgIDecoderObserver> observer;
|
nsCOMPtr<imgINotificationObserver> observer;
|
||||||
aRequest->GetDecoderObserver(getter_AddRefs(observer));
|
aRequest->GetNotificationObserver(getter_AddRefs(observer));
|
||||||
if (!observer) {
|
if (!observer) {
|
||||||
// The request has already been canceled, so ignore it. This is ok because
|
// The request has already been canceled, so ignore it. This is ok because
|
||||||
// we're not going to get any more notifications from a canceled request.
|
// we're not going to get any more notifications from a canceled request.
|
||||||
@ -157,8 +157,8 @@ ImageLoader::DisassociateRequestFromFrame(imgIRequest* aRequest,
|
|||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
{
|
{
|
||||||
nsCOMPtr<imgIDecoderObserver> observer;
|
nsCOMPtr<imgINotificationObserver> observer;
|
||||||
aRequest->GetDecoderObserver(getter_AddRefs(observer));
|
aRequest->GetNotificationObserver(getter_AddRefs(observer));
|
||||||
MOZ_ASSERT(!observer || observer == this);
|
MOZ_ASSERT(!observer || observer == this);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -334,12 +334,35 @@ NS_IMPL_ADDREF(ImageLoader)
|
|||||||
NS_IMPL_RELEASE(ImageLoader)
|
NS_IMPL_RELEASE(ImageLoader)
|
||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN(ImageLoader)
|
NS_INTERFACE_MAP_BEGIN(ImageLoader)
|
||||||
NS_INTERFACE_MAP_ENTRY(imgIDecoderObserver)
|
NS_INTERFACE_MAP_ENTRY(imgINotificationObserver)
|
||||||
NS_INTERFACE_MAP_ENTRY(imgIContainerObserver)
|
|
||||||
NS_INTERFACE_MAP_ENTRY(imgIOnloadBlocker)
|
NS_INTERFACE_MAP_ENTRY(imgIOnloadBlocker)
|
||||||
NS_INTERFACE_MAP_END
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
ImageLoader::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData)
|
||||||
|
{
|
||||||
|
if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
|
||||||
|
nsCOMPtr<imgIContainer> image;
|
||||||
|
aRequest->GetImage(getter_AddRefs(image));
|
||||||
|
return OnStartContainer(aRequest, image);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::IS_ANIMATED) {
|
||||||
|
return OnImageIsAnimated(aRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::LOAD_COMPLETE) {
|
||||||
|
return OnStopFrame(aRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::FRAME_UPDATE) {
|
||||||
|
return FrameChanged(aRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
ImageLoader::OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage)
|
ImageLoader::OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage)
|
||||||
{
|
{
|
||||||
nsPresContext* presContext = GetPresContext();
|
nsPresContext* presContext = GetPresContext();
|
||||||
@ -352,7 +375,7 @@ ImageLoader::OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
nsresult
|
||||||
ImageLoader::OnImageIsAnimated(imgIRequest* aRequest)
|
ImageLoader::OnImageIsAnimated(imgIRequest* aRequest)
|
||||||
{
|
{
|
||||||
if (!mDocument) {
|
if (!mDocument) {
|
||||||
@ -376,8 +399,8 @@ ImageLoader::OnImageIsAnimated(imgIRequest* aRequest)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
nsresult
|
||||||
ImageLoader::OnStopFrame(imgIRequest *aRequest, uint32_t aFrame)
|
ImageLoader::OnStopFrame(imgIRequest *aRequest)
|
||||||
{
|
{
|
||||||
if (!mDocument || mInClone) {
|
if (!mDocument || mInClone) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -395,10 +418,8 @@ ImageLoader::OnStopFrame(imgIRequest *aRequest, uint32_t aFrame)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
nsresult
|
||||||
ImageLoader::FrameChanged(imgIRequest *aRequest,
|
ImageLoader::FrameChanged(imgIRequest *aRequest)
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect)
|
|
||||||
{
|
{
|
||||||
if (!mDocument || mInClone) {
|
if (!mDocument || mInClone) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include "nsCSSValue.h"
|
#include "nsCSSValue.h"
|
||||||
#include "imgIRequest.h"
|
#include "imgIRequest.h"
|
||||||
#include "imgIOnloadBlocker.h"
|
#include "imgIOnloadBlocker.h"
|
||||||
#include "nsStubImageDecoderObserver.h"
|
#include "imgINotificationObserver.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
|
||||||
class nsIFrame;
|
class nsIFrame;
|
||||||
@ -24,7 +24,7 @@ class nsIPrincipal;
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace css {
|
namespace css {
|
||||||
|
|
||||||
class ImageLoader MOZ_FINAL : public nsStubImageDecoderObserver,
|
class ImageLoader MOZ_FINAL : public imgINotificationObserver,
|
||||||
public imgIOnloadBlocker {
|
public imgIOnloadBlocker {
|
||||||
public:
|
public:
|
||||||
typedef mozilla::css::ImageValue Image;
|
typedef mozilla::css::ImageValue Image;
|
||||||
@ -42,19 +42,7 @@ public:
|
|||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_IMGIONLOADBLOCKER
|
NS_DECL_IMGIONLOADBLOCKER
|
||||||
|
NS_DECL_IMGINOTIFICATIONOBSERVER
|
||||||
// imgIDecoderObserver (override nsStubImageDecoderObserver)
|
|
||||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
|
||||||
NS_IMETHOD OnStopFrame(imgIRequest *aRequest, uint32_t aFrame);
|
|
||||||
NS_IMETHOD OnImageIsAnimated(imgIRequest *aRequest);
|
|
||||||
// Do not override OnDataAvailable since background images are not
|
|
||||||
// displayed incrementally; they are displayed after the entire image
|
|
||||||
// has been loaded.
|
|
||||||
|
|
||||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
|
||||||
NS_IMETHOD FrameChanged(imgIRequest* aRequest,
|
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect);
|
|
||||||
|
|
||||||
void DropDocumentReference();
|
void DropDocumentReference();
|
||||||
|
|
||||||
@ -103,6 +91,14 @@ private:
|
|||||||
SetAnimationModeEnumerator(nsISupports* aKey, FrameSet* aValue,
|
SetAnimationModeEnumerator(nsISupports* aKey, FrameSet* aValue,
|
||||||
void* aClosure);
|
void* aClosure);
|
||||||
|
|
||||||
|
nsresult OnStartContainer(imgIRequest *aRequest, imgIContainer* aImage);
|
||||||
|
nsresult OnStopFrame(imgIRequest *aRequest);
|
||||||
|
nsresult OnImageIsAnimated(imgIRequest *aRequest);
|
||||||
|
nsresult FrameChanged(imgIRequest* aRequest);
|
||||||
|
// Do not override OnDataAvailable since background images are not
|
||||||
|
// displayed incrementally; they are displayed after the entire image
|
||||||
|
// has been loaded.
|
||||||
|
|
||||||
// A map of imgIRequests to the nsIFrames that are using them.
|
// A map of imgIRequests to the nsIFrames that are using them.
|
||||||
RequestToFrameMap mRequestToFrameMap;
|
RequestToFrameMap mRequestToFrameMap;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#include "nsIDOMSVGImageElement.h"
|
#include "nsIDOMSVGImageElement.h"
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
#include "nsRenderingContext.h"
|
#include "nsRenderingContext.h"
|
||||||
#include "nsStubImageDecoderObserver.h"
|
#include "imgINotificationObserver.h"
|
||||||
#include "nsSVGEffects.h"
|
#include "nsSVGEffects.h"
|
||||||
#include "nsSVGImageElement.h"
|
#include "nsSVGImageElement.h"
|
||||||
#include "nsSVGPathGeometryFrame.h"
|
#include "nsSVGPathGeometryFrame.h"
|
||||||
@ -23,22 +23,13 @@ using namespace mozilla;
|
|||||||
|
|
||||||
class nsSVGImageFrame;
|
class nsSVGImageFrame;
|
||||||
|
|
||||||
class nsSVGImageListener MOZ_FINAL : public nsStubImageDecoderObserver
|
class nsSVGImageListener MOZ_FINAL : public imgINotificationObserver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsSVGImageListener(nsSVGImageFrame *aFrame);
|
nsSVGImageListener(nsSVGImageFrame *aFrame);
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
// imgIDecoderObserver (override nsStubImageDecoderObserver)
|
NS_DECL_IMGINOTIFICATIONOBSERVER
|
||||||
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
|
|
||||||
const PRUnichar *statusArg);
|
|
||||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
|
||||||
NS_IMETHOD FrameChanged(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect);
|
|
||||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
|
||||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer);
|
|
||||||
|
|
||||||
void SetFrame(nsSVGImageFrame *frame) { mFrame = frame; }
|
void SetFrame(nsSVGImageFrame *frame) { mFrame = frame; }
|
||||||
|
|
||||||
@ -98,7 +89,7 @@ private:
|
|||||||
gfxMatrix GetVectorImageTransform(uint32_t aFor);
|
gfxMatrix GetVectorImageTransform(uint32_t aFor);
|
||||||
bool TransformContextForPainting(gfxContext* aGfxContext);
|
bool TransformContextForPainting(gfxContext* aGfxContext);
|
||||||
|
|
||||||
nsCOMPtr<imgIDecoderObserver> mListener;
|
nsCOMPtr<imgINotificationObserver> mListener;
|
||||||
|
|
||||||
nsCOMPtr<imgIContainer> mImageContainer;
|
nsCOMPtr<imgIContainer> mImageContainer;
|
||||||
|
|
||||||
@ -560,49 +551,34 @@ nsSVGImageFrame::GetHitTestFlags()
|
|||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// nsSVGImageListener implementation
|
// nsSVGImageListener implementation
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS2(nsSVGImageListener,
|
NS_IMPL_ISUPPORTS1(nsSVGImageListener, imgINotificationObserver)
|
||||||
imgIDecoderObserver,
|
|
||||||
imgIContainerObserver)
|
|
||||||
|
|
||||||
nsSVGImageListener::nsSVGImageListener(nsSVGImageFrame *aFrame) : mFrame(aFrame)
|
nsSVGImageListener::nsSVGImageListener(nsSVGImageFrame *aFrame) : mFrame(aFrame)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsSVGImageListener::OnStopDecode(imgIRequest *aRequest,
|
NS_IMETHODIMP
|
||||||
nsresult status,
|
nsSVGImageListener::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData)
|
||||||
const PRUnichar *statusArg)
|
|
||||||
{
|
{
|
||||||
if (!mFrame)
|
if (!mFrame)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::LOAD_COMPLETE) {
|
||||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(mFrame);
|
nsSVGUtils::InvalidateAndScheduleReflowSVG(mFrame);
|
||||||
return NS_OK;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsSVGImageListener::FrameChanged(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect)
|
|
||||||
{
|
|
||||||
if (!mFrame)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::FRAME_UPDATE) {
|
||||||
// No new dimensions, so we don't need to call
|
// No new dimensions, so we don't need to call
|
||||||
// nsSVGUtils::InvalidateAndScheduleBoundsUpdate.
|
// nsSVGUtils::InvalidateAndScheduleBoundsUpdate.
|
||||||
nsSVGEffects::InvalidateRenderingObservers(mFrame);
|
nsSVGEffects::InvalidateRenderingObservers(mFrame);
|
||||||
nsSVGUtils::InvalidateBounds(mFrame);
|
nsSVGUtils::InvalidateBounds(mFrame);
|
||||||
return NS_OK;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsSVGImageListener::OnStartContainer(imgIRequest *aRequest,
|
if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
|
||||||
imgIContainer *aContainer)
|
|
||||||
{
|
|
||||||
// Called once the resource's dimensions have been obtained.
|
// Called once the resource's dimensions have been obtained.
|
||||||
|
aRequest->GetImage(getter_AddRefs(mFrame->mImageContainer));
|
||||||
if (!mFrame)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
mFrame->mImageContainer = aContainer;
|
|
||||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(mFrame);
|
nsSVGUtils::InvalidateAndScheduleReflowSVG(mFrame);
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,7 @@ _HARNESS_FILES = \
|
|||||||
$(topsrcdir)/testing/mozbase/mozdevice/mozdevice/devicemanager.py \
|
$(topsrcdir)/testing/mozbase/mozdevice/mozdevice/devicemanager.py \
|
||||||
$(topsrcdir)/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py \
|
$(topsrcdir)/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py \
|
||||||
$(topsrcdir)/testing/mozbase/mozdevice/mozdevice/devicemanagerSUT.py \
|
$(topsrcdir)/testing/mozbase/mozdevice/mozdevice/devicemanagerSUT.py \
|
||||||
|
$(topsrcdir)/testing/mozbase/mozdevice/mozdevice/Zeroconf.py \
|
||||||
$(topsrcdir)/build/mobile/b2gautomation.py \
|
$(topsrcdir)/build/mobile/b2gautomation.py \
|
||||||
$(topsrcdir)/build/automationutils.py \
|
$(topsrcdir)/build/automationutils.py \
|
||||||
$(topsrcdir)/build/mobile/remoteautomation.py \
|
$(topsrcdir)/build/mobile/remoteautomation.py \
|
||||||
|
@ -188,7 +188,7 @@ nsImageBoxFrame::Init(nsIContent* aContent,
|
|||||||
nsImageBoxListener *listener = new nsImageBoxListener();
|
nsImageBoxListener *listener = new nsImageBoxListener();
|
||||||
NS_ADDREF(listener);
|
NS_ADDREF(listener);
|
||||||
listener->SetFrame(this);
|
listener->SetFrame(this);
|
||||||
listener->QueryInterface(NS_GET_IID(imgIDecoderObserver), getter_AddRefs(mListener));
|
listener->QueryInterface(NS_GET_IID(imgINotificationObserver), getter_AddRefs(mListener));
|
||||||
NS_RELEASE(listener);
|
NS_RELEASE(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -577,8 +577,39 @@ nsImageBoxFrame::GetFrameName(nsAString& aResult) const
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsImageBoxFrame::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData)
|
||||||
|
{
|
||||||
|
if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
|
||||||
|
nsCOMPtr<imgIContainer> image;
|
||||||
|
aRequest->GetImage(getter_AddRefs(image));
|
||||||
|
return OnStartContainer(aRequest, image);
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsImageBoxFrame::OnStartContainer(imgIRequest *request,
|
if (aType == imgINotificationObserver::DECODE_COMPLETE) {
|
||||||
|
return OnStopDecode(aRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::LOAD_COMPLETE) {
|
||||||
|
uint32_t imgStatus;
|
||||||
|
aRequest->GetImageStatus(&imgStatus);
|
||||||
|
nsresult status =
|
||||||
|
imgStatus & imgIRequest::STATUS_ERROR ? NS_ERROR_FAILURE : NS_OK;
|
||||||
|
return OnStopRequest(aRequest, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::IS_ANIMATED) {
|
||||||
|
return OnImageIsAnimated(aRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aType == imgINotificationObserver::FRAME_UPDATE) {
|
||||||
|
return FrameChanged(aRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsImageBoxFrame::OnStartContainer(imgIRequest *request,
|
||||||
imgIContainer *image)
|
imgIContainer *image)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(image);
|
NS_ENSURE_ARG_POINTER(image);
|
||||||
@ -603,8 +634,7 @@ NS_IMETHODIMP nsImageBoxFrame::OnStartContainer(imgIRequest *request,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsImageBoxFrame::OnStopContainer(imgIRequest *request,
|
nsresult nsImageBoxFrame::OnStopDecode(imgIRequest *request)
|
||||||
imgIContainer *image)
|
|
||||||
{
|
{
|
||||||
nsBoxLayoutState state(PresContext());
|
nsBoxLayoutState state(PresContext());
|
||||||
this->Redraw(state);
|
this->Redraw(state);
|
||||||
@ -612,9 +642,8 @@ NS_IMETHODIMP nsImageBoxFrame::OnStopContainer(imgIRequest *request,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsImageBoxFrame::OnStopDecode(imgIRequest *request,
|
nsresult nsImageBoxFrame::OnStopRequest(imgIRequest *request,
|
||||||
nsresult aStatus,
|
nsresult aStatus)
|
||||||
const PRUnichar *statusArg)
|
|
||||||
{
|
{
|
||||||
if (NS_SUCCEEDED(aStatus))
|
if (NS_SUCCEEDED(aStatus))
|
||||||
// Fire an onload DOM event.
|
// Fire an onload DOM event.
|
||||||
@ -630,7 +659,7 @@ NS_IMETHODIMP nsImageBoxFrame::OnStopDecode(imgIRequest *request,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsImageBoxFrame::OnImageIsAnimated(imgIRequest *aRequest)
|
nsresult nsImageBoxFrame::OnImageIsAnimated(imgIRequest *aRequest)
|
||||||
{
|
{
|
||||||
// Register with our refresh driver, if we're animated.
|
// Register with our refresh driver, if we're animated.
|
||||||
nsLayoutUtils::RegisterImageRequest(PresContext(), aRequest,
|
nsLayoutUtils::RegisterImageRequest(PresContext(), aRequest,
|
||||||
@ -639,9 +668,7 @@ NS_IMETHODIMP nsImageBoxFrame::OnImageIsAnimated(imgIRequest *aRequest)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsImageBoxFrame::FrameChanged(imgIRequest *aRequest,
|
nsresult nsImageBoxFrame::FrameChanged(imgIRequest *aRequest)
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect)
|
|
||||||
{
|
{
|
||||||
if ((0 == mRect.width) || (0 == mRect.height)) {
|
if ((0 == mRect.width) || (0 == mRect.height)) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -652,7 +679,7 @@ NS_IMETHODIMP nsImageBoxFrame::FrameChanged(imgIRequest *aRequest,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS2(nsImageBoxListener, imgIDecoderObserver, imgIContainerObserver)
|
NS_IMPL_ISUPPORTS1(nsImageBoxListener, imgINotificationObserver)
|
||||||
|
|
||||||
nsImageBoxListener::nsImageBoxListener()
|
nsImageBoxListener::nsImageBoxListener()
|
||||||
{
|
{
|
||||||
@ -662,49 +689,11 @@ nsImageBoxListener::~nsImageBoxListener()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsImageBoxListener::OnStartContainer(imgIRequest *request,
|
NS_IMETHODIMP
|
||||||
imgIContainer *image)
|
nsImageBoxListener::Notify(imgIRequest *request, int32_t aType, const nsIntRect* aData)
|
||||||
{
|
{
|
||||||
if (!mFrame)
|
if (!mFrame)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
return mFrame->OnStartContainer(request, image);
|
return mFrame->Notify(request, aType, aData);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsImageBoxListener::OnStopContainer(imgIRequest *request,
|
|
||||||
imgIContainer *image)
|
|
||||||
{
|
|
||||||
if (!mFrame)
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
return mFrame->OnStopContainer(request, image);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsImageBoxListener::OnStopDecode(imgIRequest *request,
|
|
||||||
nsresult status,
|
|
||||||
const PRUnichar *statusArg)
|
|
||||||
{
|
|
||||||
if (!mFrame)
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
return mFrame->OnStopDecode(request, status, statusArg);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsImageBoxListener::OnImageIsAnimated(imgIRequest* aRequest)
|
|
||||||
{
|
|
||||||
if (!mFrame)
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
return mFrame->OnImageIsAnimated(aRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsImageBoxListener::FrameChanged(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect)
|
|
||||||
{
|
|
||||||
if (!mFrame)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
return mFrame->FrameChanged(aRequest, aContainer, aDirtyRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -11,30 +11,20 @@
|
|||||||
#include "imgILoader.h"
|
#include "imgILoader.h"
|
||||||
#include "imgIRequest.h"
|
#include "imgIRequest.h"
|
||||||
#include "imgIContainer.h"
|
#include "imgIContainer.h"
|
||||||
#include "nsStubImageDecoderObserver.h"
|
#include "imgINotificationObserver.h"
|
||||||
|
|
||||||
class nsImageBoxFrame;
|
class nsImageBoxFrame;
|
||||||
|
|
||||||
class nsDisplayXULImage;
|
class nsDisplayXULImage;
|
||||||
|
|
||||||
class nsImageBoxListener : public nsStubImageDecoderObserver
|
class nsImageBoxListener : public imgINotificationObserver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsImageBoxListener();
|
nsImageBoxListener();
|
||||||
virtual ~nsImageBoxListener();
|
virtual ~nsImageBoxListener();
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
// imgIDecoderObserver (override nsStubImageDecoderObserver)
|
NS_DECL_IMGINOTIFICATIONOBSERVER
|
||||||
NS_IMETHOD OnStartContainer(imgIRequest *request, imgIContainer *image);
|
|
||||||
NS_IMETHOD OnStopContainer(imgIRequest *request, imgIContainer *image);
|
|
||||||
NS_IMETHOD OnStopDecode(imgIRequest *request, nsresult status,
|
|
||||||
const PRUnichar *statusArg);
|
|
||||||
NS_IMETHOD OnImageIsAnimated(imgIRequest* aRequest);
|
|
||||||
|
|
||||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
|
||||||
NS_IMETHOD FrameChanged(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect);
|
|
||||||
|
|
||||||
void SetFrame(nsImageBoxFrame *frame) { mFrame = frame; }
|
void SetFrame(nsImageBoxFrame *frame) { mFrame = frame; }
|
||||||
|
|
||||||
@ -53,6 +43,8 @@ public:
|
|||||||
virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
|
virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
|
||||||
virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE;
|
virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
nsresult Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData);
|
||||||
|
|
||||||
friend nsIFrame* NS_NewImageBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
friend nsIFrame* NS_NewImageBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||||
|
|
||||||
NS_IMETHOD Init(nsIContent* aContent,
|
NS_IMETHOD Init(nsIContent* aContent,
|
||||||
@ -89,17 +81,6 @@ public:
|
|||||||
const nsRect& aDirtyRect,
|
const nsRect& aDirtyRect,
|
||||||
const nsDisplayListSet& aLists) MOZ_OVERRIDE;
|
const nsDisplayListSet& aLists) MOZ_OVERRIDE;
|
||||||
|
|
||||||
NS_IMETHOD OnStartContainer(imgIRequest *request, imgIContainer *image);
|
|
||||||
NS_IMETHOD OnStopContainer(imgIRequest *request, imgIContainer *image);
|
|
||||||
NS_IMETHOD OnStopDecode(imgIRequest *request,
|
|
||||||
nsresult status,
|
|
||||||
const PRUnichar *statusArg);
|
|
||||||
NS_IMETHOD OnImageIsAnimated(imgIRequest* aRequest);
|
|
||||||
|
|
||||||
NS_IMETHOD FrameChanged(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect);
|
|
||||||
|
|
||||||
virtual ~nsImageBoxFrame();
|
virtual ~nsImageBoxFrame();
|
||||||
|
|
||||||
void PaintImage(nsRenderingContext& aRenderingContext,
|
void PaintImage(nsRenderingContext& aRenderingContext,
|
||||||
@ -113,6 +94,11 @@ protected:
|
|||||||
virtual void GetImageSize();
|
virtual void GetImageSize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
nsresult OnStartContainer(imgIRequest *request, imgIContainer *image);
|
||||||
|
nsresult OnStopDecode(imgIRequest *request);
|
||||||
|
nsresult OnStopRequest(imgIRequest *request, nsresult status);
|
||||||
|
nsresult OnImageIsAnimated(imgIRequest* aRequest);
|
||||||
|
nsresult FrameChanged(imgIRequest *aRequest);
|
||||||
|
|
||||||
nsRect mSubRect; ///< If set, indicates that only the portion of the image specified by the rect should be used.
|
nsRect mSubRect; ///< If set, indicates that only the portion of the image specified by the rect should be used.
|
||||||
nsSize mIntrinsicSize;
|
nsSize mIntrinsicSize;
|
||||||
@ -123,7 +109,7 @@ private:
|
|||||||
bool mRequestRegistered;
|
bool mRequestRegistered;
|
||||||
|
|
||||||
nsCOMPtr<imgIRequest> mImageRequest;
|
nsCOMPtr<imgIRequest> mImageRequest;
|
||||||
nsCOMPtr<imgIDecoderObserver> mListener;
|
nsCOMPtr<imgINotificationObserver> mListener;
|
||||||
|
|
||||||
int32_t mLoadFlags;
|
int32_t mLoadFlags;
|
||||||
|
|
||||||
|
@ -907,11 +907,7 @@ nsListBoxBodyFrame::DoInternalPositionChanged(bool aUp, int32_t aDelta)
|
|||||||
|
|
||||||
PRTime end = PR_Now();
|
PRTime end = PR_Now();
|
||||||
|
|
||||||
PRTime difTime = end - start;
|
int32_t newTime = int32_t(end - start) / aDelta;
|
||||||
|
|
||||||
int32_t newTime;
|
|
||||||
LL_L2I(newTime, difTime);
|
|
||||||
newTime /= aDelta;
|
|
||||||
|
|
||||||
// average old and new
|
// average old and new
|
||||||
mTimePerRow = (newTime + mTimePerRow)/2;
|
mTimePerRow = (newTime + mTimePerRow)/2;
|
||||||
|
@ -2117,8 +2117,8 @@ nsTreeBodyFrame::GetImage(int32_t aRowIndex, nsTreeColumn* aCol, bool aUseContex
|
|||||||
|
|
||||||
if ((!(status & imgIRequest::STATUS_LOAD_COMPLETE)) || animated) {
|
if ((!(status & imgIRequest::STATUS_LOAD_COMPLETE)) || animated) {
|
||||||
// We either aren't done loading, or we're animating. Add our row as a listener for invalidations.
|
// We either aren't done loading, or we're animating. Add our row as a listener for invalidations.
|
||||||
nsCOMPtr<imgIDecoderObserver> obs;
|
nsCOMPtr<imgINotificationObserver> obs;
|
||||||
imgReq->GetDecoderObserver(getter_AddRefs(obs));
|
imgReq->GetNotificationObserver(getter_AddRefs(obs));
|
||||||
|
|
||||||
if (obs) {
|
if (obs) {
|
||||||
static_cast<nsTreeImageListener*> (obs.get())->AddCell(aRowIndex, aCol);
|
static_cast<nsTreeImageListener*> (obs.get())->AddCell(aRowIndex, aCol);
|
||||||
@ -2140,11 +2140,11 @@ nsTreeBodyFrame::GetImage(int32_t aRowIndex, nsTreeColumn* aCol, bool aUseContex
|
|||||||
}
|
}
|
||||||
|
|
||||||
listener->AddCell(aRowIndex, aCol);
|
listener->AddCell(aRowIndex, aCol);
|
||||||
nsCOMPtr<imgIDecoderObserver> imgDecoderObserver = listener;
|
nsCOMPtr<imgINotificationObserver> imgNotificationObserver = listener;
|
||||||
|
|
||||||
nsCOMPtr<imgIRequest> imageRequest;
|
nsCOMPtr<imgIRequest> imageRequest;
|
||||||
if (styleRequest) {
|
if (styleRequest) {
|
||||||
styleRequest->Clone(imgDecoderObserver, getter_AddRefs(imageRequest));
|
styleRequest->Clone(imgNotificationObserver, getter_AddRefs(imageRequest));
|
||||||
} else {
|
} else {
|
||||||
nsIDocument* doc = mContent->GetDocument();
|
nsIDocument* doc = mContent->GetDocument();
|
||||||
if (!doc)
|
if (!doc)
|
||||||
@ -2169,7 +2169,7 @@ nsTreeBodyFrame::GetImage(int32_t aRowIndex, nsTreeColumn* aCol, bool aUseContex
|
|||||||
doc,
|
doc,
|
||||||
mContent->NodePrincipal(),
|
mContent->NodePrincipal(),
|
||||||
doc->GetDocumentURI(),
|
doc->GetDocumentURI(),
|
||||||
imgDecoderObserver,
|
imgNotificationObserver,
|
||||||
nsIRequest::LOAD_NORMAL,
|
nsIRequest::LOAD_NORMAL,
|
||||||
getter_AddRefs(imageRequest));
|
getter_AddRefs(imageRequest));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
@ -2187,7 +2187,7 @@ nsTreeBodyFrame::GetImage(int32_t aRowIndex, nsTreeColumn* aCol, bool aUseContex
|
|||||||
|
|
||||||
// In a case it was already cached.
|
// In a case it was already cached.
|
||||||
imageRequest->GetImage(aResult);
|
imageRequest->GetImage(aResult);
|
||||||
nsTreeImageCacheEntry cacheEntry(imageRequest, imgDecoderObserver);
|
nsTreeImageCacheEntry cacheEntry(imageRequest, imgNotificationObserver);
|
||||||
mImageCache.Put(imageSrc, cacheEntry);
|
mImageCache.Put(imageSrc, cacheEntry);
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
#include "nsDataHashtable.h"
|
#include "nsDataHashtable.h"
|
||||||
#include "imgIRequest.h"
|
#include "imgIRequest.h"
|
||||||
#include "imgIDecoderObserver.h"
|
#include "imgINotificationObserver.h"
|
||||||
#include "nsScrollbarFrame.h"
|
#include "nsScrollbarFrame.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "mozilla/LookAndFeel.h"
|
#include "mozilla/LookAndFeel.h"
|
||||||
@ -32,11 +32,11 @@ class nsTreeImageListener;
|
|||||||
struct nsTreeImageCacheEntry
|
struct nsTreeImageCacheEntry
|
||||||
{
|
{
|
||||||
nsTreeImageCacheEntry() {}
|
nsTreeImageCacheEntry() {}
|
||||||
nsTreeImageCacheEntry(imgIRequest *aRequest, imgIDecoderObserver *aListener)
|
nsTreeImageCacheEntry(imgIRequest *aRequest, imgINotificationObserver *aListener)
|
||||||
: request(aRequest), listener(aListener) {}
|
: request(aRequest), listener(aListener) {}
|
||||||
|
|
||||||
nsCOMPtr<imgIRequest> request;
|
nsCOMPtr<imgIRequest> request;
|
||||||
nsCOMPtr<imgIDecoderObserver> listener;
|
nsCOMPtr<imgINotificationObserver> listener;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The actual frame that paints the cells and rows.
|
// The actual frame that paints the cells and rows.
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "imgIRequest.h"
|
#include "imgIRequest.h"
|
||||||
#include "imgIContainer.h"
|
#include "imgIContainer.h"
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS2(nsTreeImageListener, imgIDecoderObserver, imgIContainerObserver)
|
NS_IMPL_ISUPPORTS1(nsTreeImageListener, imgINotificationObserver)
|
||||||
|
|
||||||
nsTreeImageListener::nsTreeImageListener(nsTreeBodyFrame* aTreeFrame)
|
nsTreeImageListener::nsTreeImageListener(nsTreeBodyFrame* aTreeFrame)
|
||||||
: mTreeFrame(aTreeFrame),
|
: mTreeFrame(aTreeFrame),
|
||||||
@ -23,42 +23,26 @@ nsTreeImageListener::~nsTreeImageListener()
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsTreeImageListener::OnImageIsAnimated(imgIRequest *aRequest)
|
nsTreeImageListener::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData)
|
||||||
{
|
{
|
||||||
if (!mTreeFrame) {
|
if (aType == imgINotificationObserver::IS_ANIMATED) {
|
||||||
return NS_OK;
|
return mTreeFrame ? mTreeFrame->OnImageIsAnimated(aRequest) : NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mTreeFrame->OnImageIsAnimated(aRequest);
|
if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsTreeImageListener::OnStartContainer(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aImage)
|
|
||||||
{
|
|
||||||
// Ensure the animation (if any) is started. Note: There is no
|
// Ensure the animation (if any) is started. Note: There is no
|
||||||
// corresponding call to Decrement for this. This Increment will be
|
// corresponding call to Decrement for this. This Increment will be
|
||||||
// 'cleaned up' by the Request when it is destroyed, but only then.
|
// 'cleaned up' by the Request when it is destroyed, but only then.
|
||||||
aRequest->IncrementAnimationConsumers();
|
aRequest->IncrementAnimationConsumers();
|
||||||
return NS_OK;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsTreeImageListener::OnDataAvailable(imgIRequest *aRequest,
|
if (aType == imgINotificationObserver::FRAME_UPDATE) {
|
||||||
bool aCurrentFrame,
|
|
||||||
const nsIntRect *aRect)
|
|
||||||
{
|
|
||||||
Invalidate();
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsTreeImageListener::FrameChanged(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect)
|
|
||||||
{
|
|
||||||
Invalidate();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsTreeImageListener::AddCell(int32_t aIndex, nsITreeColumn* aCol)
|
nsTreeImageListener::AddCell(int32_t aIndex, nsITreeColumn* aCol)
|
||||||
{
|
{
|
||||||
|
@ -9,27 +9,18 @@
|
|||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsITreeColumns.h"
|
#include "nsITreeColumns.h"
|
||||||
#include "nsStubImageDecoderObserver.h"
|
|
||||||
#include "nsTreeBodyFrame.h"
|
#include "nsTreeBodyFrame.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
|
||||||
// This class handles image load observation.
|
// This class handles image load observation.
|
||||||
class nsTreeImageListener MOZ_FINAL : public nsStubImageDecoderObserver
|
class nsTreeImageListener MOZ_FINAL : public imgINotificationObserver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsTreeImageListener(nsTreeBodyFrame *aTreeFrame);
|
nsTreeImageListener(nsTreeBodyFrame *aTreeFrame);
|
||||||
~nsTreeImageListener();
|
~nsTreeImageListener();
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
// imgIDecoderObserver (override nsStubImageDecoderObserver)
|
NS_DECL_IMGINOTIFICATIONOBSERVER
|
||||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
|
||||||
NS_IMETHOD OnImageIsAnimated(imgIRequest* aRequest);
|
|
||||||
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, bool aCurrentFrame,
|
|
||||||
const nsIntRect *aRect);
|
|
||||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
|
||||||
NS_IMETHOD FrameChanged(imgIRequest *aRequest,
|
|
||||||
imgIContainer *aContainer,
|
|
||||||
const nsIntRect *aDirtyRect);
|
|
||||||
|
|
||||||
NS_IMETHOD ClearFrame();
|
NS_IMETHOD ClearFrame();
|
||||||
|
|
||||||
|
@ -1,41 +1,6 @@
|
|||||||
/* ***** BEGIN LICENSE BLOCK *****
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
*
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
* 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 the Cisco Systems SIP Stack.
|
|
||||||
*
|
|
||||||
* The Initial Developer of the Original Code is
|
|
||||||
* Cisco Systems (CSCO).
|
|
||||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
|
||||||
* the Initial Developer. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Contributor(s):
|
|
||||||
* Enda Mannion <emannion@cisco.com>
|
|
||||||
* Suhas Nandakumar <snandaku@cisco.com>
|
|
||||||
* Ethan Hugg <ehugg@cisco.com>
|
|
||||||
*
|
|
||||||
* 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 ***** */
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@ -1,41 +1,6 @@
|
|||||||
/* ***** BEGIN LICENSE BLOCK *****
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
*
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
* 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 the Cisco Systems SIP Stack.
|
|
||||||
*
|
|
||||||
* The Initial Developer of the Original Code is
|
|
||||||
* Cisco Systems (CSCO).
|
|
||||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
|
||||||
* the Initial Developer. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Contributor(s):
|
|
||||||
* Enda Mannion <emannion@cisco.com>
|
|
||||||
* Suhas Nandakumar <snandaku@cisco.com>
|
|
||||||
* Ethan Hugg <ehugg@cisco.com>
|
|
||||||
*
|
|
||||||
* 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 ***** */
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user