зеркало из 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
|
* 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);
|
||||||
};
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче