Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #include "URL.h" |
michael@0 | 7 | |
michael@0 | 8 | #include "nsGlobalWindow.h" |
michael@0 | 9 | #include "nsIDOMFile.h" |
michael@0 | 10 | #include "DOMMediaStream.h" |
michael@0 | 11 | #include "mozilla/dom/MediaSource.h" |
michael@0 | 12 | #include "mozilla/dom/URLBinding.h" |
michael@0 | 13 | #include "nsHostObjectProtocolHandler.h" |
michael@0 | 14 | #include "nsServiceManagerUtils.h" |
michael@0 | 15 | #include "nsIIOService.h" |
michael@0 | 16 | #include "nsEscape.h" |
michael@0 | 17 | #include "nsNetCID.h" |
michael@0 | 18 | #include "nsIURL.h" |
michael@0 | 19 | |
michael@0 | 20 | namespace mozilla { |
michael@0 | 21 | namespace dom { |
michael@0 | 22 | |
michael@0 | 23 | NS_IMPL_CYCLE_COLLECTION_CLASS(URL) |
michael@0 | 24 | |
michael@0 | 25 | NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(URL) |
michael@0 | 26 | if (tmp->mSearchParams) { |
michael@0 | 27 | tmp->mSearchParams->RemoveObserver(tmp); |
michael@0 | 28 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mSearchParams) |
michael@0 | 29 | } |
michael@0 | 30 | NS_IMPL_CYCLE_COLLECTION_UNLINK_END |
michael@0 | 31 | |
michael@0 | 32 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(URL) |
michael@0 | 33 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSearchParams) |
michael@0 | 34 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END |
michael@0 | 35 | |
michael@0 | 36 | NS_IMPL_CYCLE_COLLECTING_ADDREF(URL) |
michael@0 | 37 | NS_IMPL_CYCLE_COLLECTING_RELEASE(URL) |
michael@0 | 38 | |
michael@0 | 39 | NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URL) |
michael@0 | 40 | NS_INTERFACE_MAP_ENTRY(nsISupports) |
michael@0 | 41 | NS_INTERFACE_MAP_END |
michael@0 | 42 | |
michael@0 | 43 | URL::URL(nsIURI* aURI) |
michael@0 | 44 | : mURI(aURI) |
michael@0 | 45 | { |
michael@0 | 46 | } |
michael@0 | 47 | |
michael@0 | 48 | JSObject* |
michael@0 | 49 | URL::WrapObject(JSContext* aCx) |
michael@0 | 50 | { |
michael@0 | 51 | return URLBinding::Wrap(aCx, this); |
michael@0 | 52 | } |
michael@0 | 53 | |
michael@0 | 54 | /* static */ already_AddRefed<URL> |
michael@0 | 55 | URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl, |
michael@0 | 56 | URL& aBase, ErrorResult& aRv) |
michael@0 | 57 | { |
michael@0 | 58 | nsresult rv; |
michael@0 | 59 | nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv)); |
michael@0 | 60 | if (NS_FAILED(rv)) { |
michael@0 | 61 | aRv.Throw(rv); |
michael@0 | 62 | return nullptr; |
michael@0 | 63 | } |
michael@0 | 64 | |
michael@0 | 65 | nsCOMPtr<nsIURI> uri; |
michael@0 | 66 | rv = ioService->NewURI(NS_ConvertUTF16toUTF8(aUrl), nullptr, aBase.GetURI(), |
michael@0 | 67 | getter_AddRefs(uri)); |
michael@0 | 68 | if (NS_FAILED(rv)) { |
michael@0 | 69 | nsAutoString label(aUrl); |
michael@0 | 70 | aRv.ThrowTypeError(MSG_INVALID_URL, &label); |
michael@0 | 71 | return nullptr; |
michael@0 | 72 | } |
michael@0 | 73 | |
michael@0 | 74 | nsRefPtr<URL> url = new URL(uri); |
michael@0 | 75 | return url.forget(); |
michael@0 | 76 | } |
michael@0 | 77 | |
michael@0 | 78 | /* static */ already_AddRefed<URL> |
michael@0 | 79 | URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl, |
michael@0 | 80 | const nsAString& aBase, ErrorResult& aRv) |
michael@0 | 81 | { |
michael@0 | 82 | nsresult rv; |
michael@0 | 83 | nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv)); |
michael@0 | 84 | if (NS_FAILED(rv)) { |
michael@0 | 85 | aRv.Throw(rv); |
michael@0 | 86 | return nullptr; |
michael@0 | 87 | } |
michael@0 | 88 | |
michael@0 | 89 | nsCOMPtr<nsIURI> baseUri; |
michael@0 | 90 | rv = ioService->NewURI(NS_ConvertUTF16toUTF8(aBase), nullptr, nullptr, |
michael@0 | 91 | getter_AddRefs(baseUri)); |
michael@0 | 92 | if (NS_FAILED(rv)) { |
michael@0 | 93 | nsAutoString label(aBase); |
michael@0 | 94 | aRv.ThrowTypeError(MSG_INVALID_URL, &label); |
michael@0 | 95 | return nullptr; |
michael@0 | 96 | } |
michael@0 | 97 | |
michael@0 | 98 | nsCOMPtr<nsIURI> uri; |
michael@0 | 99 | rv = ioService->NewURI(NS_ConvertUTF16toUTF8(aUrl), nullptr, baseUri, |
michael@0 | 100 | getter_AddRefs(uri)); |
michael@0 | 101 | if (NS_FAILED(rv)) { |
michael@0 | 102 | nsAutoString label(aUrl); |
michael@0 | 103 | aRv.ThrowTypeError(MSG_INVALID_URL, &label); |
michael@0 | 104 | return nullptr; |
michael@0 | 105 | } |
michael@0 | 106 | |
michael@0 | 107 | nsRefPtr<URL> url = new URL(uri); |
michael@0 | 108 | return url.forget(); |
michael@0 | 109 | } |
michael@0 | 110 | |
michael@0 | 111 | void |
michael@0 | 112 | URL::CreateObjectURL(const GlobalObject& aGlobal, |
michael@0 | 113 | nsIDOMBlob* aBlob, |
michael@0 | 114 | const objectURLOptions& aOptions, |
michael@0 | 115 | nsString& aResult, |
michael@0 | 116 | ErrorResult& aError) |
michael@0 | 117 | { |
michael@0 | 118 | CreateObjectURLInternal(aGlobal, aBlob, |
michael@0 | 119 | NS_LITERAL_CSTRING(BLOBURI_SCHEME), aOptions, aResult, |
michael@0 | 120 | aError); |
michael@0 | 121 | } |
michael@0 | 122 | |
michael@0 | 123 | void |
michael@0 | 124 | URL::CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream, |
michael@0 | 125 | const mozilla::dom::objectURLOptions& aOptions, |
michael@0 | 126 | nsString& aResult, |
michael@0 | 127 | ErrorResult& aError) |
michael@0 | 128 | { |
michael@0 | 129 | CreateObjectURLInternal(aGlobal, &aStream, |
michael@0 | 130 | NS_LITERAL_CSTRING(MEDIASTREAMURI_SCHEME), aOptions, |
michael@0 | 131 | aResult, aError); |
michael@0 | 132 | } |
michael@0 | 133 | |
michael@0 | 134 | void |
michael@0 | 135 | URL::CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource, |
michael@0 | 136 | const objectURLOptions& aOptions, |
michael@0 | 137 | nsString& aResult, |
michael@0 | 138 | ErrorResult& aError) |
michael@0 | 139 | { |
michael@0 | 140 | CreateObjectURLInternal(aGlobal, &aSource, |
michael@0 | 141 | NS_LITERAL_CSTRING(MEDIASOURCEURI_SCHEME), aOptions, |
michael@0 | 142 | aResult, aError); |
michael@0 | 143 | } |
michael@0 | 144 | |
michael@0 | 145 | void |
michael@0 | 146 | URL::CreateObjectURLInternal(const GlobalObject& aGlobal, nsISupports* aObject, |
michael@0 | 147 | const nsACString& aScheme, |
michael@0 | 148 | const objectURLOptions& aOptions, |
michael@0 | 149 | nsString& aResult, ErrorResult& aError) |
michael@0 | 150 | { |
michael@0 | 151 | nsCOMPtr<nsIPrincipal> principal = nsContentUtils::GetObjectPrincipal(aGlobal.Get()); |
michael@0 | 152 | |
michael@0 | 153 | nsCString url; |
michael@0 | 154 | nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(aScheme, aObject, |
michael@0 | 155 | principal, url); |
michael@0 | 156 | if (NS_FAILED(rv)) { |
michael@0 | 157 | aError.Throw(rv); |
michael@0 | 158 | return; |
michael@0 | 159 | } |
michael@0 | 160 | |
michael@0 | 161 | nsCOMPtr<nsPIDOMWindow> w = do_QueryInterface(aGlobal.GetAsSupports()); |
michael@0 | 162 | nsGlobalWindow* window = static_cast<nsGlobalWindow*>(w.get()); |
michael@0 | 163 | |
michael@0 | 164 | if (window) { |
michael@0 | 165 | NS_PRECONDITION(window->IsInnerWindow(), "Should be inner window"); |
michael@0 | 166 | |
michael@0 | 167 | if (!window->GetExtantDoc()) { |
michael@0 | 168 | aError.Throw(NS_ERROR_INVALID_POINTER); |
michael@0 | 169 | return; |
michael@0 | 170 | } |
michael@0 | 171 | |
michael@0 | 172 | nsIDocument* doc = window->GetExtantDoc(); |
michael@0 | 173 | if (doc) { |
michael@0 | 174 | doc->RegisterHostObjectUri(url); |
michael@0 | 175 | } |
michael@0 | 176 | } |
michael@0 | 177 | |
michael@0 | 178 | CopyASCIItoUTF16(url, aResult); |
michael@0 | 179 | } |
michael@0 | 180 | |
michael@0 | 181 | void |
michael@0 | 182 | URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL) |
michael@0 | 183 | { |
michael@0 | 184 | nsIPrincipal* principal = nsContentUtils::GetObjectPrincipal(aGlobal.Get()); |
michael@0 | 185 | |
michael@0 | 186 | NS_LossyConvertUTF16toASCII asciiurl(aURL); |
michael@0 | 187 | |
michael@0 | 188 | nsIPrincipal* urlPrincipal = |
michael@0 | 189 | nsHostObjectProtocolHandler::GetDataEntryPrincipal(asciiurl); |
michael@0 | 190 | |
michael@0 | 191 | if (urlPrincipal && principal->Subsumes(urlPrincipal)) { |
michael@0 | 192 | nsCOMPtr<nsPIDOMWindow> w = do_QueryInterface(aGlobal.GetAsSupports()); |
michael@0 | 193 | nsGlobalWindow* window = static_cast<nsGlobalWindow*>(w.get()); |
michael@0 | 194 | |
michael@0 | 195 | if (window && window->GetExtantDoc()) { |
michael@0 | 196 | window->GetExtantDoc()->UnregisterHostObjectUri(asciiurl); |
michael@0 | 197 | } |
michael@0 | 198 | nsHostObjectProtocolHandler::RemoveDataEntry(asciiurl); |
michael@0 | 199 | } |
michael@0 | 200 | } |
michael@0 | 201 | |
michael@0 | 202 | void |
michael@0 | 203 | URL::GetHref(nsString& aHref) const |
michael@0 | 204 | { |
michael@0 | 205 | aHref.Truncate(); |
michael@0 | 206 | |
michael@0 | 207 | nsAutoCString href; |
michael@0 | 208 | nsresult rv = mURI->GetSpec(href); |
michael@0 | 209 | if (NS_SUCCEEDED(rv)) { |
michael@0 | 210 | CopyUTF8toUTF16(href, aHref); |
michael@0 | 211 | } |
michael@0 | 212 | } |
michael@0 | 213 | |
michael@0 | 214 | void |
michael@0 | 215 | URL::SetHref(const nsAString& aHref, ErrorResult& aRv) |
michael@0 | 216 | { |
michael@0 | 217 | nsCString href = NS_ConvertUTF16toUTF8(aHref); |
michael@0 | 218 | |
michael@0 | 219 | nsresult rv; |
michael@0 | 220 | nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv)); |
michael@0 | 221 | if (NS_FAILED(rv)) { |
michael@0 | 222 | aRv.Throw(rv); |
michael@0 | 223 | return; |
michael@0 | 224 | } |
michael@0 | 225 | |
michael@0 | 226 | nsCOMPtr<nsIURI> uri; |
michael@0 | 227 | rv = ioService->NewURI(href, nullptr, nullptr, getter_AddRefs(uri)); |
michael@0 | 228 | if (NS_FAILED(rv)) { |
michael@0 | 229 | nsAutoString label(aHref); |
michael@0 | 230 | aRv.ThrowTypeError(MSG_INVALID_URL, &label); |
michael@0 | 231 | return; |
michael@0 | 232 | } |
michael@0 | 233 | |
michael@0 | 234 | mURI = uri; |
michael@0 | 235 | UpdateURLSearchParams(); |
michael@0 | 236 | } |
michael@0 | 237 | |
michael@0 | 238 | void |
michael@0 | 239 | URL::GetOrigin(nsString& aOrigin) const |
michael@0 | 240 | { |
michael@0 | 241 | nsContentUtils::GetUTFNonNullOrigin(mURI, aOrigin); |
michael@0 | 242 | } |
michael@0 | 243 | |
michael@0 | 244 | void |
michael@0 | 245 | URL::GetProtocol(nsString& aProtocol) const |
michael@0 | 246 | { |
michael@0 | 247 | nsCString protocol; |
michael@0 | 248 | if (NS_SUCCEEDED(mURI->GetScheme(protocol))) { |
michael@0 | 249 | aProtocol.Truncate(); |
michael@0 | 250 | } |
michael@0 | 251 | |
michael@0 | 252 | CopyASCIItoUTF16(protocol, aProtocol); |
michael@0 | 253 | aProtocol.Append(char16_t(':')); |
michael@0 | 254 | } |
michael@0 | 255 | |
michael@0 | 256 | void |
michael@0 | 257 | URL::SetProtocol(const nsAString& aProtocol) |
michael@0 | 258 | { |
michael@0 | 259 | nsAString::const_iterator start, end; |
michael@0 | 260 | aProtocol.BeginReading(start); |
michael@0 | 261 | aProtocol.EndReading(end); |
michael@0 | 262 | nsAString::const_iterator iter(start); |
michael@0 | 263 | |
michael@0 | 264 | FindCharInReadable(':', iter, end); |
michael@0 | 265 | mURI->SetScheme(NS_ConvertUTF16toUTF8(Substring(start, iter))); |
michael@0 | 266 | } |
michael@0 | 267 | |
michael@0 | 268 | #define URL_GETTER( value, func ) \ |
michael@0 | 269 | value.Truncate(); \ |
michael@0 | 270 | nsAutoCString tmp; \ |
michael@0 | 271 | nsresult rv = mURI->func(tmp); \ |
michael@0 | 272 | if (NS_SUCCEEDED(rv)) { \ |
michael@0 | 273 | CopyUTF8toUTF16(tmp, value); \ |
michael@0 | 274 | } |
michael@0 | 275 | |
michael@0 | 276 | void |
michael@0 | 277 | URL::GetUsername(nsString& aUsername) const |
michael@0 | 278 | { |
michael@0 | 279 | URL_GETTER(aUsername, GetUsername); |
michael@0 | 280 | } |
michael@0 | 281 | |
michael@0 | 282 | void |
michael@0 | 283 | URL::SetUsername(const nsAString& aUsername) |
michael@0 | 284 | { |
michael@0 | 285 | mURI->SetUsername(NS_ConvertUTF16toUTF8(aUsername)); |
michael@0 | 286 | } |
michael@0 | 287 | |
michael@0 | 288 | void |
michael@0 | 289 | URL::GetPassword(nsString& aPassword) const |
michael@0 | 290 | { |
michael@0 | 291 | URL_GETTER(aPassword, GetPassword); |
michael@0 | 292 | } |
michael@0 | 293 | |
michael@0 | 294 | void |
michael@0 | 295 | URL::SetPassword(const nsAString& aPassword) |
michael@0 | 296 | { |
michael@0 | 297 | mURI->SetPassword(NS_ConvertUTF16toUTF8(aPassword)); |
michael@0 | 298 | } |
michael@0 | 299 | |
michael@0 | 300 | void |
michael@0 | 301 | URL::GetHost(nsString& aHost) const |
michael@0 | 302 | { |
michael@0 | 303 | URL_GETTER(aHost, GetHostPort); |
michael@0 | 304 | } |
michael@0 | 305 | |
michael@0 | 306 | void |
michael@0 | 307 | URL::SetHost(const nsAString& aHost) |
michael@0 | 308 | { |
michael@0 | 309 | mURI->SetHostPort(NS_ConvertUTF16toUTF8(aHost)); |
michael@0 | 310 | } |
michael@0 | 311 | |
michael@0 | 312 | void |
michael@0 | 313 | URL::URLSearchParamsUpdated() |
michael@0 | 314 | { |
michael@0 | 315 | MOZ_ASSERT(mSearchParams); |
michael@0 | 316 | |
michael@0 | 317 | nsAutoString search; |
michael@0 | 318 | mSearchParams->Serialize(search); |
michael@0 | 319 | SetSearchInternal(search); |
michael@0 | 320 | } |
michael@0 | 321 | |
michael@0 | 322 | void |
michael@0 | 323 | URL::UpdateURLSearchParams() |
michael@0 | 324 | { |
michael@0 | 325 | if (!mSearchParams) { |
michael@0 | 326 | return; |
michael@0 | 327 | } |
michael@0 | 328 | |
michael@0 | 329 | nsAutoCString search; |
michael@0 | 330 | nsCOMPtr<nsIURL> url(do_QueryInterface(mURI)); |
michael@0 | 331 | if (url) { |
michael@0 | 332 | nsresult rv = url->GetQuery(search); |
michael@0 | 333 | if (NS_FAILED(rv)) { |
michael@0 | 334 | NS_WARNING("Failed to get the query from a nsIURL."); |
michael@0 | 335 | } |
michael@0 | 336 | } |
michael@0 | 337 | |
michael@0 | 338 | mSearchParams->ParseInput(search, this); |
michael@0 | 339 | } |
michael@0 | 340 | |
michael@0 | 341 | void |
michael@0 | 342 | URL::GetHostname(nsString& aHostname) const |
michael@0 | 343 | { |
michael@0 | 344 | URL_GETTER(aHostname, GetHost); |
michael@0 | 345 | } |
michael@0 | 346 | |
michael@0 | 347 | void |
michael@0 | 348 | URL::SetHostname(const nsAString& aHostname) |
michael@0 | 349 | { |
michael@0 | 350 | // nsStandardURL returns NS_ERROR_UNEXPECTED for an empty hostname |
michael@0 | 351 | // The return code is silently ignored |
michael@0 | 352 | mURI->SetHost(NS_ConvertUTF16toUTF8(aHostname)); |
michael@0 | 353 | } |
michael@0 | 354 | |
michael@0 | 355 | void |
michael@0 | 356 | URL::GetPort(nsString& aPort) const |
michael@0 | 357 | { |
michael@0 | 358 | aPort.Truncate(); |
michael@0 | 359 | |
michael@0 | 360 | int32_t port; |
michael@0 | 361 | nsresult rv = mURI->GetPort(&port); |
michael@0 | 362 | if (NS_SUCCEEDED(rv) && port != -1) { |
michael@0 | 363 | nsAutoString portStr; |
michael@0 | 364 | portStr.AppendInt(port, 10); |
michael@0 | 365 | aPort.Assign(portStr); |
michael@0 | 366 | } |
michael@0 | 367 | } |
michael@0 | 368 | |
michael@0 | 369 | void |
michael@0 | 370 | URL::SetPort(const nsAString& aPort) |
michael@0 | 371 | { |
michael@0 | 372 | nsresult rv; |
michael@0 | 373 | nsAutoString portStr(aPort); |
michael@0 | 374 | int32_t port = -1; |
michael@0 | 375 | |
michael@0 | 376 | // nsIURI uses -1 as default value. |
michael@0 | 377 | if (!portStr.IsEmpty()) { |
michael@0 | 378 | port = portStr.ToInteger(&rv); |
michael@0 | 379 | if (NS_FAILED(rv)) { |
michael@0 | 380 | return; |
michael@0 | 381 | } |
michael@0 | 382 | } |
michael@0 | 383 | |
michael@0 | 384 | mURI->SetPort(port); |
michael@0 | 385 | } |
michael@0 | 386 | |
michael@0 | 387 | void |
michael@0 | 388 | URL::GetPathname(nsString& aPathname) const |
michael@0 | 389 | { |
michael@0 | 390 | aPathname.Truncate(); |
michael@0 | 391 | |
michael@0 | 392 | nsCOMPtr<nsIURL> url(do_QueryInterface(mURI)); |
michael@0 | 393 | if (!url) { |
michael@0 | 394 | // Do not throw! Not having a valid URI or URL should result in an empty |
michael@0 | 395 | // string. |
michael@0 | 396 | return; |
michael@0 | 397 | } |
michael@0 | 398 | |
michael@0 | 399 | nsAutoCString file; |
michael@0 | 400 | nsresult rv = url->GetFilePath(file); |
michael@0 | 401 | if (NS_SUCCEEDED(rv)) { |
michael@0 | 402 | CopyUTF8toUTF16(file, aPathname); |
michael@0 | 403 | } |
michael@0 | 404 | } |
michael@0 | 405 | |
michael@0 | 406 | void |
michael@0 | 407 | URL::SetPathname(const nsAString& aPathname) |
michael@0 | 408 | { |
michael@0 | 409 | nsCOMPtr<nsIURL> url(do_QueryInterface(mURI)); |
michael@0 | 410 | if (!url) { |
michael@0 | 411 | // Ignore failures to be compatible with NS4. |
michael@0 | 412 | return; |
michael@0 | 413 | } |
michael@0 | 414 | |
michael@0 | 415 | url->SetFilePath(NS_ConvertUTF16toUTF8(aPathname)); |
michael@0 | 416 | } |
michael@0 | 417 | |
michael@0 | 418 | void |
michael@0 | 419 | URL::GetSearch(nsString& aSearch) const |
michael@0 | 420 | { |
michael@0 | 421 | aSearch.Truncate(); |
michael@0 | 422 | |
michael@0 | 423 | nsCOMPtr<nsIURL> url(do_QueryInterface(mURI)); |
michael@0 | 424 | if (!url) { |
michael@0 | 425 | // Do not throw! Not having a valid URI or URL should result in an empty |
michael@0 | 426 | // string. |
michael@0 | 427 | return; |
michael@0 | 428 | } |
michael@0 | 429 | |
michael@0 | 430 | nsAutoCString search; |
michael@0 | 431 | nsresult rv = url->GetQuery(search); |
michael@0 | 432 | if (NS_SUCCEEDED(rv) && !search.IsEmpty()) { |
michael@0 | 433 | CopyUTF8toUTF16(NS_LITERAL_CSTRING("?") + search, aSearch); |
michael@0 | 434 | } |
michael@0 | 435 | } |
michael@0 | 436 | |
michael@0 | 437 | void |
michael@0 | 438 | URL::SetSearch(const nsAString& aSearch) |
michael@0 | 439 | { |
michael@0 | 440 | SetSearchInternal(aSearch); |
michael@0 | 441 | UpdateURLSearchParams(); |
michael@0 | 442 | } |
michael@0 | 443 | |
michael@0 | 444 | void |
michael@0 | 445 | URL::SetSearchInternal(const nsAString& aSearch) |
michael@0 | 446 | { |
michael@0 | 447 | nsCOMPtr<nsIURL> url(do_QueryInterface(mURI)); |
michael@0 | 448 | if (!url) { |
michael@0 | 449 | // Ignore failures to be compatible with NS4. |
michael@0 | 450 | return; |
michael@0 | 451 | } |
michael@0 | 452 | |
michael@0 | 453 | url->SetQuery(NS_ConvertUTF16toUTF8(aSearch)); |
michael@0 | 454 | } |
michael@0 | 455 | |
michael@0 | 456 | URLSearchParams* |
michael@0 | 457 | URL::SearchParams() |
michael@0 | 458 | { |
michael@0 | 459 | CreateSearchParamsIfNeeded(); |
michael@0 | 460 | return mSearchParams; |
michael@0 | 461 | } |
michael@0 | 462 | |
michael@0 | 463 | void |
michael@0 | 464 | URL::SetSearchParams(URLSearchParams& aSearchParams) |
michael@0 | 465 | { |
michael@0 | 466 | if (mSearchParams) { |
michael@0 | 467 | mSearchParams->RemoveObserver(this); |
michael@0 | 468 | } |
michael@0 | 469 | |
michael@0 | 470 | // the observer will be cleared using the cycle collector. |
michael@0 | 471 | mSearchParams = &aSearchParams; |
michael@0 | 472 | mSearchParams->AddObserver(this); |
michael@0 | 473 | |
michael@0 | 474 | nsAutoString search; |
michael@0 | 475 | mSearchParams->Serialize(search); |
michael@0 | 476 | SetSearchInternal(search); |
michael@0 | 477 | } |
michael@0 | 478 | |
michael@0 | 479 | void |
michael@0 | 480 | URL::GetHash(nsString& aHash) const |
michael@0 | 481 | { |
michael@0 | 482 | aHash.Truncate(); |
michael@0 | 483 | |
michael@0 | 484 | nsAutoCString ref; |
michael@0 | 485 | nsresult rv = mURI->GetRef(ref); |
michael@0 | 486 | if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) { |
michael@0 | 487 | NS_UnescapeURL(ref); // XXX may result in random non-ASCII bytes! |
michael@0 | 488 | aHash.Assign(char16_t('#')); |
michael@0 | 489 | AppendUTF8toUTF16(ref, aHash); |
michael@0 | 490 | } |
michael@0 | 491 | } |
michael@0 | 492 | |
michael@0 | 493 | void |
michael@0 | 494 | URL::SetHash(const nsAString& aHash) |
michael@0 | 495 | { |
michael@0 | 496 | mURI->SetRef(NS_ConvertUTF16toUTF8(aHash)); |
michael@0 | 497 | } |
michael@0 | 498 | |
michael@0 | 499 | bool IsChromeURI(nsIURI* aURI) |
michael@0 | 500 | { |
michael@0 | 501 | bool isChrome = false; |
michael@0 | 502 | if (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome))) |
michael@0 | 503 | return isChrome; |
michael@0 | 504 | return false; |
michael@0 | 505 | } |
michael@0 | 506 | |
michael@0 | 507 | void |
michael@0 | 508 | URL::CreateSearchParamsIfNeeded() |
michael@0 | 509 | { |
michael@0 | 510 | if (!mSearchParams) { |
michael@0 | 511 | mSearchParams = new URLSearchParams(); |
michael@0 | 512 | mSearchParams->AddObserver(this); |
michael@0 | 513 | UpdateURLSearchParams(); |
michael@0 | 514 | } |
michael@0 | 515 | } |
michael@0 | 516 | |
michael@0 | 517 | } |
michael@0 | 518 | } |