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
* this issue. (It could be that the image status on imgIRequest is
* 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)]

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

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

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

@ -39,6 +39,27 @@ public:
NS_DECL_NSIIMAGELOADINGCONTENT
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:
/**
* LoadImage is called by subclasses when the appropriate
@ -142,8 +163,6 @@ protected:
void ClearBrokenState() { mBroken = false; }
bool LoadingEnabled() { return mLoadingEnabled; }
// Sets blocking state only if the desired state is different from the
// current one. See the comment for mBlockingOnload for more information.
void SetBlockingOnload(bool aBlocking);
@ -234,6 +253,7 @@ private:
* @param aEventType "load" or "error" depending on how things went
*/
nsresult FireEvent(const nsAString& aEventType);
protected:
/**
* Method to create an nsIURI object from the given string (will

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

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

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

@ -11,6 +11,12 @@
* and create derivative works of this document.
*/
interface imgINotificationObserver;
interface imgIRequest;
interface URI;
interface MozChannel;
interface nsIStreamListener;
[NamedConstructor=Image(),
NamedConstructor=Image(unsigned long width),
NamedConstructor=Image(unsigned long width, unsigned long height)]
@ -50,4 +56,34 @@ partial interface HTMLImageElement {
attribute DOMString longDesc;
[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);
};