зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1310483 - Implement nsIURIWithQuery for having query part in simple URI, r=valentin
This commit is contained in:
Родитель
b809e13f8d
Коммит
9f4ca5a041
|
@ -17,6 +17,7 @@
|
|||
#include "nsEscape.h"
|
||||
#include "nsHostObjectProtocolHandler.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsIURIWithQuery.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
@ -521,37 +522,37 @@ URLMainThread::GetPathname(nsAString& aPathname, ErrorResult& aRv) const
|
|||
{
|
||||
aPathname.Truncate();
|
||||
|
||||
nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
|
||||
if (!url) {
|
||||
nsAutoCString path;
|
||||
nsresult rv = mURI->GetPath(path);
|
||||
if (NS_FAILED(rv)){
|
||||
// Do not throw! Not having a valid URI or URL should result in an empty
|
||||
// string.
|
||||
return;
|
||||
// Do not throw! Not having a valid URI or URL should result in an empty
|
||||
// string.
|
||||
|
||||
nsCOMPtr<nsIURIWithQuery> url(do_QueryInterface(mURI));
|
||||
if (url) {
|
||||
nsAutoCString file;
|
||||
nsresult rv = url->GetFilePath(file);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
CopyUTF8toUTF16(file, aPathname);
|
||||
}
|
||||
|
||||
CopyUTF8toUTF16(path, aPathname);
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString file;
|
||||
nsresult rv = url->GetFilePath(file);
|
||||
nsAutoCString path;
|
||||
nsresult rv = mURI->GetPath(path);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
CopyUTF8toUTF16(file, aPathname);
|
||||
CopyUTF8toUTF16(path, aPathname);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URLMainThread::SetPathname(const nsAString& aPathname, ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
|
||||
if (!url) {
|
||||
// Ignore failures to be compatible with NS4.
|
||||
// Do not throw!
|
||||
|
||||
nsCOMPtr<nsIURIWithQuery> url(do_QueryInterface(mURI));
|
||||
if (url) {
|
||||
url->SetFilePath(NS_ConvertUTF16toUTF8(aPathname));
|
||||
return;
|
||||
}
|
||||
|
||||
url->SetFilePath(NS_ConvertUTF16toUTF8(aPathname));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -559,17 +560,19 @@ URLMainThread::GetSearch(nsAString& aSearch, ErrorResult& aRv) const
|
|||
{
|
||||
aSearch.Truncate();
|
||||
|
||||
nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
|
||||
if (!url) {
|
||||
// Do not throw! Not having a valid URI or URL should result in an empty
|
||||
// string.
|
||||
return;
|
||||
}
|
||||
// Do not throw! Not having a valid URI or URL should result in an empty
|
||||
// string.
|
||||
|
||||
nsAutoCString search;
|
||||
nsresult rv = url->GetQuery(search);
|
||||
if (NS_SUCCEEDED(rv) && !search.IsEmpty()) {
|
||||
CopyUTF8toUTF16(NS_LITERAL_CSTRING("?") + search, aSearch);
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIURIWithQuery> url(do_QueryInterface(mURI));
|
||||
if (url) {
|
||||
rv = url->GetQuery(search);
|
||||
if (NS_SUCCEEDED(rv) && !search.IsEmpty()) {
|
||||
CopyUTF8toUTF16(NS_LITERAL_CSTRING("?") + search, aSearch);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -598,13 +601,13 @@ URLMainThread::SetHash(const nsAString& aHash, ErrorResult& aRv)
|
|||
void
|
||||
URLMainThread::SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
|
||||
if (!url) {
|
||||
// Ignore failures to be compatible with NS4.
|
||||
// Ignore failures to be compatible with NS4.
|
||||
|
||||
nsCOMPtr<nsIURIWithQuery> uriWithQuery(do_QueryInterface(mURI));
|
||||
if (uriWithQuery) {
|
||||
uriWithQuery->SetQuery(NS_ConvertUTF16toUTF8(aSearch));
|
||||
return;
|
||||
}
|
||||
|
||||
url->SetQuery(NS_ConvertUTF16toUTF8(aSearch));
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
|
|
@ -217,6 +217,16 @@
|
|||
pathname: 'blank',
|
||||
skip_setters: false,
|
||||
},
|
||||
|
||||
{ url: 'foo:bar?what#yeah',
|
||||
base: undefined,
|
||||
error: false,
|
||||
protocol: 'foo:',
|
||||
pathname: 'bar',
|
||||
search: '?what',
|
||||
hash: '#yeah',
|
||||
skip_setters: false,
|
||||
},
|
||||
];
|
||||
|
||||
while(tests.length) {
|
||||
|
@ -387,5 +397,40 @@
|
|||
url = new URL("scheme://tmp\\test", base);
|
||||
is(url.href, "scheme://tmp\\test");
|
||||
</script>
|
||||
|
||||
<script>
|
||||
var url = new URL("scheme:path/to/file?query#hash");
|
||||
is(url.href, "scheme:path/to/file?query#hash");
|
||||
is(url.pathname, "path/to/file");
|
||||
is(url.search, "?query");
|
||||
is(url.hash, "#hash");
|
||||
|
||||
// pathname cannot be overwritten.
|
||||
url.pathname = "new/path?newquery#newhash";
|
||||
is(url.href, "scheme:path/to/file?query#hash");
|
||||
|
||||
url.search = "?newquery#newhash";
|
||||
is(url.href, "scheme:path/to/file?newquery%23newhash#hash");
|
||||
|
||||
// nulls get encoded, whitespace gets stripped
|
||||
url = new URL("scheme:pa\0\nth/to/fi\0\nle?qu\0\nery#ha\0\nsh");
|
||||
is(url.href, "scheme:pa%00th/to/fi%00le?qu%00ery#ha%00sh");
|
||||
|
||||
url.search = "new\0\nquery";
|
||||
is(url.href, "scheme:pa%00th/to/fi%00le?new%00%0Aquery#ha%00sh");
|
||||
url.hash = "new\0\nhash";
|
||||
is(url.href, "scheme:pa%00th/to/fi%00le?new%00%0Aquery#new%00%0Ahash");
|
||||
|
||||
url = new URL("scheme:path#hash");
|
||||
is(url.href, "scheme:path#hash");
|
||||
url.search = "query";
|
||||
is(url.href, "scheme:path?query#hash");
|
||||
url.hash = "";
|
||||
is(url.href, "scheme:path?query");
|
||||
url.hash = "newhash";
|
||||
is(url.href, "scheme:path?query#newhash");
|
||||
url.search = "";
|
||||
is(url.href, "scheme:path#newhash");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -15,6 +15,7 @@ struct SimpleURIParams
|
|||
nsCString scheme;
|
||||
nsCString path;
|
||||
nsCString ref;
|
||||
nsCString query;
|
||||
bool isMutable;
|
||||
};
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ NS_IMPL_RELEASE(nsJARURI)
|
|||
NS_INTERFACE_MAP_BEGIN(nsJARURI)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIJARURI)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIURI)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIURIWithQuery)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIURL)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIJARURI)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISerializable)
|
||||
|
|
|
@ -41,6 +41,7 @@ class nsJARURI final : public nsIJARURI,
|
|||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIURI
|
||||
NS_DECL_NSIURIWITHQUERY
|
||||
NS_DECL_NSIURL
|
||||
NS_DECL_NSIJARURI
|
||||
NS_DECL_NSISERIALIZABLE
|
||||
|
|
|
@ -132,6 +132,7 @@ XPIDL_SOURCES += [
|
|||
'nsIURIClassifier.idl',
|
||||
'nsIURIWithBlobImpl.idl',
|
||||
'nsIURIWithPrincipal.idl',
|
||||
'nsIURIWithQuery.idl',
|
||||
'nsIURL.idl',
|
||||
'nsIURLParser.idl',
|
||||
'nsPILoadGroupInternal.idl',
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/* 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 "nsIURI.idl"
|
||||
|
||||
/**
|
||||
* nsIURIWithQuery is implemented by URIs which have a query parameter.
|
||||
* This is useful for the URL API.
|
||||
*/
|
||||
[scriptable, uuid(367510ee-8556-435a-8f99-b5fd357e08cc)]
|
||||
interface nsIURIWithQuery : nsIURI
|
||||
{
|
||||
/**
|
||||
* Returns a path including the directory and file portions of a
|
||||
* URL. For example, the filePath of "http://host/foo/bar.html#baz"
|
||||
* is "/foo/bar.html".
|
||||
*
|
||||
* Some characters may be escaped.
|
||||
*/
|
||||
attribute AUTF8String filePath;
|
||||
|
||||
/**
|
||||
* Returns the query portion (the part after the "?") of the URL.
|
||||
* If there isn't one, an empty string is returned.
|
||||
*
|
||||
* Some characters may be escaped.
|
||||
*/
|
||||
attribute AUTF8String query;
|
||||
};
|
|
@ -3,7 +3,7 @@
|
|||
* 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 "nsIURI.idl"
|
||||
#include "nsIURIWithQuery.idl"
|
||||
|
||||
/**
|
||||
* The nsIURL interface provides convenience methods that further
|
||||
|
@ -20,29 +20,16 @@
|
|||
* filePath
|
||||
*/
|
||||
[scriptable, uuid(86adcd89-0b70-47a2-b0fe-5bb2c5f37e31)]
|
||||
interface nsIURL : nsIURI
|
||||
interface nsIURL : nsIURIWithQuery
|
||||
{
|
||||
/*************************************************************************
|
||||
* The URL path is broken down into the following principal components:
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns a path including the directory and file portions of a
|
||||
* URL. For example, the filePath of "http://host/foo/bar.html#baz"
|
||||
* is "/foo/bar.html".
|
||||
*
|
||||
* Some characters may be escaped.
|
||||
*/
|
||||
attribute AUTF8String filePath;
|
||||
|
||||
/**
|
||||
* Returns the query portion (the part after the "?") of the URL.
|
||||
* If there isn't one, an empty string is returned.
|
||||
* attribute AUTF8String filePath;
|
||||
* attribute AUTF8String query;
|
||||
*
|
||||
* Some characters may be escaped.
|
||||
* These are inherited from nsIURIWithQuery.
|
||||
*/
|
||||
attribute AUTF8String query;
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* The URL filepath is broken down into the following sub-components:
|
||||
|
|
|
@ -35,8 +35,9 @@ static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
|
|||
// nsSimpleURI methods:
|
||||
|
||||
nsSimpleURI::nsSimpleURI()
|
||||
: mMutable(true),
|
||||
mIsRefValid(false)
|
||||
: mMutable(true)
|
||||
, mIsRefValid(false)
|
||||
, mIsQueryValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -47,8 +48,8 @@ nsSimpleURI::~nsSimpleURI()
|
|||
NS_IMPL_ADDREF(nsSimpleURI)
|
||||
NS_IMPL_RELEASE(nsSimpleURI)
|
||||
NS_INTERFACE_TABLE_HEAD(nsSimpleURI)
|
||||
NS_INTERFACE_TABLE(nsSimpleURI, nsIURI, nsISerializable, nsIClassInfo,
|
||||
nsIMutable, nsIIPCSerializableURI)
|
||||
NS_INTERFACE_TABLE(nsSimpleURI, nsIURI, nsIURIWithQuery, nsISerializable,
|
||||
nsIClassInfo, nsIMutable, nsIIPCSerializableURI)
|
||||
NS_INTERFACE_TABLE_TO_MAP_SEGUE
|
||||
if (aIID.Equals(kThisSimpleURIImplementationCID))
|
||||
foundInterface = static_cast<nsIURI*>(this);
|
||||
|
@ -87,6 +88,18 @@ nsSimpleURI::Read(nsIObjectInputStream* aStream)
|
|||
mRef.Truncate(); // invariant: mRef should be empty when it's not valid
|
||||
}
|
||||
|
||||
bool isQueryValid;
|
||||
rv = aStream->ReadBoolean(&isQueryValid);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
mIsQueryValid = isQueryValid;
|
||||
|
||||
if (isQueryValid) {
|
||||
rv = aStream->ReadCString(mQuery);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
} else {
|
||||
mQuery.Truncate(); // invariant: mQuery should be empty when it's not valid
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -112,6 +125,14 @@ nsSimpleURI::Write(nsIObjectOutputStream* aStream)
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
rv = aStream->WriteBoolean(mIsQueryValid);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (mIsQueryValid) {
|
||||
rv = aStream->WriteStringZ(mQuery.get());
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -125,12 +146,19 @@ nsSimpleURI::Serialize(URIParams& aParams)
|
|||
|
||||
params.scheme() = mScheme;
|
||||
params.path() = mPath;
|
||||
|
||||
if (mIsRefValid) {
|
||||
params.ref() = mRef;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
params.ref().SetIsVoid(true);
|
||||
}
|
||||
|
||||
if (mIsQueryValid) {
|
||||
params.query() = mQuery;
|
||||
} else {
|
||||
params.query().SetIsVoid(true);
|
||||
}
|
||||
|
||||
params.isMutable() = mMutable;
|
||||
|
||||
aParams = params;
|
||||
|
@ -148,14 +176,23 @@ nsSimpleURI::Deserialize(const URIParams& aParams)
|
|||
|
||||
mScheme = params.scheme();
|
||||
mPath = params.path();
|
||||
|
||||
if (params.ref().IsVoid()) {
|
||||
mRef.Truncate();
|
||||
mIsRefValid = false;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
mRef = params.ref();
|
||||
mIsRefValid = true;
|
||||
}
|
||||
|
||||
if (params.query().IsVoid()) {
|
||||
mQuery.Truncate();
|
||||
mIsQueryValid = false;
|
||||
} else {
|
||||
mQuery = params.query();
|
||||
mIsQueryValid = true;
|
||||
}
|
||||
|
||||
mMutable = params.isMutable();
|
||||
|
||||
return true;
|
||||
|
@ -173,6 +210,15 @@ nsSimpleURI::GetSpec(nsACString &result)
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (mIsQueryValid) {
|
||||
if (!result.Append(NS_LITERAL_CSTRING("?"), fallible) ||
|
||||
!result.Append(mQuery, fallible)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(mQuery.IsEmpty(), "mIsQueryValid/mQuery invariant broken");
|
||||
}
|
||||
|
||||
if (mIsRefValid) {
|
||||
if (!result.Append(NS_LITERAL_CSTRING("#"), fallible) ||
|
||||
!result.Append(mRef, fallible)) {
|
||||
|
@ -181,6 +227,7 @@ nsSimpleURI::GetSpec(nsACString &result)
|
|||
} else {
|
||||
MOZ_ASSERT(mRef.IsEmpty(), "mIsRefValid/mRef invariant broken");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -189,6 +236,9 @@ NS_IMETHODIMP
|
|||
nsSimpleURI::GetSpecIgnoringRef(nsACString &result)
|
||||
{
|
||||
result = mScheme + NS_LITERAL_CSTRING(":") + mPath;
|
||||
if (mIsQueryValid) {
|
||||
result += NS_LITERAL_CSTRING("?") + mQuery;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -203,7 +253,7 @@ NS_IMETHODIMP
|
|||
nsSimpleURI::SetSpec(const nsACString &aSpec)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
|
||||
// filter out unexpected chars "\r\n\t" if necessary
|
||||
nsAutoCString filteredSpec;
|
||||
net_FilterURIString(aSpec, filteredSpec);
|
||||
|
@ -224,7 +274,7 @@ nsSimpleURI::SetSpec(const nsACString &aSpec)
|
|||
NS_ASSERTION(n == colonPos, "Left failed");
|
||||
ToLowerCase(mScheme);
|
||||
|
||||
// This sets both mPath and mRef.
|
||||
// This sets mPath, mQuery and mRef.
|
||||
return SetPath(Substring(spec, colonPos + 1));
|
||||
}
|
||||
|
||||
|
@ -280,7 +330,7 @@ NS_IMETHODIMP
|
|||
nsSimpleURI::SetUsername(const nsACString &userName)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -294,7 +344,7 @@ NS_IMETHODIMP
|
|||
nsSimpleURI::SetPassword(const nsACString &password)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -311,7 +361,7 @@ NS_IMETHODIMP
|
|||
nsSimpleURI::SetHostPort(const nsACString &result)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -335,7 +385,7 @@ NS_IMETHODIMP
|
|||
nsSimpleURI::SetHost(const nsACString &host)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -351,7 +401,7 @@ NS_IMETHODIMP
|
|||
nsSimpleURI::SetPort(int32_t port)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -359,6 +409,9 @@ NS_IMETHODIMP
|
|||
nsSimpleURI::GetPath(nsACString &result)
|
||||
{
|
||||
result = mPath;
|
||||
if (mIsQueryValid) {
|
||||
result += NS_LITERAL_CSTRING("?") + mQuery;
|
||||
}
|
||||
if (mIsRefValid) {
|
||||
result += NS_LITERAL_CSTRING("#") + mRef;
|
||||
}
|
||||
|
@ -367,32 +420,64 @@ nsSimpleURI::GetPath(nsACString &result)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::SetPath(const nsACString &path)
|
||||
nsSimpleURI::SetPath(const nsACString &aPath)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
|
||||
nsAutoCString path(aPath);
|
||||
int32_t queryPos = path.FindChar('?');
|
||||
int32_t hashPos = path.FindChar('#');
|
||||
if (hashPos < 0) {
|
||||
mIsRefValid = false;
|
||||
mRef.Truncate(); // invariant: mRef should be empty when it's not valid
|
||||
if (!mPath.Assign(path, fallible)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_OK;
|
||||
|
||||
if (queryPos != kNotFound && hashPos != kNotFound && hashPos < queryPos) {
|
||||
queryPos = kNotFound;
|
||||
}
|
||||
|
||||
mPath = StringHead(path, hashPos);
|
||||
return SetRef(Substring(path, uint32_t(hashPos)));
|
||||
nsAutoCString query;
|
||||
if (queryPos != kNotFound) {
|
||||
query.Assign(Substring(path, queryPos));
|
||||
path.Truncate(queryPos);
|
||||
}
|
||||
|
||||
nsAutoCString hash;
|
||||
if (hashPos != kNotFound) {
|
||||
if (query.IsEmpty()) {
|
||||
hash.Assign(Substring(path, hashPos));
|
||||
path.Truncate(hashPos);
|
||||
} else {
|
||||
// We have to search the hash character in the query
|
||||
hashPos = query.FindChar('#');
|
||||
hash.Assign(Substring(query, hashPos));
|
||||
query.Truncate(hashPos);
|
||||
}
|
||||
}
|
||||
|
||||
mIsQueryValid = false;
|
||||
mQuery.Truncate();
|
||||
|
||||
mIsRefValid = false;
|
||||
mRef.Truncate();
|
||||
|
||||
// The path
|
||||
if (!mPath.Assign(path, fallible)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsresult rv = SetQuery(query);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return SetRef(hash);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::GetRef(nsACString &result)
|
||||
{
|
||||
if (!mIsRefValid) {
|
||||
MOZ_ASSERT(mRef.IsEmpty(), "mIsRefValid/mRef invariant broken");
|
||||
result.Truncate();
|
||||
MOZ_ASSERT(mRef.IsEmpty(), "mIsRefValid/mRef invariant broken");
|
||||
result.Truncate();
|
||||
} else {
|
||||
result = mRef;
|
||||
result = mRef;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -405,20 +490,26 @@ nsSimpleURI::SetRef(const nsACString &aRef)
|
|||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
if (aRef.IsEmpty()) {
|
||||
// Empty string means to remove ref completely.
|
||||
mIsRefValid = false;
|
||||
mRef.Truncate(); // invariant: mRef should be empty when it's not valid
|
||||
return NS_OK;
|
||||
nsAutoCString ref;
|
||||
nsresult rv = NS_EscapeURL(aRef, esc_OnlyNonASCII, ref, fallible);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (ref.IsEmpty()) {
|
||||
// Empty string means to remove ref completely.
|
||||
mIsRefValid = false;
|
||||
mRef.Truncate(); // invariant: mRef should be empty when it's not valid
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mIsRefValid = true;
|
||||
|
||||
// Gracefully skip initial hash
|
||||
if (aRef[0] == '#') {
|
||||
mRef = Substring(aRef, 1);
|
||||
if (ref[0] == '#') {
|
||||
mRef = Substring(ref, 1);
|
||||
} else {
|
||||
mRef = aRef;
|
||||
mRef = ref;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -462,6 +553,11 @@ nsSimpleURI::EqualsInternal(nsSimpleURI* otherUri, RefHandlingEnum refHandlingMo
|
|||
bool result = (mScheme == otherUri->mScheme &&
|
||||
mPath == otherUri->mPath);
|
||||
|
||||
if (result) {
|
||||
result = (mIsQueryValid == otherUri->mIsQueryValid &&
|
||||
(!mIsQueryValid || mQuery == otherUri->mQuery));
|
||||
}
|
||||
|
||||
if (result && refHandlingMode == eHonorRef) {
|
||||
result = (mIsRefValid == otherUri->mIsRefValid &&
|
||||
(!mIsRefValid || mRef == otherUri->mRef));
|
||||
|
@ -542,12 +638,17 @@ nsSimpleURI::CloneInternal(nsSimpleURI::RefHandlingEnum refHandlingMode,
|
|||
url->mScheme = mScheme;
|
||||
url->mPath = mPath;
|
||||
|
||||
url->mIsQueryValid = mIsQueryValid;
|
||||
if (url->mIsQueryValid) {
|
||||
url->mQuery = mQuery;
|
||||
}
|
||||
|
||||
url.forget(result);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::Resolve(const nsACString &relativePath, nsACString &result)
|
||||
nsSimpleURI::Resolve(const nsACString &relativePath, nsACString &result)
|
||||
{
|
||||
result = relativePath;
|
||||
return NS_OK;
|
||||
|
@ -588,7 +689,7 @@ nsSimpleURI::GetOriginCharset(nsACString &result)
|
|||
// nsSimpleURI::nsIClassInfo
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::GetInterfaces(uint32_t *count, nsIID * **array)
|
||||
{
|
||||
*count = 0;
|
||||
|
@ -596,14 +697,14 @@ nsSimpleURI::GetInterfaces(uint32_t *count, nsIID * **array)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::GetScriptableHelper(nsIXPCScriptable **_retval)
|
||||
{
|
||||
*_retval = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::GetContractID(char * *aContractID)
|
||||
{
|
||||
// Make sure to modify any subclasses as needed if this ever
|
||||
|
@ -612,14 +713,14 @@ nsSimpleURI::GetContractID(char * *aContractID)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::GetClassDescription(char * *aClassDescription)
|
||||
{
|
||||
*aClassDescription = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::GetClassID(nsCID * *aClassID)
|
||||
{
|
||||
// Make sure to modify any subclasses as needed if this ever
|
||||
|
@ -630,14 +731,14 @@ nsSimpleURI::GetClassID(nsCID * *aClassID)
|
|||
return GetClassIDNoAlloc(*aClassID);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::GetFlags(uint32_t *aFlags)
|
||||
{
|
||||
*aFlags = nsIClassInfo::MAIN_THREAD_ONLY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
|
||||
{
|
||||
*aClassIDNoAlloc = kSimpleURICID;
|
||||
|
@ -667,11 +768,12 @@ nsSimpleURI::SetMutable(bool value)
|
|||
// nsSimpleURI::nsISizeOf
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
size_t
|
||||
size_t
|
||||
nsSimpleURI::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return mScheme.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
|
||||
mPath.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
|
||||
mQuery.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
|
||||
mRef.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||
}
|
||||
|
||||
|
@ -680,5 +782,64 @@ nsSimpleURI::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
|
|||
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// nsSimpleURI::nsIURIWithQuery
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::GetFilePath(nsACString& aFilePath)
|
||||
{
|
||||
aFilePath = mPath;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::SetFilePath(const nsACString& aFilePath)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::GetQuery(nsACString& aQuery)
|
||||
{
|
||||
if (!mIsQueryValid) {
|
||||
MOZ_ASSERT(mQuery.IsEmpty(), "mIsQueryValid/mQuery invariant broken");
|
||||
aQuery.Truncate();
|
||||
} else {
|
||||
aQuery = mQuery;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::SetQuery(const nsACString& aQuery)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
nsAutoCString query;
|
||||
nsresult rv = NS_EscapeURL(aQuery, esc_Query, query, fallible);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (query.IsEmpty()) {
|
||||
// Empty string means to remove ref completely.
|
||||
mIsQueryValid = false;
|
||||
mQuery.Truncate(); // invariant: mQuery should be empty when it's not valid
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mIsQueryValid = true;
|
||||
|
||||
// Gracefully skip initial hash
|
||||
if (query[0] == '?') {
|
||||
mQuery = Substring(query, 1);
|
||||
} else {
|
||||
mQuery = query;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIURIWithQuery.h"
|
||||
#include "nsISerializable.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIClassInfo.h"
|
||||
|
@ -26,12 +27,13 @@ namespace net {
|
|||
{0xb9, 0xb9, 0x9f, 0xd9, 0x46, 0x2b, 0x5e, 0x19} \
|
||||
}
|
||||
|
||||
class nsSimpleURI : public nsIURI,
|
||||
public nsISerializable,
|
||||
public nsIClassInfo,
|
||||
public nsIMutable,
|
||||
public nsISizeOf,
|
||||
public nsIIPCSerializableURI
|
||||
class nsSimpleURI
|
||||
: public nsIURIWithQuery
|
||||
, public nsISerializable
|
||||
, public nsIClassInfo
|
||||
, public nsIMutable
|
||||
, public nsISizeOf
|
||||
, public nsIIPCSerializableURI
|
||||
{
|
||||
protected:
|
||||
virtual ~nsSimpleURI();
|
||||
|
@ -39,6 +41,7 @@ protected:
|
|||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIURI
|
||||
NS_DECL_NSIURIWITHQUERY
|
||||
NS_DECL_NSISERIALIZABLE
|
||||
NS_DECL_NSICLASSINFO
|
||||
NS_DECL_NSIMUTABLE
|
||||
|
@ -95,8 +98,10 @@ protected:
|
|||
nsCString mScheme;
|
||||
nsCString mPath; // NOTE: mPath does not include ref, as an optimization
|
||||
nsCString mRef; // so that URIs with different refs can share string data.
|
||||
nsCString mQuery; // so that URLs with different querys can share string data.
|
||||
bool mMutable;
|
||||
bool mIsRefValid; // To distinguish between empty-ref and no-ref.
|
||||
bool mIsQueryValid; // To distinguish between empty-query and no-query.
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -1191,6 +1191,7 @@ NS_IMPL_RELEASE(nsStandardURL)
|
|||
NS_INTERFACE_MAP_BEGIN(nsStandardURL)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStandardURL)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIURI)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIURIWithQuery)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIURL)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIFileURL, mSupportsFileURL)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStandardURL)
|
||||
|
|
|
@ -54,6 +54,7 @@ protected:
|
|||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIURI
|
||||
NS_DECL_NSIURIWITHQUERY
|
||||
NS_DECL_NSIURL
|
||||
NS_DECL_NSIFILEURL
|
||||
NS_DECL_NSISTANDARDURL
|
||||
|
|
|
@ -102,11 +102,6 @@ navigate.IdempotentURL = function(o) {
|
|||
hash = "#";
|
||||
}
|
||||
|
||||
let pathname = url.pathname;
|
||||
if (url.protocol == "data:" && hash != "") {
|
||||
pathname = pathname.substring(0, pathname.length - hash.length);
|
||||
}
|
||||
|
||||
return {
|
||||
hash: hash,
|
||||
host: url.host,
|
||||
|
@ -114,7 +109,7 @@ navigate.IdempotentURL = function(o) {
|
|||
href: url.href,
|
||||
origin: url.origin,
|
||||
password: url.password,
|
||||
pathname: pathname,
|
||||
pathname: url.pathname,
|
||||
port: url.port,
|
||||
protocol: url.protocol,
|
||||
search: url.search,
|
||||
|
|
|
@ -42,9 +42,6 @@
|
|||
[Parsing: <#β> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <data:text/html,test#test> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <file:c:\\foo\\bar.html> against <file:///tmp/mock/path>]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -153,21 +150,6 @@
|
|||
[Parsing: <http://%3g%78%63%30%2e%30%32%35%30%2E.01> against <http://other.com/>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <#> against <test:test>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <#x> against <mailto:x@x.com>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <#x> against <data:,>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <#x> against <about:blank>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <#> against <test:test?test>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <i> against <sc:/pa/pa>]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -204,15 +186,6 @@
|
|||
[Parsing: <?i> against <sc:///pa/pa>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <#i> against <sc:sd>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <#i> against <sc:sd/sd>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <#i> against <sc:/pa/pa>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <#i> against <sc://ho/pa>]
|
||||
expected: FAIL
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче