mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Back out d3b8c0394c5e, 701372c96a92, f2c16b13cf65, 367ff8c94636 (bug 683290, bug 684919, bug 685516) for Android reftest failures
This commit is contained in:
parent
4151b38db0
commit
57442b74d1
@ -65,7 +65,7 @@ interface nsIDocument;
|
||||
* sufficient, when combined with the imageBlockingStatus information.)
|
||||
*/
|
||||
|
||||
[scriptable, uuid(4bf1a7c5-6edb-4191-a257-e31a90f6aa85)]
|
||||
[scriptable, uuid(95c74255-df9a-4060-b5a0-0d111fcafe08)]
|
||||
interface nsIImageLoadingContent : imgIDecoderObserver
|
||||
{
|
||||
/**
|
||||
@ -175,4 +175,9 @@ interface nsIImageLoadingContent : imgIDecoderObserver
|
||||
* as PR_FALSE to revert ImageState() to its original behaviour.
|
||||
*/
|
||||
void forceImageState(in boolean aForce, in unsigned long long aState);
|
||||
|
||||
/**
|
||||
* We need to be notified when our document changes.
|
||||
*/
|
||||
[noscript, notxpcom] void NotifyOwnerDocumentChanged(in nsIDocument aOldDoc);
|
||||
};
|
||||
|
@ -67,10 +67,6 @@ public:
|
||||
}
|
||||
|
||||
// nsIContent overrides
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(bool aDeep, bool aNullParent);
|
||||
virtual nsEventStates IntrinsicState() const;
|
||||
|
||||
private:
|
||||
@ -103,28 +99,6 @@ nsGenConImageContent::~nsGenConImageContent()
|
||||
DestroyImageLoadingContent();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenConImageContent::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers)
|
||||
{
|
||||
nsresult rv;
|
||||
rv = nsXMLElement::BindToTree(aDocument, aParent, aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenConImageContent::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
{
|
||||
nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
|
||||
nsXMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
nsEventStates
|
||||
nsGenConImageContent::IntrinsicState() const
|
||||
{
|
||||
|
@ -132,7 +132,7 @@ nsImageLoadingContent::DestroyImageLoadingContent()
|
||||
|
||||
nsImageLoadingContent::~nsImageLoadingContent()
|
||||
{
|
||||
NS_ASSERTION(!mCurrentRequest.Ptr() && !mPendingRequest.Ptr(),
|
||||
NS_ASSERTION(!mCurrentRequest && !mPendingRequest,
|
||||
"DestroyImageLoadingContent not called");
|
||||
NS_ASSERTION(!mObserverList.mObserver && !mObserverList.mNext,
|
||||
"Observers still registered?");
|
||||
@ -181,7 +181,7 @@ nsImageLoadingContent::OnStartDecode(imgIRequest* aRequest)
|
||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
// Onload blocking. This only applies for the current request.
|
||||
if (aRequest == mCurrentRequest.Ptr()) {
|
||||
if (aRequest == mCurrentRequest) {
|
||||
|
||||
// Determine whether this is a background request (this can be the case
|
||||
// with multipart/x-mixed-replace images, for example).
|
||||
@ -243,7 +243,7 @@ nsImageLoadingContent::OnStopFrame(imgIRequest* aRequest,
|
||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
// If we're blocking a load, one frame is enough
|
||||
if (aRequest == mCurrentRequest.Ptr())
|
||||
if (aRequest == mCurrentRequest)
|
||||
SetBlockingOnload(PR_FALSE);
|
||||
|
||||
LOOP_OVER_OBSERVERS(OnStopFrame(aRequest, aFrame));
|
||||
@ -262,7 +262,7 @@ nsImageLoadingContent::OnStopContainer(imgIRequest* aRequest,
|
||||
// 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 (aRequest == mCurrentRequest.Ptr())
|
||||
if (aRequest == mCurrentRequest)
|
||||
SetBlockingOnload(PR_FALSE);
|
||||
|
||||
LOOP_OVER_OBSERVERS(OnStopContainer(aRequest, aContainer));
|
||||
@ -282,8 +282,7 @@ nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest,
|
||||
// We should definitely have a request here
|
||||
NS_ABORT_IF_FALSE(aRequest, "no request?");
|
||||
|
||||
NS_PRECONDITION(aRequest == mCurrentRequest.Ptr() ||
|
||||
aRequest == mPendingRequest.Ptr(),
|
||||
NS_PRECONDITION(aRequest == mCurrentRequest || aRequest == mPendingRequest,
|
||||
"Unknown request");
|
||||
LOOP_OVER_OBSERVERS(OnStopDecode(aRequest, aStatus, aStatusArg));
|
||||
|
||||
@ -294,19 +293,18 @@ nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest,
|
||||
AutoStateChanger changer(this, PR_TRUE);
|
||||
|
||||
// If the pending request is loaded, switch to it.
|
||||
if (aRequest == mPendingRequest.Ptr()) {
|
||||
PrepareCurrentRequest();
|
||||
mCurrentRequest = mPendingRequest;
|
||||
mPendingRequest.Clear();
|
||||
if (aRequest == mPendingRequest) {
|
||||
PrepareCurrentRequest() = mPendingRequest;
|
||||
mPendingRequest = nsnull;
|
||||
mCurrentRequestNeedsResetAnimation = mPendingRequestNeedsResetAnimation;
|
||||
mPendingRequestNeedsResetAnimation = PR_FALSE;
|
||||
}
|
||||
NS_ABORT_IF_FALSE(aRequest == mCurrentRequest.Ptr(),
|
||||
NS_ABORT_IF_FALSE(aRequest == mCurrentRequest,
|
||||
"One way or another, we should be current by now");
|
||||
|
||||
if (mCurrentRequestNeedsResetAnimation) {
|
||||
nsCOMPtr<imgIContainer> container;
|
||||
mCurrentRequest.Ptr()->GetImage(getter_AddRefs(container));
|
||||
mCurrentRequest->GetImage(getter_AddRefs(container));
|
||||
if (container)
|
||||
container->ResetAnimation();
|
||||
mCurrentRequestNeedsResetAnimation = PR_FALSE;
|
||||
@ -327,9 +325,7 @@ nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest,
|
||||
// decoding, so we can't wait for them to finish. See bug 512435.
|
||||
|
||||
// We can only do this if we have a presshell
|
||||
// XXXkhuey should this be GetOurCurrentDoc? Decoding if we're not in
|
||||
// the document seems silly.
|
||||
nsIDocument* doc = GetOurOwnerDoc();
|
||||
nsIDocument* doc = GetOurDocument();
|
||||
nsIPresShell* shell = doc ? doc->GetShell() : nsnull;
|
||||
if (shell) {
|
||||
|
||||
@ -350,7 +346,7 @@ nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest,
|
||||
|
||||
// If we're requesting a decode, do it
|
||||
if (doRequestDecode)
|
||||
mCurrentRequest.Ptr()->RequestDecode();
|
||||
mCurrentRequest->RequestDecode();
|
||||
}
|
||||
|
||||
// Fire the appropriate DOM event.
|
||||
@ -490,10 +486,10 @@ nsImageLoadingContent::GetRequest(PRInt32 aRequestType,
|
||||
{
|
||||
switch(aRequestType) {
|
||||
case CURRENT_REQUEST:
|
||||
*aRequest = mCurrentRequest.Ptr();
|
||||
*aRequest = mCurrentRequest;
|
||||
break;
|
||||
case PENDING_REQUEST:
|
||||
*aRequest = mPendingRequest.Ptr();
|
||||
*aRequest = mPendingRequest;
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("Unknown request type");
|
||||
@ -514,12 +510,12 @@ nsImageLoadingContent::GetRequestType(imgIRequest* aRequest,
|
||||
|
||||
NS_PRECONDITION(aRequestType, "Null out param");
|
||||
|
||||
if (aRequest == mCurrentRequest.Ptr()) {
|
||||
if (aRequest == mCurrentRequest) {
|
||||
*aRequestType = CURRENT_REQUEST;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aRequest == mPendingRequest.Ptr()) {
|
||||
if (aRequest == mPendingRequest) {
|
||||
*aRequestType = PENDING_REQUEST;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -532,8 +528,8 @@ nsImageLoadingContent::GetRequestType(imgIRequest* aRequest,
|
||||
NS_IMETHODIMP
|
||||
nsImageLoadingContent::GetCurrentURI(nsIURI** aURI)
|
||||
{
|
||||
if (mCurrentRequest.Ptr()) {
|
||||
return mCurrentRequest.Ptr()->GetURI(aURI);
|
||||
if (mCurrentRequest) {
|
||||
return mCurrentRequest->GetURI(aURI);
|
||||
}
|
||||
|
||||
if (!mCurrentURI) {
|
||||
@ -554,7 +550,7 @@ nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel,
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = GetOurOwnerDoc();
|
||||
nsCOMPtr<nsIDocument> doc = GetOurDocument();
|
||||
if (!doc) {
|
||||
// Don't bother
|
||||
return NS_OK;
|
||||
@ -568,7 +564,7 @@ nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel,
|
||||
AutoStateChanger changer(this, PR_TRUE);
|
||||
|
||||
// Do the load.
|
||||
RequestWithState& req = PrepareNextRequest();
|
||||
nsCOMPtr<imgIRequest>& req = PrepareNextRequest();
|
||||
nsresult rv = nsContentUtils::GetImgLoader()->
|
||||
LoadImageWithChannel(aChannel, this, doc, aListener,
|
||||
getter_AddRefs(req));
|
||||
@ -577,7 +573,7 @@ nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel,
|
||||
} else {
|
||||
// If we don't have a current URI, we might as well store this URI so people
|
||||
// know what we tried (and failed) to load.
|
||||
if (!mCurrentRequest.Ptr())
|
||||
if (!mCurrentRequest)
|
||||
aChannel->GetURI(getter_AddRefs(mCurrentURI));
|
||||
FireEvent(NS_LITERAL_STRING("error"));
|
||||
return rv;
|
||||
@ -602,13 +598,29 @@ NS_IMETHODIMP nsImageLoadingContent::ForceReload()
|
||||
* Non-interface methods
|
||||
*/
|
||||
|
||||
void
|
||||
nsImageLoadingContent::NotifyOwnerDocumentChanged(nsIDocument *aOldDoc)
|
||||
{
|
||||
// If we had a document before, unregister ourselves with it.
|
||||
if (aOldDoc) {
|
||||
if (mCurrentRequest)
|
||||
aOldDoc->RemoveImage(mCurrentRequest);
|
||||
if (mPendingRequest)
|
||||
aOldDoc->RemoveImage(mPendingRequest);
|
||||
}
|
||||
|
||||
// Re-track the images
|
||||
TrackImage(mCurrentRequest);
|
||||
TrackImage(mPendingRequest);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsImageLoadingContent::LoadImage(const nsAString& aNewURI,
|
||||
bool aForce,
|
||||
bool aNotify)
|
||||
{
|
||||
// First, get a document (needed for security checks and the like)
|
||||
nsIDocument* doc = GetOurOwnerDoc();
|
||||
nsIDocument* doc = GetOurDocument();
|
||||
if (!doc) {
|
||||
// No reason to bother, I think...
|
||||
return NS_OK;
|
||||
@ -656,11 +668,11 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(!aDocument || aDocument == GetOurOwnerDoc(),
|
||||
NS_ASSERTION(!aDocument || aDocument == GetOurDocument(),
|
||||
"Bogus document passed in");
|
||||
// First, get a document (needed for security checks and the like)
|
||||
if (!aDocument) {
|
||||
aDocument = GetOurOwnerDoc();
|
||||
aDocument = GetOurDocument();
|
||||
if (!aDocument) {
|
||||
// No reason to bother, I think...
|
||||
return NS_OK;
|
||||
@ -716,7 +728,7 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
||||
}
|
||||
|
||||
// Not blocked. Do the load.
|
||||
RequestWithState& req = PrepareNextRequest();
|
||||
nsCOMPtr<imgIRequest>& req = PrepareNextRequest();
|
||||
nsresult rv;
|
||||
rv = nsContentUtils::LoadImage(aNewURI, aDocument,
|
||||
aDocument->NodePrincipal(),
|
||||
@ -728,7 +740,7 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
||||
} else {
|
||||
// If we don't have a current URI, we might as well store this URI so people
|
||||
// know what we tried (and failed) to load.
|
||||
if (!mCurrentRequest.Ptr())
|
||||
if (!mCurrentRequest)
|
||||
mCurrentURI = aNewURI;
|
||||
FireEvent(NS_LITERAL_STRING("error"));
|
||||
return NS_OK;
|
||||
@ -799,12 +811,12 @@ nsImageLoadingContent::UpdateImageState(bool aNotify)
|
||||
mSuppressed = PR_TRUE;
|
||||
} else if (mImageBlockingStatus == nsIContentPolicy::REJECT_TYPE) {
|
||||
mUserDisabled = PR_TRUE;
|
||||
} else if (!mCurrentRequest.Ptr()) {
|
||||
} else if (!mCurrentRequest) {
|
||||
// No current request means error, since we weren't disabled or suppressed
|
||||
mBroken = PR_TRUE;
|
||||
} else {
|
||||
PRUint32 currentLoadStatus;
|
||||
nsresult rv = mCurrentRequest.Ptr()->GetImageStatus(¤tLoadStatus);
|
||||
nsresult rv = mCurrentRequest->GetImageStatus(¤tLoadStatus);
|
||||
if (NS_FAILED(rv) || (currentLoadStatus & imgIRequest::STATUS_ERROR)) {
|
||||
mBroken = PR_TRUE;
|
||||
} else if (!(currentLoadStatus & imgIRequest::STATUS_SIZE_AVAILABLE)) {
|
||||
@ -836,7 +848,7 @@ nsImageLoadingContent::UseAsPrimaryRequest(imgIRequest* aRequest,
|
||||
ClearCurrentRequest(NS_BINDING_ABORTED);
|
||||
|
||||
// Clone the request we were given.
|
||||
RequestWithState& req = PrepareNextRequest();
|
||||
nsCOMPtr<imgIRequest>& req = PrepareNextRequest();;
|
||||
nsresult rv = aRequest->Clone(this, getter_AddRefs(req));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
TrackImage(req);
|
||||
@ -847,7 +859,7 @@ nsImageLoadingContent::UseAsPrimaryRequest(imgIRequest* aRequest,
|
||||
}
|
||||
|
||||
nsIDocument*
|
||||
nsImageLoadingContent::GetOurOwnerDoc()
|
||||
nsImageLoadingContent::GetOurDocument()
|
||||
{
|
||||
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
|
||||
NS_ENSURE_TRUE(thisContent, nsnull);
|
||||
@ -855,15 +867,6 @@ nsImageLoadingContent::GetOurOwnerDoc()
|
||||
return thisContent->GetOwnerDoc();
|
||||
}
|
||||
|
||||
nsIDocument*
|
||||
nsImageLoadingContent::GetOurCurrentDoc()
|
||||
{
|
||||
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
|
||||
NS_ENSURE_TRUE(thisContent, nsnull);
|
||||
|
||||
return thisContent->GetCurrentDoc();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsImageLoadingContent::StringToURI(const nsAString& aSpec,
|
||||
nsIDocument* aDocument,
|
||||
@ -904,19 +907,16 @@ nsImageLoadingContent::FireEvent(const nsAString& aEventType)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsImageLoadingContent::RequestWithState&
|
||||
nsCOMPtr<imgIRequest>&
|
||||
nsImageLoadingContent::PrepareNextRequest()
|
||||
{
|
||||
// If we don't have a usable current request, get rid of any half-baked
|
||||
// request that might be sitting there and make this one current.
|
||||
if (!HaveSize(mCurrentRequest.Ptr())) {
|
||||
PrepareCurrentRequest();
|
||||
return mCurrentRequest;
|
||||
}
|
||||
if (!HaveSize(mCurrentRequest))
|
||||
return PrepareCurrentRequest();
|
||||
|
||||
// Otherwise, make it pending.
|
||||
PreparePendingRequest();
|
||||
return mPendingRequest;
|
||||
return PreparePendingRequest();
|
||||
}
|
||||
|
||||
void
|
||||
@ -935,7 +935,7 @@ nsImageLoadingContent::SetBlockedRequest(nsIURI* aURI, PRInt16 aContentDecision)
|
||||
|
||||
// For the blocked case, we only want to cancel the existing current request
|
||||
// if size is not available. bz says the web depends on this behavior.
|
||||
if (!HaveSize(mCurrentRequest.Ptr())) {
|
||||
if (!HaveSize(mCurrentRequest)) {
|
||||
|
||||
mImageBlockingStatus = aContentDecision;
|
||||
ClearCurrentRequest(NS_ERROR_IMAGE_BLOCKED);
|
||||
@ -946,7 +946,7 @@ nsImageLoadingContent::SetBlockedRequest(nsIURI* aURI, PRInt16 aContentDecision)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsCOMPtr<imgIRequest>&
|
||||
nsImageLoadingContent::PrepareCurrentRequest()
|
||||
{
|
||||
// Blocked images go through SetBlockedRequest, which is a separate path. For
|
||||
@ -957,21 +957,27 @@ nsImageLoadingContent::PrepareCurrentRequest()
|
||||
ClearCurrentRequest(NS_ERROR_IMAGE_SRC_CHANGED);
|
||||
|
||||
mCurrentRequestNeedsResetAnimation = mNewRequestsWillNeedAnimationReset;
|
||||
|
||||
// Return a reference.
|
||||
return mCurrentRequest;
|
||||
}
|
||||
|
||||
void
|
||||
nsCOMPtr<imgIRequest>&
|
||||
nsImageLoadingContent::PreparePendingRequest()
|
||||
{
|
||||
// Get rid of anything that was there previously.
|
||||
ClearPendingRequest(NS_ERROR_IMAGE_SRC_CHANGED);
|
||||
|
||||
mPendingRequestNeedsResetAnimation = mNewRequestsWillNeedAnimationReset;
|
||||
|
||||
// Return a reference.
|
||||
return mPendingRequest;
|
||||
}
|
||||
|
||||
void
|
||||
nsImageLoadingContent::ClearCurrentRequest(nsresult aReason)
|
||||
{
|
||||
if (!mCurrentRequest.Ptr()) {
|
||||
if (!mCurrentRequest) {
|
||||
// Even if we didn't have a current request, we might have been keeping
|
||||
// a URI as a placeholder for a failed load. Clear that now.
|
||||
mCurrentURI = nsnull;
|
||||
@ -982,8 +988,8 @@ nsImageLoadingContent::ClearCurrentRequest(nsresult aReason)
|
||||
|
||||
// Clean up the request.
|
||||
UntrackImage(mCurrentRequest);
|
||||
mCurrentRequest.Ptr()->CancelAndForgetObserver(aReason);
|
||||
mCurrentRequest.Clear();
|
||||
mCurrentRequest->CancelAndForgetObserver(aReason);
|
||||
mCurrentRequest = nsnull;
|
||||
mCurrentRequestNeedsResetAnimation = PR_FALSE;
|
||||
|
||||
// We only block onload during the decoding of "current" images. This one is
|
||||
@ -994,7 +1000,7 @@ nsImageLoadingContent::ClearCurrentRequest(nsresult aReason)
|
||||
void
|
||||
nsImageLoadingContent::ClearPendingRequest(nsresult aReason)
|
||||
{
|
||||
if (!mPendingRequest.Ptr())
|
||||
if (!mPendingRequest)
|
||||
return;
|
||||
|
||||
// Push a null JSContext on the stack so that code that runs within
|
||||
@ -1004,8 +1010,8 @@ nsImageLoadingContent::ClearPendingRequest(nsresult aReason)
|
||||
pusher.PushNull();
|
||||
|
||||
UntrackImage(mPendingRequest);
|
||||
mPendingRequest.Ptr()->CancelAndForgetObserver(aReason);
|
||||
mPendingRequest.Clear();
|
||||
mPendingRequest->CancelAndForgetObserver(aReason);
|
||||
mPendingRequest = nsnull;
|
||||
mPendingRequestNeedsResetAnimation = PR_FALSE;
|
||||
}
|
||||
|
||||
@ -1030,7 +1036,7 @@ nsImageLoadingContent::SetBlockingOnload(bool aBlocking)
|
||||
return;
|
||||
|
||||
// Get the document
|
||||
nsIDocument* doc = GetOurOwnerDoc();
|
||||
nsIDocument* doc = GetOurDocument();
|
||||
|
||||
if (doc) {
|
||||
// Take the appropriate action
|
||||
@ -1044,68 +1050,30 @@ nsImageLoadingContent::SetBlockingOnload(bool aBlocking)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsImageLoadingContent::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers)
|
||||
{
|
||||
// We may be entering the document, so if our image should be tracked,
|
||||
// track it.
|
||||
if (!aDocument)
|
||||
return;
|
||||
|
||||
if (mCurrentRequest.Flag())
|
||||
aDocument->AddImage(mCurrentRequest.Ptr());
|
||||
if (mPendingRequest.Flag())
|
||||
aDocument->AddImage(mPendingRequest.Ptr());
|
||||
}
|
||||
|
||||
void
|
||||
nsImageLoadingContent::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
{
|
||||
// We may be leaving the document, so if our image is tracked, untrack it.
|
||||
nsCOMPtr<nsIDocument> doc = GetOurCurrentDoc();
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
if (mCurrentRequest.Flag())
|
||||
doc->RemoveImage(mCurrentRequest.Ptr());
|
||||
if (mPendingRequest.Flag())
|
||||
doc->RemoveImage(mPendingRequest.Ptr());
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsImageLoadingContent::TrackImage(RequestWithState& aImage)
|
||||
nsImageLoadingContent::TrackImage(imgIRequest* aImage)
|
||||
{
|
||||
if (!aImage.Ptr())
|
||||
if (!aImage)
|
||||
return NS_OK;
|
||||
|
||||
NS_ASSERTION(!aImage.Flag(), "Already tracked!?");
|
||||
|
||||
aImage.SetFlag(true);
|
||||
|
||||
nsIDocument* doc = GetOurCurrentDoc();
|
||||
nsIDocument* doc = GetOurDocument();
|
||||
if (doc)
|
||||
return doc->AddImage(aImage.Ptr());
|
||||
return doc->AddImage(aImage);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsImageLoadingContent::UntrackImage(RequestWithState& aImage)
|
||||
nsImageLoadingContent::UntrackImage(imgIRequest* aImage)
|
||||
{
|
||||
if (!aImage.Ptr())
|
||||
if (!aImage)
|
||||
return NS_OK;
|
||||
|
||||
NS_ASSERTION(aImage.Flag(), "Not already tracked!?");
|
||||
|
||||
aImage.SetFlag(false);
|
||||
|
||||
// If GetOurCurrentDoc() returns null here, we've outlived our document.
|
||||
// If GetOurDocument() returns null here, we've outlived our document.
|
||||
// That's fine, because the document empties out the tracker and unlocks
|
||||
// all locked images on destruction.
|
||||
nsIDocument* doc = GetOurCurrentDoc();
|
||||
nsIDocument* doc = GetOurDocument();
|
||||
if (doc)
|
||||
return doc->RemoveImage(aImage.Ptr());
|
||||
return doc->RemoveImage(aImage);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1113,7 +1081,7 @@ nsImageLoadingContent::UntrackImage(RequestWithState& aImage)
|
||||
void
|
||||
nsImageLoadingContent::CreateStaticImageClone(nsImageLoadingContent* aDest) const
|
||||
{
|
||||
aDest->mCurrentRequest.SetPtr(nsContentUtils::GetStaticRequest(mCurrentRequest.Ptr()));
|
||||
aDest->mCurrentRequest = nsContentUtils::GetStaticRequest(mCurrentRequest);
|
||||
aDest->TrackImage(aDest->mCurrentRequest);
|
||||
aDest->mForcedImageState = mForcedImageState;
|
||||
aDest->mImageBlockingStatus = mImageBlockingStatus;
|
||||
|
@ -53,7 +53,6 @@
|
||||
#include "nsContentUtils.h" // NS_CONTENT_DELETE_LIST_MEMBER
|
||||
#include "nsString.h"
|
||||
#include "nsEventStates.h"
|
||||
#include "mozilla/COMPtrAndFlag.h"
|
||||
|
||||
class nsIURI;
|
||||
class nsIDocument;
|
||||
@ -139,14 +138,13 @@ protected:
|
||||
nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL);
|
||||
|
||||
/**
|
||||
* helpers to get the document for this content (from the nodeinfo
|
||||
* and such). Not named GetOwnerDoc/GetCurrentDoc to prevent ambiguous
|
||||
* method names in subclasses
|
||||
* helper to get the document for this content (from the nodeinfo
|
||||
* and such). Not named GetDocument to prevent ambiguous method
|
||||
* names in subclasses
|
||||
*
|
||||
* @return the document we belong to
|
||||
*/
|
||||
nsIDocument* GetOurOwnerDoc();
|
||||
nsIDocument* GetOurCurrentDoc();
|
||||
nsIDocument* GetOurDocument();
|
||||
|
||||
/**
|
||||
* CancelImageRequests is called by subclasses when they want to
|
||||
@ -187,11 +185,6 @@ protected:
|
||||
*/
|
||||
virtual CORSMode GetCORSMode();
|
||||
|
||||
// Subclasses are *required* to call BindToTree/UnbindFromTree.
|
||||
void BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent, bool aCompileEventHandlers);
|
||||
void UnbindFromTree(bool aDeep, bool aNullParent);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Struct used to manage the image observers.
|
||||
@ -279,18 +272,13 @@ protected:
|
||||
|
||||
void CreateStaticImageClone(nsImageLoadingContent* aDest) const;
|
||||
|
||||
// The flag on these pointers tells whether or not the image "should" be
|
||||
// tracked by the document. The only situation in which we should be
|
||||
// tracked but aren't is when we are not in a document.
|
||||
typedef mozilla::COMPtrAndFlag<imgIRequest> RequestWithState;
|
||||
|
||||
/**
|
||||
* Prepare and returns a reference to the "next request". If there's already
|
||||
* a _usable_ current request (one with SIZE_AVAILABLE), this request is
|
||||
* "pending" until it becomes usable. Otherwise, this becomes the current
|
||||
* request.
|
||||
*/
|
||||
RequestWithState& PrepareNextRequest();
|
||||
nsCOMPtr<imgIRequest>& PrepareNextRequest();
|
||||
|
||||
/**
|
||||
* Called when we would normally call PrepareNextRequest(), but the request was
|
||||
@ -299,13 +287,14 @@ protected:
|
||||
void SetBlockedRequest(nsIURI* aURI, PRInt16 aContentDecision);
|
||||
|
||||
/**
|
||||
* Cleans up and cancels the appropriate request. Note that if you just want
|
||||
* Returns a COMPtr reference to the current/pending image requests, cleaning
|
||||
* up and canceling anything that was there before. Note that if you just want
|
||||
* to get rid of one of the requests, you should call
|
||||
* Clear*Request(NS_BINDING_ABORTED) instead, since it passes a more appropriate
|
||||
* aReason than Prepare*Request() does (NS_ERROR_IMAGE_SRC_CHANGED).
|
||||
*/
|
||||
void PrepareCurrentRequest();
|
||||
void PreparePendingRequest();
|
||||
nsCOMPtr<imgIRequest>& PrepareCurrentRequest();
|
||||
nsCOMPtr<imgIRequest>& PreparePendingRequest();
|
||||
|
||||
/**
|
||||
* Cancels and nulls-out the "current" and "pending" requests if they exist.
|
||||
@ -324,12 +313,12 @@ protected:
|
||||
*
|
||||
* No-op if aImage is null.
|
||||
*/
|
||||
nsresult TrackImage(RequestWithState& aImage);
|
||||
nsresult UntrackImage(RequestWithState& aImage);
|
||||
nsresult TrackImage(imgIRequest* aImage);
|
||||
nsresult UntrackImage(imgIRequest* aImage);
|
||||
|
||||
/* MEMBERS */
|
||||
RequestWithState mCurrentRequest;
|
||||
RequestWithState mPendingRequest;
|
||||
nsCOMPtr<imgIRequest> mCurrentRequest;
|
||||
nsCOMPtr<imgIRequest> mPendingRequest;
|
||||
|
||||
// If the image was blocked or if there was an error loading, it's nice to
|
||||
// still keep track of what the URI was despite not having an imgIRequest.
|
||||
|
@ -62,6 +62,7 @@
|
||||
#ifdef MOZ_MEDIA
|
||||
#include "nsHTMLMediaElement.h"
|
||||
#endif // MOZ_MEDIA
|
||||
#include "nsImageLoadingContent.h"
|
||||
#include "jsgc.h"
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
|
||||
@ -586,6 +587,13 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
|
||||
}
|
||||
#endif
|
||||
|
||||
// nsImageLoadingContent needs to know when its document changes
|
||||
if (oldDoc != newDoc) {
|
||||
nsCOMPtr<nsIImageLoadingContent> imageContent(do_QueryInterface(aNode));
|
||||
if (imageContent)
|
||||
imageContent->NotifyOwnerDocumentChanged(oldDoc);
|
||||
}
|
||||
|
||||
if (elem) {
|
||||
elem->RecompileScriptEventListeners();
|
||||
}
|
||||
|
@ -965,7 +965,7 @@ nsObjectLoadingContent::HasNewFrame(nsIObjectFrame* aFrame)
|
||||
|
||||
// When in a plugin document, the document will take care of calling
|
||||
// instantiate
|
||||
nsCOMPtr<nsIPluginDocument> pDoc (do_QueryInterface(GetOurOwnerDoc()));
|
||||
nsCOMPtr<nsIPluginDocument> pDoc (do_QueryInterface(GetOurDocument()));
|
||||
if (pDoc) {
|
||||
bool willHandleInstantiation;
|
||||
pDoc->GetWillHandleInstantiation(&willHandleInstantiation);
|
||||
|
@ -144,7 +144,6 @@ public:
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(bool aDeep, bool aNullParent);
|
||||
|
||||
virtual nsEventStates IntrinsicState() const;
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
@ -254,12 +253,12 @@ nsHTMLImageElement::GetComplete(bool* aComplete)
|
||||
NS_PRECONDITION(aComplete, "Null out param!");
|
||||
*aComplete = PR_TRUE;
|
||||
|
||||
if (!mCurrentRequest.Ptr()) {
|
||||
if (!mCurrentRequest) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint32 status;
|
||||
mCurrentRequest.Ptr()->GetImageStatus(&status);
|
||||
mCurrentRequest->GetImageStatus(&status);
|
||||
*aComplete =
|
||||
(status &
|
||||
(imgIRequest::STATUS_LOAD_COMPLETE | imgIRequest::STATUS_ERROR)) != 0;
|
||||
@ -282,8 +281,8 @@ nsHTMLImageElement::GetWidthHeight()
|
||||
} else {
|
||||
const nsAttrValue* value;
|
||||
nsCOMPtr<imgIContainer> image;
|
||||
if (mCurrentRequest.Ptr()) {
|
||||
mCurrentRequest.Ptr()->GetImage(getter_AddRefs(image));
|
||||
if (mCurrentRequest) {
|
||||
mCurrentRequest->GetImage(getter_AddRefs(image));
|
||||
}
|
||||
|
||||
if ((value = GetParsedAttr(nsGkAtoms::width)) &&
|
||||
@ -530,9 +529,6 @@ nsHTMLImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::src)) {
|
||||
// FIXME: Bug 660963 it would be nice if we could just have
|
||||
// ClearBrokenState update our state and do it fast...
|
||||
@ -550,13 +546,6 @@ nsHTMLImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLImageElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
{
|
||||
nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLImageElement::MaybeLoadImage()
|
||||
{
|
||||
@ -614,12 +603,12 @@ nsHTMLImageElement::GetNaturalHeight(PRUint32* aNaturalHeight)
|
||||
|
||||
*aNaturalHeight = 0;
|
||||
|
||||
if (!mCurrentRequest.Ptr()) {
|
||||
if (!mCurrentRequest) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIContainer> image;
|
||||
mCurrentRequest.Ptr()->GetImage(getter_AddRefs(image));
|
||||
mCurrentRequest->GetImage(getter_AddRefs(image));
|
||||
if (!image) {
|
||||
return NS_OK;
|
||||
}
|
||||
@ -638,12 +627,12 @@ nsHTMLImageElement::GetNaturalWidth(PRUint32* aNaturalWidth)
|
||||
|
||||
*aNaturalWidth = 0;
|
||||
|
||||
if (!mCurrentRequest.Ptr()) {
|
||||
if (!mCurrentRequest) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIContainer> image;
|
||||
mCurrentRequest.Ptr()->GetImage(getter_AddRefs(image));
|
||||
mCurrentRequest->GetImage(getter_AddRefs(image));
|
||||
if (!image) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2320,9 +2320,6 @@ nsHTMLInputElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
|
||||
if (mType == NS_FORM_INPUT_IMAGE) {
|
||||
// Our base URI may have changed; claim that our URI changed, and the
|
||||
// nsImageLoadingContent will decide whether a new image load is warranted.
|
||||
@ -2369,8 +2366,6 @@ nsHTMLInputElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
WillRemoveFromRadioGroup();
|
||||
}
|
||||
|
||||
nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
|
||||
|
||||
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
|
||||
|
||||
// GetCurrentDoc is returning nsnull so we can update the value
|
||||
|
@ -245,9 +245,6 @@ nsHTMLObjectElement::BindToTree(nsIDocument *aDocument,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
|
||||
// If we already have all the children, start the load.
|
||||
if (mIsDoneAddingChildren) {
|
||||
void (nsHTMLObjectElement::*start)() = &nsHTMLObjectElement::StartObjectLoad;
|
||||
@ -262,7 +259,6 @@ nsHTMLObjectElement::UnbindFromTree(bool aDeep,
|
||||
bool aNullParent)
|
||||
{
|
||||
RemovedFromDocument();
|
||||
nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
|
||||
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
|
@ -272,9 +272,6 @@ nsHTMLSharedObjectElement::BindToTree(nsIDocument *aDocument,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
|
||||
// If we already have all the children, start the load.
|
||||
if (mIsDoneAddingChildren) {
|
||||
void (nsHTMLSharedObjectElement::*start)() =
|
||||
@ -290,7 +287,6 @@ nsHTMLSharedObjectElement::UnbindFromTree(bool aDeep,
|
||||
bool aNullParent)
|
||||
{
|
||||
RemovedFromDocument();
|
||||
nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
|
@ -5343,7 +5343,6 @@ public:
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(bool aDeep, bool aNullParent);
|
||||
virtual nsEventStates IntrinsicState() const;
|
||||
|
||||
// imgIDecoderObserver
|
||||
@ -5501,9 +5500,6 @@ nsSVGFEImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
|
||||
if (mStringAttributes[HREF].IsExplicitlySet()) {
|
||||
// FIXME: Bug 660963 it would be nice if we could just have
|
||||
// ClearBrokenState update our state and do it fast...
|
||||
@ -5516,13 +5512,6 @@ nsSVGFEImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGFEImageElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
{
|
||||
nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
|
||||
nsSVGFEImageElementBase::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
nsEventStates
|
||||
nsSVGFEImageElement::IntrinsicState() const
|
||||
{
|
||||
|
@ -208,9 +208,6 @@ nsSVGImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
|
||||
if (mStringAttributes[HREF].IsExplicitlySet()) {
|
||||
// FIXME: Bug 660963 it would be nice if we could just have
|
||||
// ClearBrokenState update our state and do it fast...
|
||||
@ -223,13 +220,6 @@ nsSVGImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGImageElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
{
|
||||
nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
|
||||
nsSVGImageElementBase::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
nsEventStates
|
||||
nsSVGImageElement::IntrinsicState() const
|
||||
{
|
||||
|
@ -82,7 +82,6 @@ public:
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(bool aDeep, bool aNullParent);
|
||||
|
||||
virtual nsEventStates IntrinsicState() const;
|
||||
|
||||
|
@ -85,6 +85,7 @@ static PRLogModuleInfo *gCompressedImageAccountingLog = PR_NewLogModule ("Compre
|
||||
// Tweakable progressive decoding parameters
|
||||
static PRUint32 gDecodeBytesAtATime = 200000;
|
||||
static PRUint32 gMaxMSBeforeYield = 400;
|
||||
static PRUint32 gMaxBytesForSyncDecode = 150000;
|
||||
|
||||
void
|
||||
RasterImage::SetDecodeBytesAtATime(PRUint32 aBytesAtATime)
|
||||
@ -96,6 +97,11 @@ RasterImage::SetMaxMSBeforeYield(PRUint32 aMaxMS)
|
||||
{
|
||||
gMaxMSBeforeYield = aMaxMS;
|
||||
}
|
||||
void
|
||||
RasterImage::SetMaxBytesForSyncDecode(PRUint32 aMaxBytes)
|
||||
{
|
||||
gMaxBytesForSyncDecode = aMaxBytes;
|
||||
}
|
||||
|
||||
/* We define our own error checking macros here for 2 reasons:
|
||||
*
|
||||
@ -683,12 +689,10 @@ RasterImage::GetFrame(PRUint32 aWhichFrame,
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
PRUint32 desiredDecodeFlags = aFlags & DECODE_FLAGS_MASK;
|
||||
|
||||
if (mDecoded) {
|
||||
// If we have decoded data, and it is not a perfect match for what we are
|
||||
// looking for, we must discard to be able to generate the proper data.
|
||||
|
||||
PRUint32 desiredDecodeFlags = aFlags & DECODE_FLAGS_MASK;
|
||||
if (desiredDecodeFlags != mFrameDecodeFlags) {
|
||||
// if we can't discard, then we're screwed; we have no way
|
||||
// to re-decode. Similarly if we aren't allowed to do a sync
|
||||
@ -699,11 +703,11 @@ RasterImage::GetFrame(PRUint32 aWhichFrame,
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
ForceDiscard();
|
||||
|
||||
mFrameDecodeFlags = desiredDecodeFlags;
|
||||
}
|
||||
}
|
||||
|
||||
mFrameDecodeFlags = desiredDecodeFlags;
|
||||
|
||||
// If the caller requested a synchronous decode, do it
|
||||
if (aFlags & FLAG_SYNC_DECODE) {
|
||||
rv = SyncDecode();
|
||||
@ -2382,12 +2386,13 @@ RasterImage::RequestDecode()
|
||||
if (mBytesDecoded == mSourceData.Length())
|
||||
return NS_OK;
|
||||
|
||||
// If we can do decoding now, do so. Small images will decode completely,
|
||||
// large images will decode a bit and post themselves to the event loop
|
||||
// to finish decoding.
|
||||
if (!mDecoded && !mInDecoder && mHasSourceData)
|
||||
return mWorker->Run();
|
||||
// If it's a smallish image, it's not worth it to do things async
|
||||
if (!mDecoded && !mInDecoder && mHasSourceData && (mSourceData.Length() < gMaxBytesForSyncDecode))
|
||||
return SyncDecode();
|
||||
|
||||
// If we get this far, dispatch the worker. We do this instead of starting
|
||||
// any immediate decoding to guarantee that all our decode notifications are
|
||||
// dispatched asynchronously, and to ensure we stay responsive.
|
||||
return mWorker->Dispatch();
|
||||
}
|
||||
|
||||
|
@ -88,6 +88,7 @@
|
||||
#define DECODEONDRAW_PREF "image.mem.decodeondraw"
|
||||
#define BYTESATATIME_PREF "image.mem.decode_bytes_at_a_time"
|
||||
#define MAXMS_PREF "image.mem.max_ms_before_yield"
|
||||
#define MAXBYTESFORSYNC_PREF "image.mem.max_bytes_for_sync_decode"
|
||||
#define SVG_MIMETYPE "image/svg+xml"
|
||||
|
||||
using namespace mozilla;
|
||||
@ -131,6 +132,11 @@ ReloadPrefs()
|
||||
RasterImage::SetMaxMSBeforeYield(maxMS);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(Preferences::GetInt(MAXBYTESFORSYNC_PREF,
|
||||
&maxBytesForSync))) {
|
||||
RasterImage::SetMaxBytesForSyncDecode(maxBytesForSync);
|
||||
}
|
||||
|
||||
// Discard timeout
|
||||
mozilla::imagelib::DiscardTracker::ReloadTimeout();
|
||||
}
|
||||
|
@ -3276,6 +3276,9 @@ pref("image.mem.decode_bytes_at_a_time", 4096);
|
||||
// The longest time we can spend in an iteration of an async decode
|
||||
pref("image.mem.max_ms_before_yield", 5);
|
||||
|
||||
// The maximum source data size for which we auto sync decode
|
||||
pref("image.mem.max_bytes_for_sync_decode", 150000);
|
||||
|
||||
// WebGL prefs
|
||||
pref("webgl.force-enabled", false);
|
||||
pref("webgl.disabled", false);
|
||||
|
@ -1,269 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Kyle Huey <me@kylehuey.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 ***** */
|
||||
|
||||
#ifndef mozilla_PtrAndFlag_h__
|
||||
#define mozilla_PtrAndFlag_h__
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "mozilla/Types.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace please_dont_use_this_directly {
|
||||
template <class T>
|
||||
class COMPtrAndFlagGetterAddRefs;
|
||||
}
|
||||
|
||||
// A class designed to allow stealing a bit from an nsCOMPtr.
|
||||
template <class T>
|
||||
class COMPtrAndFlag
|
||||
{
|
||||
// A RAII class that saves/restores the flag, allowing the COMPtr to be
|
||||
// manipulated directly.
|
||||
class AutoFlagPersister
|
||||
{
|
||||
public:
|
||||
AutoFlagPersister(uintptr_t* aPtr)
|
||||
: mPtr(aPtr), mFlag(*aPtr & 0x1)
|
||||
{
|
||||
if (mFlag)
|
||||
*mPtr &= ~0x1;
|
||||
}
|
||||
|
||||
~AutoFlagPersister()
|
||||
{
|
||||
if (mFlag)
|
||||
*mPtr |= 0x1;
|
||||
}
|
||||
private:
|
||||
uintptr_t *mPtr;
|
||||
bool mFlag;
|
||||
};
|
||||
|
||||
template <class U>
|
||||
friend class please_dont_use_this_directly::COMPtrAndFlagGetterAddRefs;
|
||||
|
||||
public:
|
||||
COMPtrAndFlag()
|
||||
{
|
||||
Set(nsnull, false);
|
||||
}
|
||||
|
||||
COMPtrAndFlag(T* aPtr, bool aFlag)
|
||||
{
|
||||
Set(aPtr, aFlag);
|
||||
}
|
||||
|
||||
COMPtrAndFlag(const nsQueryInterface aPtr, bool aFlag)
|
||||
{
|
||||
Set(aPtr, aFlag);
|
||||
}
|
||||
|
||||
COMPtrAndFlag(const already_AddRefed<T>& aPtr, bool aFlag)
|
||||
{
|
||||
Set(aPtr, aFlag);
|
||||
}
|
||||
|
||||
~COMPtrAndFlag()
|
||||
{
|
||||
// Make sure we unset the flag before nsCOMPtr's dtor tries to
|
||||
// Release, or we might explode.
|
||||
UnsetFlag();
|
||||
}
|
||||
|
||||
COMPtrAndFlag<T>&
|
||||
operator= (const COMPtrAndFlag<T>& rhs)
|
||||
{
|
||||
Set(rhs.Ptr(), rhs.Flag());
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Set(T* aPtr, bool aFlag)
|
||||
{
|
||||
SetInternal(aPtr, aFlag);
|
||||
}
|
||||
|
||||
void Set(const nsQueryInterface aPtr, bool aFlag)
|
||||
{
|
||||
SetInternal(aPtr, aFlag);
|
||||
}
|
||||
|
||||
void Set(const already_AddRefed<T>& aPtr, bool aFlag)
|
||||
{
|
||||
SetInternal(aPtr, aFlag);
|
||||
}
|
||||
|
||||
void UnsetFlag()
|
||||
{
|
||||
SetFlag(false);
|
||||
}
|
||||
|
||||
void SetFlag(bool aFlag)
|
||||
{
|
||||
if (aFlag) {
|
||||
*VoidPtr() |= 0x1;
|
||||
} else {
|
||||
*VoidPtr() &= ~0x1;
|
||||
}
|
||||
}
|
||||
|
||||
bool Flag() const
|
||||
{
|
||||
return *VoidPtr() & 0x1;
|
||||
}
|
||||
|
||||
void SetPtr(T* aPtr)
|
||||
{
|
||||
SetInternal(aPtr);
|
||||
}
|
||||
|
||||
void SetPtr(const nsQueryInterface aPtr)
|
||||
{
|
||||
SetInternal(aPtr);
|
||||
}
|
||||
|
||||
void SetPtr(const already_AddRefed<T>& aPtr)
|
||||
{
|
||||
SetInternal(aPtr);
|
||||
}
|
||||
|
||||
T* Ptr() const
|
||||
{
|
||||
return reinterpret_cast<T*>(*VoidPtr() & ~0x1);
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
Set(nsnull, false);
|
||||
}
|
||||
|
||||
private:
|
||||
template<class PtrType>
|
||||
void SetInternal(PtrType aPtr, bool aFlag)
|
||||
{
|
||||
UnsetFlag();
|
||||
mCOMPtr = aPtr;
|
||||
SetFlag(aFlag);
|
||||
}
|
||||
|
||||
template<class PtrType>
|
||||
void SetInternal(PtrType aPtr)
|
||||
{
|
||||
AutoFlagPersister saveFlag(VoidPtr());
|
||||
mCOMPtr = aPtr;
|
||||
}
|
||||
|
||||
uintptr_t* VoidPtr() const {
|
||||
return (uintptr_t*)(&mCOMPtr);
|
||||
}
|
||||
|
||||
// Don't modify this without using the AutoFlagPersister, or you will explode
|
||||
nsCOMPtr<T> mCOMPtr;
|
||||
};
|
||||
|
||||
namespace please_dont_use_this_directly {
|
||||
/*
|
||||
...
|
||||
|
||||
This class is designed to be used for anonymous temporary objects in the
|
||||
argument list of calls that return COM interface pointers, e.g.,
|
||||
|
||||
COMPtrAndFlag<IFoo> fooP;
|
||||
...->GetAddRefedPointer(getter_AddRefs(fooP))
|
||||
|
||||
DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |getter_AddRefs()| instead.
|
||||
|
||||
When initialized with a |COMPtrAndFlag|, as in the example above, it returns
|
||||
a |void**|, a |T**|, or an |nsISupports**| as needed, that the
|
||||
outer call (|GetAddRefedPointer| in this case) can fill in.
|
||||
*/
|
||||
template <class T>
|
||||
class COMPtrAndFlagGetterAddRefs
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
COMPtrAndFlagGetterAddRefs( COMPtrAndFlag<T>& aSmartPtr )
|
||||
: mTargetSmartPtr(aSmartPtr), mFlag(aSmartPtr.Flag())
|
||||
{
|
||||
if (mFlag)
|
||||
aSmartPtr.UnsetFlag();
|
||||
}
|
||||
|
||||
~COMPtrAndFlagGetterAddRefs()
|
||||
{
|
||||
if (mFlag)
|
||||
mTargetSmartPtr.SetFlag(true);
|
||||
}
|
||||
|
||||
operator void**()
|
||||
{
|
||||
return reinterpret_cast<void**>(mTargetSmartPtr.VoidPtr());
|
||||
}
|
||||
|
||||
operator T**()
|
||||
{
|
||||
return reinterpret_cast<T**>(mTargetSmartPtr.VoidPtr());
|
||||
}
|
||||
|
||||
T*&
|
||||
operator*()
|
||||
{
|
||||
return *reinterpret_cast<T**>(mTargetSmartPtr.VoidPtr());
|
||||
}
|
||||
|
||||
private:
|
||||
COMPtrAndFlag<T>& mTargetSmartPtr;
|
||||
bool mFlag;
|
||||
};
|
||||
|
||||
} // namespace please_dont_use_this_directly
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
mozilla::please_dont_use_this_directly::COMPtrAndFlagGetterAddRefs<T>
|
||||
getter_AddRefs( mozilla::COMPtrAndFlag<T>& aSmartPtr )
|
||||
/*
|
||||
Used around a |COMPtrWithFlag| when
|
||||
...makes the class |COMPtrWithFlag::GetterAddRefs<T>| invisible.
|
||||
*/
|
||||
{
|
||||
return mozilla::please_dont_use_this_directly::COMPtrAndFlagGetterAddRefs<T>(aSmartPtr);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
@ -119,7 +119,6 @@ EXPORTS = \
|
||||
EXPORTS_mozilla = \
|
||||
AutoRestore.h \
|
||||
BlockingResourceBase.h \
|
||||
COMPtrAndFlag.h \
|
||||
CondVar.h \
|
||||
DeadlockDetector.h \
|
||||
FileUtils.h \
|
||||
|
@ -40,7 +40,6 @@
|
||||
#include <stdio.h>
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsISupports.h"
|
||||
#include "mozilla/COMPtrAndFlag.h"
|
||||
|
||||
#define NS_IFOO_IID \
|
||||
{ 0x6f7652e0, 0xee43, 0x11d1, \
|
||||
@ -588,43 +587,6 @@ main()
|
||||
AnISupportsPtrPtrContext( getter_AddRefs(supportsP) );
|
||||
}
|
||||
|
||||
{
|
||||
IBar* ibar1 = new IBar;
|
||||
mozilla::COMPtrAndFlag<IFoo> foop( do_QueryInterface(ibar1) , false);
|
||||
if (foop.Flag())
|
||||
return -1;
|
||||
if (foop.Ptr() != ibar1)
|
||||
return -1;
|
||||
|
||||
foop.SetFlag(true);
|
||||
if (!foop.Flag())
|
||||
return -1;
|
||||
if (foop.Ptr() != ibar1)
|
||||
return -1;
|
||||
|
||||
IBar* ibar2 = new IBar;
|
||||
mozilla::COMPtrAndFlag<IFoo> foop2( do_QueryInterface(ibar2) , true);
|
||||
|
||||
if (!foop2.Flag())
|
||||
return -1;
|
||||
if (foop2.Ptr() != ibar2)
|
||||
return -1;
|
||||
|
||||
foop2.SetFlag(false);
|
||||
if (foop2.Flag())
|
||||
return -1;
|
||||
if (foop2.Ptr() != ibar2)
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
mozilla::COMPtrAndFlag<nsISupports> supportsP;
|
||||
|
||||
AVoidPtrPtrContext( getter_AddRefs(supportsP) );
|
||||
AnISupportsPtrPtrContext( getter_AddRefs(supportsP) );
|
||||
}
|
||||
|
||||
|
||||
printf("\n### Test 25: will a static |nsCOMPtr| |Release| before program termination?\n");
|
||||
gFoop = do_QueryInterface(new IFoo);
|
||||
|
Loading…
Reference in New Issue
Block a user