зеркало из https://github.com/mozilla/gecko-dev.git
Bug 825527 - Part 4: Mirror the nsIImageLoadingContent API in HTMLImageElement for chrome callers; r=bzbarsky
This commit is contained in:
Родитель
fd6ad89073
Коммит
e3a4f8e6ac
|
@ -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);
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче