Bug 825527 - Part 4: Mirror the nsIImageLoadingContent API in HTMLImageElement for chrome callers; r=bzbarsky

This commit is contained in:
Ehsan Akhgari 2013-01-02 14:30:02 -05:00
Родитель fd6ad89073
Коммит e3a4f8e6ac
5 изменённых файлов: 171 добавлений и 55 удалений

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

@ -32,6 +32,9 @@ interface nsIFrame;
* missed. We should NOT freeze this interface without considering * missed. We should NOT freeze this interface without considering
* this issue. (It could be that the image status on imgIRequest is * this issue. (It could be that the image status on imgIRequest is
* sufficient, when combined with the imageBlockingStatus information.) * sufficient, when combined with the imageBlockingStatus information.)
*
* Please make sure to update the HTMLImageElement Web IDL interface to
* mirror this interface when changing it.
*/ */
[scriptable, builtinclass, uuid(497bfb9b-d996-4d1e-a647-8137b0cfc876)] [scriptable, builtinclass, uuid(497bfb9b-d996-4d1e-a647-8137b0cfc876)]

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

@ -273,7 +273,7 @@ nsImageLoadingContent::GetImageBlockingStatus(int16_t* aStatus)
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
NS_PRECONDITION(aStatus, "Null out param"); NS_PRECONDITION(aStatus, "Null out param");
*aStatus = mImageBlockingStatus; *aStatus = ImageBlockingStatus();
return NS_OK; return NS_OK;
} }
@ -341,25 +341,36 @@ nsImageLoadingContent::RemoveObserver(imgINotificationObserver* aObserver)
return NS_OK; return NS_OK;
} }
already_AddRefed<imgIRequest>
nsImageLoadingContent::GetRequest(int32_t aRequestType,
ErrorResult& aError)
{
nsCOMPtr<imgIRequest> request;
switch(aRequestType) {
case CURRENT_REQUEST:
request = mCurrentRequest;
break;
case PENDING_REQUEST:
request = mPendingRequest;
break;
default:
NS_ERROR("Unknown request type");
aError.Throw(NS_ERROR_UNEXPECTED);
}
return request.forget();
}
NS_IMETHODIMP NS_IMETHODIMP
nsImageLoadingContent::GetRequest(int32_t aRequestType, nsImageLoadingContent::GetRequest(int32_t aRequestType,
imgIRequest** aRequest) imgIRequest** aRequest)
{ {
switch(aRequestType) { NS_ENSURE_ARG_POINTER(aRequest);
case CURRENT_REQUEST:
*aRequest = mCurrentRequest; ErrorResult result;
break; *aRequest = GetRequest(aRequestType, result).get();
case PENDING_REQUEST:
*aRequest = mPendingRequest; return result.ErrorCode();
break;
default:
NS_ERROR("Unknown request type");
*aRequest = nullptr;
return NS_ERROR_UNEXPECTED;
}
NS_IF_ADDREF(*aRequest);
return NS_OK;
} }
NS_IMETHODIMP_(void) NS_IMETHODIMP_(void)
@ -401,6 +412,23 @@ nsImageLoadingContent::FrameDestroyed(nsIFrame* aFrame)
} }
} }
int32_t
nsImageLoadingContent::GetRequestType(imgIRequest* aRequest,
ErrorResult& aError)
{
if (aRequest == mCurrentRequest) {
return CURRENT_REQUEST;
}
if (aRequest == mPendingRequest) {
return PENDING_REQUEST;
}
NS_ERROR("Unknown request");
aError.Throw(NS_ERROR_UNEXPECTED);
return UNKNOWN_REQUEST;
}
NS_IMETHODIMP NS_IMETHODIMP
nsImageLoadingContent::GetRequestType(imgIRequest* aRequest, nsImageLoadingContent::GetRequestType(imgIRequest* aRequest,
int32_t* aRequestType) int32_t* aRequestType)
@ -408,51 +436,51 @@ nsImageLoadingContent::GetRequestType(imgIRequest* aRequest,
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
NS_PRECONDITION(aRequestType, "Null out param"); NS_PRECONDITION(aRequestType, "Null out param");
if (aRequest == mCurrentRequest) { ErrorResult result;
*aRequestType = CURRENT_REQUEST; *aRequestType = GetRequestType(aRequest, result);
return NS_OK; return result.ErrorCode();
}
already_AddRefed<nsIURI>
nsImageLoadingContent::GetCurrentURI(ErrorResult& aError)
{
nsCOMPtr<nsIURI> uri;
if (mCurrentRequest) {
mCurrentRequest->GetURI(getter_AddRefs(uri));
} else if (mCurrentURI) {
nsresult rv = NS_EnsureSafeToReturn(mCurrentURI, getter_AddRefs(uri));
if (NS_FAILED(rv)) {
aError.Throw(rv);
}
} }
if (aRequest == mPendingRequest) { return uri.forget();
*aRequestType = PENDING_REQUEST;
return NS_OK;
}
*aRequestType = UNKNOWN_REQUEST;
NS_ERROR("Unknown request");
return NS_ERROR_UNEXPECTED;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsImageLoadingContent::GetCurrentURI(nsIURI** aURI) nsImageLoadingContent::GetCurrentURI(nsIURI** aURI)
{ {
if (mCurrentRequest) { NS_ENSURE_ARG_POINTER(aURI);
return mCurrentRequest->GetURI(aURI);
}
if (!mCurrentURI) { ErrorResult result;
*aURI = nullptr; *aURI = GetCurrentURI(result).get();
return NS_OK; return result.ErrorCode();
}
return NS_EnsureSafeToReturn(mCurrentURI, aURI);
} }
NS_IMETHODIMP already_AddRefed<nsIStreamListener>
nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel, nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel,
nsIStreamListener** aListener) ErrorResult& aError)
{ {
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
if (!nsContentUtils::GetImgLoaderForChannel(aChannel)) { if (!nsContentUtils::GetImgLoaderForChannel(aChannel)) {
return NS_ERROR_NULL_POINTER; aError.Throw(NS_ERROR_NULL_POINTER);
return nullptr;
} }
nsCOMPtr<nsIDocument> doc = GetOurOwnerDoc(); nsCOMPtr<nsIDocument> doc = GetOurOwnerDoc();
if (!doc) { if (!doc) {
// Don't bother // Don't bother
return NS_OK; return nullptr;
} }
// XXX what should we do with content policies here, if anything? // XXX what should we do with content policies here, if anything?
@ -463,9 +491,11 @@ nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel,
AutoStateChanger changer(this, true); AutoStateChanger changer(this, true);
// Do the load. // Do the load.
nsCOMPtr<nsIStreamListener> listener;
nsRefPtr<imgRequestProxy>& req = PrepareNextRequest(); nsRefPtr<imgRequestProxy>& req = PrepareNextRequest();
nsresult rv = nsContentUtils::GetImgLoaderForChannel(aChannel)-> nsresult rv = nsContentUtils::GetImgLoaderForChannel(aChannel)->
LoadImageWithChannel(aChannel, this, doc, aListener, LoadImageWithChannel(aChannel, this, doc,
getter_AddRefs(listener),
getter_AddRefs(req)); getter_AddRefs(req));
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
TrackImage(req); TrackImage(req);
@ -476,22 +506,46 @@ nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel,
if (!mCurrentRequest) if (!mCurrentRequest)
aChannel->GetURI(getter_AddRefs(mCurrentURI)); aChannel->GetURI(getter_AddRefs(mCurrentURI));
FireEvent(NS_LITERAL_STRING("error")); FireEvent(NS_LITERAL_STRING("error"));
return rv; aError.Throw(rv);
}
return listener.forget();
}
NS_IMETHODIMP
nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel,
nsIStreamListener** aListener)
{
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
NS_ENSURE_ARG_POINTER(aListener);
ErrorResult result;
*aListener = LoadImageWithChannel(aChannel, result).get();
return result.ErrorCode();
}
void
nsImageLoadingContent::ForceReload(ErrorResult& aError)
{
nsCOMPtr<nsIURI> currentURI;
GetCurrentURI(getter_AddRefs(currentURI));
if (!currentURI) {
aError.Throw(NS_ERROR_NOT_AVAILABLE);
return;
}
nsresult rv = LoadImage(currentURI, true, true, nullptr, nsIRequest::VALIDATE_ALWAYS);
if (NS_FAILED(rv)) {
aError.Throw(rv);
} }
return NS_OK;;
} }
NS_IMETHODIMP nsImageLoadingContent::ForceReload() NS_IMETHODIMP nsImageLoadingContent::ForceReload()
{ {
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
nsCOMPtr<nsIURI> currentURI; ErrorResult result;
GetCurrentURI(getter_AddRefs(currentURI)); ForceReload(result);
if (!currentURI) { return result.ErrorCode();
return NS_ERROR_NOT_AVAILABLE;
}
return LoadImage(currentURI, true, true, nullptr, nsIRequest::VALIDATE_ALWAYS);
} }
NS_IMETHODIMP NS_IMETHODIMP

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

@ -39,6 +39,27 @@ public:
NS_DECL_NSIIMAGELOADINGCONTENT NS_DECL_NSIIMAGELOADINGCONTENT
NS_DECL_IMGIONLOADBLOCKER NS_DECL_IMGIONLOADBLOCKER
// Web IDL binding methods.
// Note that the XPCOM SetLoadingEnabled, AddObserver, RemoveObserver,
// ForceImageState methods are OK for Web IDL bindings to use as well,
// since none of them throw when called via the Web IDL bindings.
bool LoadingEnabled() const { return mLoadingEnabled; }
int16_t ImageBlockingStatus() const
{
return mImageBlockingStatus;
}
already_AddRefed<imgIRequest>
GetRequest(int32_t aRequestType, mozilla::ErrorResult& aError);
int32_t
GetRequestType(imgIRequest* aRequest, mozilla::ErrorResult& aError);
already_AddRefed<nsIURI> GetCurrentURI(mozilla::ErrorResult& aError);
already_AddRefed<nsIStreamListener>
LoadImageWithChannel(nsIChannel* aChannel, mozilla::ErrorResult& aError);
void ForceReload(mozilla::ErrorResult& aError);
protected: protected:
/** /**
* LoadImage is called by subclasses when the appropriate * LoadImage is called by subclasses when the appropriate
@ -142,8 +163,6 @@ protected:
void ClearBrokenState() { mBroken = false; } void ClearBrokenState() { mBroken = false; }
bool LoadingEnabled() { return mLoadingEnabled; }
// Sets blocking state only if the desired state is different from the // Sets blocking state only if the desired state is different from the
// current one. See the comment for mBlockingOnload for more information. // current one. See the comment for mBlockingOnload for more information.
void SetBlockingOnload(bool aBlocking); void SetBlockingOnload(bool aBlocking);
@ -234,6 +253,7 @@ private:
* @param aEventType "load" or "error" depending on how things went * @param aEventType "load" or "error" depending on how things went
*/ */
nsresult FireEvent(const nsAString& aEventType); nsresult FireEvent(const nsAString& aEventType);
protected: protected:
/** /**
* Method to create an nsIURI object from the given string (will * Method to create an nsIURI object from the given string (will

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

@ -1041,10 +1041,13 @@ addExternalIface('File')
addExternalIface('HitRegionOptions', nativeType='nsISupports') addExternalIface('HitRegionOptions', nativeType='nsISupports')
addExternalIface('HTMLHeadElement', nativeType='mozilla::dom::Element') addExternalIface('HTMLHeadElement', nativeType='mozilla::dom::Element')
addExternalIface('HTMLImageElement', nativeType='mozilla::dom::HTMLImageElement') addExternalIface('HTMLImageElement', nativeType='mozilla::dom::HTMLImageElement')
addExternalIface('imgINotificationObserver', nativeType='imgINotificationObserver')
addExternalIface('imgIRequest', nativeType='imgIRequest', notflattened=True)
addExternalIface('LockedFile') addExternalIface('LockedFile')
addExternalIface('MediaStream') addExternalIface('MediaStream')
addExternalIface('NamedNodeMap') addExternalIface('NamedNodeMap')
addExternalIface('NodeIterator') addExternalIface('NodeIterator')
addExternalIface('nsIStreamListener', nativeType='nsIStreamListener', notflattened=True)
addExternalIface('nsISupports', nativeType='nsISupports') addExternalIface('nsISupports', nativeType='nsISupports')
addExternalIface('OutputStream', nativeType='nsIOutputStream', addExternalIface('OutputStream', nativeType='nsIOutputStream',
notflattened=True) notflattened=True)

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

@ -11,6 +11,12 @@
* and create derivative works of this document. * and create derivative works of this document.
*/ */
interface imgINotificationObserver;
interface imgIRequest;
interface URI;
interface MozChannel;
interface nsIStreamListener;
[NamedConstructor=Image(), [NamedConstructor=Image(),
NamedConstructor=Image(unsigned long width), NamedConstructor=Image(unsigned long width),
NamedConstructor=Image(unsigned long width, unsigned long height)] NamedConstructor=Image(unsigned long width, unsigned long height)]
@ -50,4 +56,34 @@ partial interface HTMLImageElement {
attribute DOMString longDesc; attribute DOMString longDesc;
[TreatNullAs=EmptyString,SetterThrows] attribute DOMString border; [TreatNullAs=EmptyString,SetterThrows] attribute DOMString border;
// Mirrored chrome-only nsIImageLoadingContent methods. Please make sure
// to update this list if nsIImageLoadingContent changes.
[ChromeOnly]
const long UNKNOWN_REQUEST = -1;
[ChromeOnly]
const long CURRENT_REQUEST = 0;
[ChromeOnly]
const long PENDING_REQUEST = 1;
[ChromeOnly]
attribute boolean loadingEnabled;
[ChromeOnly]
readonly attribute short imageBlockingStatus;
[ChromeOnly]
void addObserver(imgINotificationObserver aObserver);
[ChromeOnly]
void removeObserver(imgINotificationObserver aObserver);
[ChromeOnly,Throws]
imgIRequest? getRequest(long aRequestType);
[ChromeOnly,Throws]
long getRequestType(imgIRequest aRequest);
[ChromeOnly,Throws]
readonly attribute URI? currentURI;
[ChromeOnly,Throws]
nsIStreamListener? loadImageWithChannel(MozChannel aChannel);
[ChromeOnly,Throws]
void forceReload();
[ChromeOnly]
void forceImageState(boolean aForce, unsigned long long aState);
}; };