зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1431760 - Add NS_MutateURI.Apply that allows calling methods declared in other interfaces implemented by NS_MutateURI::mMutator r=mayhemer
* The method can be chained just as the other methods on NS_MutateURI. * In case the mutator object does not implement the interface, mStatus will be set to an error code. * This is useful when you are constructing a new URI and the type of the mutator is known. I expect a future patch will add a MaybeApply method, that does not set mStatus to an error code if the mutator does not implement the interface. * This patch changes nsHostObjectProtocolHandler::NewURI to use the new method and avoid a static_cast<nsHostObjectURI*>(uri) MozReview-Commit-ID: 9kvXJX54gUP --HG-- extra : rebase_source : 2a27778ec583251fac26c74d78125bd7266d6d87
This commit is contained in:
Родитель
00db51f54b
Коммит
a48c8f1ada
|
@ -892,20 +892,23 @@ nsHostObjectProtocolHandler::NewURI(const nsACString& aSpec,
|
|||
|
||||
DataInfo* info = GetDataInfo(aSpec);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
RefPtr<mozilla::dom::BlobImpl> blob;
|
||||
if (info && info->mObjectType == DataInfo::eBlobImpl) {
|
||||
MOZ_ASSERT(info->mBlobImpl);
|
||||
principal = info->mPrincipal;
|
||||
blob = info->mBlobImpl;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = NS_MutateURI(new nsHostObjectURI::Mutator())
|
||||
.SetSpec(aSpec)
|
||||
.Apply<nsIBlobURIMutator>(&nsIBlobURIMutator::SetBlobImpl, blob)
|
||||
.Apply<nsIPrincipalURIMutator>(&nsIPrincipalURIMutator::SetPrincipal, principal)
|
||||
.Finalize(uri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
RefPtr<nsHostObjectURI> hostURI = static_cast<nsHostObjectURI*>(uri.get());
|
||||
if (info && info->mObjectType == DataInfo::eBlobImpl) {
|
||||
MOZ_ASSERT(info->mBlobImpl);
|
||||
hostURI->mPrincipal = info->mPrincipal;
|
||||
hostURI->mBlobImpl = info->mBlobImpl;
|
||||
}
|
||||
|
||||
NS_TryToSetImmutable(hostURI);
|
||||
NS_TryToSetImmutable(uri);
|
||||
uri.forget(aResult);
|
||||
|
||||
if (info && info->mObjectType == DataInfo::eBlobImpl) {
|
||||
|
|
|
@ -230,7 +230,7 @@ nsHostObjectURI::EqualsInternal(nsIURI* aOther,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsHostObjectURI::Mutator, nsIURISetters, nsIURIMutator)
|
||||
NS_IMPL_ISUPPORTS(nsHostObjectURI::Mutator, nsIURISetters, nsIURIMutator, nsIBlobURIMutator, nsIPrincipalURIMutator)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHostObjectURI::Mutate(nsIURIMutator** aMutator)
|
||||
|
|
|
@ -81,11 +81,33 @@ public:
|
|||
class Mutator
|
||||
: public nsIURIMutator
|
||||
, public BaseURIMutator<nsHostObjectURI>
|
||||
, public nsIBlobURIMutator
|
||||
, public nsIPrincipalURIMutator
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
|
||||
NS_DEFINE_NSIMUTATOR_COMMON
|
||||
|
||||
MOZ_MUST_USE NS_IMETHOD
|
||||
SetBlobImpl(mozilla::dom::BlobImpl *aBlobImpl) override
|
||||
{
|
||||
if (!mURI) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
mURI->mBlobImpl = aBlobImpl;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_MUST_USE NS_IMETHOD
|
||||
SetPrincipal(nsIPrincipal *aPrincipal) override
|
||||
{
|
||||
if (!mURI) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
mURI->mPrincipal = aPrincipal;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
explicit Mutator() { }
|
||||
private:
|
||||
virtual ~Mutator() { }
|
||||
|
|
|
@ -369,6 +369,32 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows consumers to call the methods declared in other
|
||||
* interfaces implemented by the mutator object.
|
||||
*
|
||||
* Example:
|
||||
* nsCOMPtr<nsIURI> uri;
|
||||
* nsresult rv = NS_MutateURI(new URIClass::Mutator())
|
||||
* .SetSpec(aSpec)
|
||||
* .Apply<SomeInterface>(&SomeInterface::Method, arg1, arg2)
|
||||
* .Finalize(uri);
|
||||
*
|
||||
* If mMutator does not implement SomeInterface, do_QueryInterface will fail
|
||||
* and the method will not be called.
|
||||
* If aMethod does not exist, or if there is a mismatch between argument
|
||||
* types, or the number of arguments, then there will be a compile error.
|
||||
*/
|
||||
template <typename Interface, typename Method, typename... Args>
|
||||
NS_MutateURI& Apply(Method aMethod, Args ...aArgs)
|
||||
{
|
||||
NS_ENSURE_SUCCESS(mStatus, *this);
|
||||
nsCOMPtr<Interface> target = do_QueryInterface(mMutator, &mStatus);
|
||||
NS_ENSURE_SUCCESS(mStatus, *this);
|
||||
mStatus = (target->*aMethod)(aArgs...);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class C>
|
||||
MOZ_MUST_USE nsresult Finalize(nsCOMPtr<C>& aURI)
|
||||
{
|
||||
|
|
|
@ -6,6 +6,15 @@
|
|||
|
||||
interface nsIURI;
|
||||
|
||||
%{C++
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class BlobImpl;
|
||||
}}
|
||||
%}
|
||||
|
||||
[ptr] native BlobImplPtr(mozilla::dom::BlobImpl);
|
||||
|
||||
/**
|
||||
* nsIURIWithBlobImpl is implemented by URIs which are associated with a
|
||||
* specific BlobImpl.
|
||||
|
@ -18,3 +27,14 @@ interface nsIURIWithBlobImpl : nsISupports
|
|||
*/
|
||||
readonly attribute nsISupports blobImpl;
|
||||
};
|
||||
|
||||
[builtinclass, uuid(d3e8c9fa-ff07-47cc-90dc-0cc5445ddb59)]
|
||||
interface nsIBlobURIMutator : nsISupports
|
||||
{
|
||||
/**
|
||||
* Associates a blobImpl to the mutated URI.
|
||||
* Would normally return nsIURIMutator, but since it only gets called
|
||||
* from C++, there is no need for that.
|
||||
*/
|
||||
[must_use, noscript] void setBlobImpl(in BlobImplPtr blobImpl);
|
||||
};
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
interface nsIPrincipal;
|
||||
interface nsIURI;
|
||||
interface nsIURIMutator;
|
||||
|
||||
/**
|
||||
* nsIURIWithPrincipal is implemented by URIs which are associated with a
|
||||
|
@ -25,3 +26,14 @@ interface nsIURIWithPrincipal : nsISupports
|
|||
*/
|
||||
readonly attribute nsIURI principalUri;
|
||||
};
|
||||
|
||||
[builtinclass, uuid(fa138a89-c76e-4b7f-95ec-c7b56ded5ef5)]
|
||||
interface nsIPrincipalURIMutator : nsISupports
|
||||
{
|
||||
/**
|
||||
* Associates a principal to the mutated URI.
|
||||
* Would normally return nsIURIMutator, but since it only gets called
|
||||
* from C++, there is no need for that.
|
||||
*/
|
||||
[must_use, noscript] void setPrincipal(in nsIPrincipal aPrincipal);
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче