Bug 1420954 - Make nsIURIMutator setters return nsIURIMutator so we can chain setters r=bagder
MozReview-Commit-ID: 53BD91hB2yi
--- a/caps/NullPrincipalURI.h
+++ b/caps/NullPrincipalURI.h
@@ -53,17 +53,17 @@ private:
nsAutoCStringN<NSID_LENGTH> mPath;
public:
class Mutator
: public nsIURIMutator
, public BaseURIMutator<NullPrincipalURI>
{
NS_DECL_ISUPPORTS
- NS_FORWARD_SAFE_NSIURISETTERS(mURI)
+ NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
NS_IMETHOD Deserialize(const mozilla::ipc::URIParams& aParams) override
{
return InitFromIPCParams(aParams);
}
NS_IMETHOD Read(nsIObjectInputStream* aStream) override
{
@@ -71,18 +71,19 @@ public:
}
NS_IMETHOD Finalize(nsIURI** aURI) override
{
mURI.forget(aURI);
return NS_OK;
}
- NS_IMETHOD SetSpec(const nsACString & aSpec) override
+ NS_IMETHOD SetSpec(const nsACString & aSpec, nsIURIMutator** aMutator) override
{
+ NS_ADDREF(*aMutator = this);
return NS_ERROR_NOT_IMPLEMENTED;
}
explicit Mutator() { }
private:
virtual ~Mutator() { }
friend class NullPrincipalURI;
--- a/dom/file/nsHostObjectURI.h
+++ b/dom/file/nsHostObjectURI.h
@@ -78,17 +78,17 @@ protected:
virtual ~nsHostObjectURI() {}
public:
class Mutator
: public nsIURIMutator
, public BaseURIMutator<nsHostObjectURI>
{
NS_DECL_ISUPPORTS
- NS_FORWARD_SAFE_NSIURISETTERS(mURI)
+ NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
NS_DEFINE_NSIMUTATOR_COMMON
explicit Mutator() { }
private:
virtual ~Mutator() { }
friend class nsHostObjectURI;
};
--- a/dom/jsurl/nsJSProtocolHandler.h
+++ b/dom/jsurl/nsJSProtocolHandler.h
@@ -105,17 +105,17 @@ private:
nsCOMPtr<nsIURI> mBaseURI;
public:
class Mutator
: public nsIURIMutator
, public BaseURIMutator<nsJSURI>
{
NS_DECL_ISUPPORTS
- NS_FORWARD_SAFE_NSIURISETTERS(mURI)
+ NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
NS_DEFINE_NSIMUTATOR_COMMON
explicit Mutator() { }
private:
virtual ~Mutator() { }
friend class nsJSURI;
};
--- a/image/decoders/icon/nsIconURI.h
+++ b/image/decoders/icon/nsIconURI.h
@@ -46,17 +46,17 @@ protected:
// kStateStrings
public:
class Mutator
: public nsIURIMutator
, public BaseURIMutator<nsMozIconURI>
{
NS_DECL_ISUPPORTS
- NS_FORWARD_SAFE_NSIURISETTERS(mURI)
+ NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
NS_IMETHOD Deserialize(const mozilla::ipc::URIParams& aParams) override
{
return InitFromIPCParams(aParams);
}
NS_IMETHOD Read(nsIObjectInputStream* aStream) override
{
@@ -64,17 +64,18 @@ public:
}
NS_IMETHOD Finalize(nsIURI** aURI) override
{
mURI.forget(aURI);
return NS_OK;
}
- NS_IMETHOD SetSpec(const nsACString & aSpec) override {
+ NS_IMETHOD SetSpec(const nsACString & aSpec, nsIURIMutator** aMutator) override {
+ NS_ADDREF(*aMutator = this);
return InitFromSpec(aSpec);
}
explicit Mutator() { }
private:
virtual ~Mutator() { }
friend class nsMozIconURI;
--- a/modules/libjar/nsJARURI.h
+++ b/modules/libjar/nsJARURI.h
@@ -99,17 +99,17 @@ protected:
nsCString mCharsetHint;
public:
class Mutator
: public nsIURIMutator
, public BaseURIMutator<nsJARURI>
{
NS_DECL_ISUPPORTS
- NS_FORWARD_SAFE_NSIURISETTERS(mURI)
+ NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
NS_DEFINE_NSIMUTATOR_COMMON
explicit Mutator() { }
private:
virtual ~Mutator() { }
friend class nsJARURI;
};
--- a/netwerk/base/nsIURIMutator.idl
+++ b/netwerk/base/nsIURIMutator.idl
@@ -1,16 +1,17 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsIURI;
interface nsIObjectInputStream;
+interface nsIURIMutator;
%{C++
#include "nsStringGlue.h"
#undef SetPort // XXX Windows!
namespace mozilla {
class Encoding;
@@ -82,54 +83,96 @@ protected:
// to avoid code duplication.
#define NS_DEFINE_NSIMUTATOR_COMMON \
NS_IMETHOD Deserialize(const mozilla::ipc::URIParams& aParams) override \
{ return InitFromIPCParams(aParams); } \
NS_IMETHOD Read(nsIObjectInputStream* aStream) override \
{ return InitFromInputStream(aStream); } \
NS_IMETHOD Finalize(nsIURI** aURI) override \
{ mURI.forget(aURI); return NS_OK; } \
- NS_IMETHOD SetSpec(const nsACString & aSpec) override \
- { return InitFromSpec(aSpec); }
-
+ NS_IMETHOD SetSpec(const nsACString & aSpec, nsIURIMutator** aMutator) override \
+ { NS_ADDREF(*aMutator = this); return InitFromSpec(aSpec); }
%}
[ptr] native Encoding(const mozilla::Encoding);
[ref] native const_URIParams_ref(const mozilla::ipc::URIParams);
[scriptable, builtinclass, uuid(1fc53257-898b-4c5e-b69c-05bc84b4cd8f)]
interface nsIURISetSpec : nsISupports
{
/**
* This setter is different from all other setters because it may be used to
* initialize the object. We define it separately allowing mutator implementors
* to define it separately, while the rest of the setters may be simply
* forwarded to the mutable URI.
*/
- void setSpec(in AUTF8String aSpec);
+ nsIURIMutator setSpec(in AUTF8String aSpec);
};
+/**
+ * These methods allow the mutator to change various parts of the URI.
+ * They return the same nsIURIMutator so that we may chain setter operations:
+ * Example:
+ * let newURI = uri.mutate()
+ * .setSpec("http://example.com")
+ * .setQuery("hello")
+ * .finalize();
+ */
[scriptable, builtinclass, uuid(5403a6ec-99d7-405e-8b45-9f805bbdfcef)]
interface nsIURISetters : nsIURISetSpec
{
- void setScheme(in AUTF8String aScheme);
- void setUserPass(in AUTF8String aUserPass);
- void setUsername(in AUTF8String aUsername);
- void setPassword(in AUTF8String aPassword);
- void setHostPort(in AUTF8String aHostPort);
- void setHostAndPort(in AUTF8String aHostAndPort);
- void setHost(in AUTF8String aHost);
- void setPort(in long aPort);
- void setPathQueryRef(in AUTF8String aPathQueryRef);
- void setRef(in AUTF8String aRef);
- void setFilePath(in AUTF8String aFilePath);
- void setQuery(in AUTF8String aQuery);
- [noscript] void setQueryWithEncoding(in AUTF8String query, in Encoding encoding);
+ nsIURIMutator setScheme(in AUTF8String aScheme);
+ nsIURIMutator setUserPass(in AUTF8String aUserPass);
+ nsIURIMutator setUsername(in AUTF8String aUsername);
+ nsIURIMutator setPassword(in AUTF8String aPassword);
+ nsIURIMutator setHostPort(in AUTF8String aHostPort);
+ nsIURIMutator setHostAndPort(in AUTF8String aHostAndPort);
+ nsIURIMutator setHost(in AUTF8String aHost);
+ nsIURIMutator setPort(in long aPort);
+ nsIURIMutator setPathQueryRef(in AUTF8String aPathQueryRef);
+ nsIURIMutator setRef(in AUTF8String aRef);
+ nsIURIMutator setFilePath(in AUTF8String aFilePath);
+ nsIURIMutator setQuery(in AUTF8String aQuery);
+ [noscript] nsIURIMutator setQueryWithEncoding(in AUTF8String query, in Encoding encoding);
};
+%{C++
+
+// Using this macro instead of NS_FORWARD_SAFE_NSIURISETTERS makes chaining
+// setter operations possible.
+#define NS_FORWARD_SAFE_NSIURISETTERS_RET(_to) \
+ NS_IMETHOD SetScheme(const nsACString & aScheme, nsIURIMutator** aMutator) override \
+ { NS_ADDREF(*aMutator = this); return !_to ? NS_ERROR_NULL_POINTER : _to->SetScheme(aScheme); } \
+ NS_IMETHOD SetUserPass(const nsACString & aUserPass, nsIURIMutator** aMutator) override \
+ { NS_ADDREF(*aMutator = this); return !_to ? NS_ERROR_NULL_POINTER : _to->SetUserPass(aUserPass); } \
+ NS_IMETHOD SetUsername(const nsACString & aUsername, nsIURIMutator** aMutator) override \
+ { NS_ADDREF(*aMutator = this); return !_to ? NS_ERROR_NULL_POINTER : _to->SetUsername(aUsername); } \
+ NS_IMETHOD SetPassword(const nsACString & aPassword, nsIURIMutator** aMutator) override \
+ { NS_ADDREF(*aMutator = this); return !_to ? NS_ERROR_NULL_POINTER : _to->SetPassword(aPassword); } \
+ NS_IMETHOD SetHostPort(const nsACString & aHostPort, nsIURIMutator** aMutator) override \
+ { NS_ADDREF(*aMutator = this); return !_to ? NS_ERROR_NULL_POINTER : _to->SetHostPort(aHostPort); } \
+ NS_IMETHOD SetHostAndPort(const nsACString & aHostAndPort, nsIURIMutator** aMutator) override \
+ { NS_ADDREF(*aMutator = this); return !_to ? NS_ERROR_NULL_POINTER : _to->SetHostAndPort(aHostAndPort); } \
+ NS_IMETHOD SetHost(const nsACString & aHost, nsIURIMutator** aMutator) override \
+ { NS_ADDREF(*aMutator = this); return !_to ? NS_ERROR_NULL_POINTER : _to->SetHost(aHost); } \
+ NS_IMETHOD SetPort(int32_t aPort, nsIURIMutator** aMutator) override \
+ { NS_ADDREF(*aMutator = this); return !_to ? NS_ERROR_NULL_POINTER : _to->SetPort(aPort); } \
+ NS_IMETHOD SetPathQueryRef(const nsACString & aPathQueryRef, nsIURIMutator** aMutator) override \
+ { NS_ADDREF(*aMutator = this); return !_to ? NS_ERROR_NULL_POINTER : _to->SetPathQueryRef(aPathQueryRef); } \
+ NS_IMETHOD SetRef(const nsACString & aRef, nsIURIMutator** aMutator) override \
+ { NS_ADDREF(*aMutator = this); return !_to ? NS_ERROR_NULL_POINTER : _to->SetRef(aRef); } \
+ NS_IMETHOD SetFilePath(const nsACString & aFilePath, nsIURIMutator** aMutator) override \
+ { NS_ADDREF(*aMutator = this); return !_to ? NS_ERROR_NULL_POINTER : _to->SetFilePath(aFilePath); } \
+ NS_IMETHOD SetQuery(const nsACString & aQuery, nsIURIMutator** aMutator) override \
+ { NS_ADDREF(*aMutator = this); return !_to ? NS_ERROR_NULL_POINTER : _to->SetQuery(aQuery); } \
+ NS_IMETHOD SetQueryWithEncoding(const nsACString & query, const mozilla::Encoding *encoding, nsIURIMutator** aMutator) override \
+ { NS_ADDREF(*aMutator = this); return !_to ? NS_ERROR_NULL_POINTER : _to->SetQueryWithEncoding(query, encoding); }
+
+%}
+
[scriptable, builtinclass, uuid(4d1f3103-1c44-4dcd-b717-5d22a697a7d9)]
interface nsIURIMutator : nsIURISetters
{
/**
* Initializes the URI by reading from the input stream.
* The input stream must contain the serialization of the same object type.
* See nsISerializable.
*/
--- a/netwerk/base/nsSimpleNestedURI.h
+++ b/netwerk/base/nsSimpleNestedURI.h
@@ -72,18 +72,18 @@ protected:
public:
class Mutator
: public nsIURIMutator
, public BaseURIMutator<nsSimpleNestedURI>
{
NS_DECL_ISUPPORTS
- NS_FORWARD_SAFE_NSIURISETTERS(mURI)
NS_DEFINE_NSIMUTATOR_COMMON
+ NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
explicit Mutator() { }
private:
virtual ~Mutator() { }
friend class nsSimpleNestedURI;
};
};
--- a/netwerk/base/nsSimpleURI.h
+++ b/netwerk/base/nsSimpleURI.h
@@ -113,17 +113,17 @@ protected:
public:
class Mutator
: public nsIURIMutator
, public BaseURIMutator<nsSimpleURI>
{
NS_DECL_ISUPPORTS
- NS_FORWARD_SAFE_NSIURISETTERS(mURI)
+ NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
NS_DEFINE_NSIMUTATOR_COMMON
explicit Mutator() { }
private:
virtual ~Mutator() { }
friend class nsSimpleURI;
};
--- a/netwerk/base/nsStandardURL.h
+++ b/netwerk/base/nsStandardURL.h
@@ -313,17 +313,17 @@ public:
#endif
public:
class Mutator
: public nsIURIMutator
, public BaseURIMutator<nsStandardURL>
{
NS_DECL_ISUPPORTS
- NS_FORWARD_SAFE_NSIURISETTERS(mURI)
+ NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
NS_DEFINE_NSIMUTATOR_COMMON
explicit Mutator() { }
private:
virtual ~Mutator() { }
friend class nsStandardURL;
};
--- a/netwerk/protocol/about/nsAboutProtocolHandler.h
+++ b/netwerk/protocol/about/nsAboutProtocolHandler.h
@@ -87,17 +87,17 @@ protected:
nsCOMPtr<nsIURI> mBaseURI;
public:
class Mutator
: public nsIURIMutator
, public BaseURIMutator<nsNestedAboutURI>
{
NS_DECL_ISUPPORTS
- NS_FORWARD_SAFE_NSIURISETTERS(mURI)
+ NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
NS_DEFINE_NSIMUTATOR_COMMON
explicit Mutator() { }
private:
virtual ~Mutator() { }
friend class nsNestedAboutURI;
};
new file mode 100644
--- /dev/null
+++ b/netwerk/test/unit/test_uri_mutator.js
@@ -0,0 +1,23 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+Cu.import("resource://gre/modules/NetUtil.jsm");
+
+function standardMutator()
+{
+ return Cc['@mozilla.org/network/standard-url-mutator;1']
+ .createInstance(Ci.nsIURIMutator);
+}
+
+add_task(async function test_simple_setter_chaining() {
+ let uri = standardMutator()
+ .setSpec("http://example.com/")
+ .setQuery("hello")
+ .setRef("bla")
+ .setScheme("ftp")
+ .finalize();
+ equal(uri.spec, "ftp://example.com/?hello#bla");
+});
--- a/netwerk/test/unit/xpcshell.ini
+++ b/netwerk/test/unit/xpcshell.ini
@@ -400,8 +400,9 @@ skip-if = os == "android"
[test_channel_priority.js]
[test_bug1312774_http1.js]
[test_1351443-missing-NewChannel2.js]
[test_bug1312782_http1.js]
[test_bug1355539_http1.js]
[test_bug1378385_http1.js]
[test_tls_flags_separate_connections.js]
[test_tls_flags.js]
+[test_uri_mutator.js]