Bug 507930 - 'Workers: Implement WorkerLocation'. r+sr=jst

This commit is contained in:
Ben Turner 2009-08-12 16:39:08 -07:00
Родитель 30323afdf4
Коммит 69c89ea957
10 изменённых файлов: 429 добавлений и 5 удалений

Просмотреть файл

@ -83,6 +83,21 @@ interface nsIWorkerErrorEvent : nsIDOMEvent
in unsigned long aLinenoArg);
};
[scriptable, uuid(17a005c3-4f2f-4bb6-b169-c181fa6873de)]
interface nsIWorkerLocation : nsISupports
{
readonly attribute AUTF8String href;
readonly attribute AUTF8String protocol;
readonly attribute AUTF8String host;
readonly attribute AUTF8String hostname;
readonly attribute AUTF8String port;
readonly attribute AUTF8String pathname;
readonly attribute AUTF8String search;
readonly attribute AUTF8String hash;
AUTF8String toString();
};
[scriptable, uuid(74fb665a-e477-4ce2-b3c6-c58b1b28b6c3)]
interface nsIWorkerNavigator : nsISupports
{
@ -92,11 +107,12 @@ interface nsIWorkerNavigator : nsISupports
readonly attribute DOMString userAgent;
};
[scriptable, uuid(d7d7cf59-6c8a-4598-8753-630953ae7409)]
[scriptable, uuid(c111e7d3-8044-4458-aa7b-637696ffb841)]
interface nsIWorkerGlobalScope : nsISupports
{
readonly attribute nsIWorkerGlobalScope self;
readonly attribute nsIWorkerNavigator navigator;
readonly attribute nsIWorkerLocation location;
attribute nsIDOMEventListener onerror;
};

Просмотреть файл

@ -71,6 +71,7 @@ CPPSRCS = \
nsDOMThreadService.cpp \
nsDOMWorker.cpp \
nsDOMWorkerEvents.cpp \
nsDOMWorkerLocation.cpp \
nsDOMWorkerMessageHandler.cpp \
nsDOMWorkerNavigator.cpp \
nsDOMWorkerPool.cpp \

Просмотреть файл

@ -58,6 +58,7 @@
#include "nsDOMThreadService.h"
#include "nsDOMWorkerEvents.h"
#include "nsDOMWorkerLocation.h"
#include "nsDOMWorkerNavigator.h"
#include "nsDOMWorkerPool.h"
#include "nsDOMWorkerScriptLoader.h"
@ -698,6 +699,18 @@ nsDOMWorkerScope::GetNavigator(nsIWorkerNavigator** _retval)
return NS_OK;
}
NS_IMETHODIMP
nsDOMWorkerScope::GetLocation(nsIWorkerLocation** _retval)
{
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
nsCOMPtr<nsIWorkerLocation> location = mWorker->GetLocation();
NS_ASSERTION(location, "This should never be null!");
location.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWorkerScope::GetOnerror(nsIDOMEventListener** aOnerror)
{
@ -1744,6 +1757,24 @@ nsDOMWorker::ResumeFeatures()
}
}
nsresult
nsDOMWorker::SetURI(nsIURI* aURI)
{
NS_ASSERTION(aURI, "Don't hand me a null pointer!");
NS_ASSERTION(!mURI && !mLocation, "Called more than once?!");
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
mURI = aURI;
nsCOMPtr<nsIURL> url(do_QueryInterface(aURI));
NS_ENSURE_TRUE(url, NS_ERROR_NO_INTERFACE);
mLocation = nsDOMWorkerLocation::NewLocation(url);
NS_ENSURE_TRUE(mLocation, NS_ERROR_FAILURE);
return NS_OK;
}
nsresult
nsDOMWorker::FireCloseRunnable(PRIntervalTime aTimeoutInterval,
PRBool aClearQueue,

Просмотреть файл

@ -266,9 +266,7 @@ private:
return mURI;
}
void SetURI(nsIURI* aURI) {
mURI = aURI;
}
nsresult SetURI(nsIURI* aURI);
nsresult FireCloseRunnable(PRIntervalTime aTimeoutInterval,
PRBool aClearQueue,
@ -277,6 +275,10 @@ private:
nsresult TerminateInternal(PRBool aFromFinalize);
nsIWorkerLocation* GetLocation() {
return mLocation;
}
private:
// mParent will live as long as mParentWN but only mParentWN will keep the JS
@ -314,6 +316,8 @@ private:
nsCOMPtr<nsITimer> mKillTimer;
nsCOMPtr<nsIWorkerLocation> mLocation;
PRPackedBool mSuspended;
PRPackedBool mCompileAttempted;
};

Просмотреть файл

@ -0,0 +1,223 @@
/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is worker threads.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Turner <bent.mozilla@gmail.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsDOMWorkerLocation.h"
#include "nsIClassInfoImpl.h"
#include "nsITextToSubURI.h"
#include "nsIURL.h"
#include "nsDOMWorkerMacros.h"
#include "nsAutoPtr.h"
#include "nsEscape.h"
#include "nsNetUtil.h"
#define XPC_MAP_CLASSNAME nsDOMWorkerLocation
#define XPC_MAP_QUOTED_CLASSNAME "WorkerLocation"
#define XPC_MAP_FLAGS \
nsIXPCScriptable::USE_JSSTUB_FOR_ADDPROPERTY | \
nsIXPCScriptable::USE_JSSTUB_FOR_DELPROPERTY | \
nsIXPCScriptable::USE_JSSTUB_FOR_SETPROPERTY | \
nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE | \
nsIXPCScriptable::CLASSINFO_INTERFACES_ONLY | \
nsIXPCScriptable::DONT_REFLECT_INTERFACE_NAMES
#include "xpc_map_end.h"
NS_IMPL_THREADSAFE_ISUPPORTS3(nsDOMWorkerLocation, nsIWorkerLocation,
nsIClassInfo,
nsIXPCScriptable)
NS_IMPL_CI_INTERFACE_GETTER1(nsDOMWorkerLocation, nsIWorkerLocation)
NS_IMPL_THREADSAFE_DOM_CI_GETINTERFACES(nsDOMWorkerLocation)
NS_IMPL_THREADSAFE_DOM_CI_ALL_THE_REST(nsDOMWorkerLocation)
NS_IMETHODIMP
nsDOMWorkerLocation::GetHelperForLanguage(PRUint32 aLanguage,
nsISupports** _retval)
{
if (aLanguage == nsIProgrammingLanguage::JAVASCRIPT) {
NS_ADDREF(*_retval = NS_ISUPPORTS_CAST(nsIWorkerLocation*, this));
}
else {
*_retval = nsnull;
}
return NS_OK;
}
// static
already_AddRefed<nsIWorkerLocation>
nsDOMWorkerLocation::NewLocation(nsIURL* aURL)
{
NS_ASSERTION(aURL, "Don't hand me a null pointer!");
nsAutoPtr<nsDOMWorkerLocation> location(new nsDOMWorkerLocation());
NS_ENSURE_TRUE(location, nsnull);
nsresult rv = aURL->GetSpec(location->mHref);
NS_ENSURE_SUCCESS(rv, nsnull);
rv = aURL->GetHost(location->mHostname);
NS_ENSURE_SUCCESS(rv, nsnull);
rv = aURL->GetPath(location->mPathname);
NS_ENSURE_SUCCESS(rv, nsnull);
nsCString temp;
rv = aURL->GetQuery(temp);
NS_ENSURE_SUCCESS(rv, nsnull);
if (!temp.IsEmpty()) {
location->mSearch.AssignLiteral("?");
location->mSearch.Append(temp);
}
rv = aURL->GetRef(temp);
NS_ENSURE_SUCCESS(rv, nsnull);
if (!temp.IsEmpty()) {
nsAutoString unicodeRef;
nsCOMPtr<nsITextToSubURI> converter =
do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
nsCString charset;
rv = aURL->GetOriginCharset(charset);
if (NS_SUCCEEDED(rv)) {
rv = converter->UnEscapeURIForUI(charset, temp, unicodeRef);
if (NS_SUCCEEDED(rv)) {
location->mHash.AssignLiteral("#");
location->mHash.Append(NS_ConvertUTF16toUTF8(unicodeRef));
}
}
}
if (NS_FAILED(rv)) {
location->mHash.AssignLiteral("#");
location->mHash.Append(temp);
}
}
rv = aURL->GetScheme(location->mProtocol);
NS_ENSURE_SUCCESS(rv, nsnull);
location->mProtocol.AppendLiteral(":");
PRInt32 port;
rv = aURL->GetPort(&port);
if (NS_SUCCEEDED(rv) && port != -1) {
location->mPort.AppendInt(port);
nsCAutoString host(location->mHostname);
host.AppendLiteral(":");
host.Append(location->mPort);
location->mHost.Assign(host);
}
else {
location->mHost.Assign(location->mHostname);
}
NS_ADDREF(location);
return location.forget();
}
NS_IMETHODIMP
nsDOMWorkerLocation::GetHref(nsACString& aHref)
{
aHref.Assign(mHref);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWorkerLocation::GetProtocol(nsACString& aProtocol)
{
aProtocol.Assign(mProtocol);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWorkerLocation::GetHost(nsACString& aHost)
{
aHost.Assign(mHost);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWorkerLocation::GetHostname(nsACString& aHostname)
{
aHostname.Assign(mHostname);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWorkerLocation::GetPort(nsACString& aPort)
{
aPort.Assign(mPort);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWorkerLocation::GetPathname(nsACString& aPathname)
{
aPathname.Assign(mPathname);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWorkerLocation::GetSearch(nsACString& aSearch)
{
aSearch.Assign(mSearch);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWorkerLocation::GetHash(nsACString& aHash)
{
aHash.Assign(mHash);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWorkerLocation::ToString(nsACString& _retval)
{
return GetHref(_retval);
}

Просмотреть файл

@ -0,0 +1,77 @@
/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is worker threads.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Turner <bent.mozilla@gmail.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef __NSDOMWORKERLOCATION_H__
#define __NSDOMWORKERLOCATION_H__
#include "nsIClassInfo.h"
#include "nsIDOMWorkers.h"
#include "nsIXPCScriptable.h"
#include "nsCOMPtr.h"
#include "nsStringGlue.h"
class nsIURL;
class nsDOMWorkerLocation : public nsIWorkerLocation,
public nsIClassInfo,
public nsIXPCScriptable
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIWORKERLOCATION
NS_DECL_NSICLASSINFO
NS_DECL_NSIXPCSCRIPTABLE
static already_AddRefed<nsIWorkerLocation> NewLocation(nsIURL* aURL);
protected:
nsDOMWorkerLocation() { }
private:
nsCString mHref;
nsCString mProtocol;
nsCString mHost;
nsCString mHostname;
nsCString mPort;
nsCString mPathname;
nsCString mSearch;
nsCString mHash;
};
#endif /* __NSDOMWORKERLOCATION_H__ */

Просмотреть файл

@ -483,7 +483,9 @@ nsDOMWorkerScriptLoader::RunInternal()
// Set the principal and URI on the new worker.
mWorker->SetPrincipal(principal);
mWorker->SetURI(uri);
rv = mWorker->SetURI(uri);
NS_ENSURE_SUCCESS(rv, rv);
}
else {
rv = secMan->CheckLoadURIWithPrincipal(principal, uri, 0);

Просмотреть файл

@ -66,6 +66,8 @@ _TEST_FILES = \
importScripts_worker_imported4.js \
test_json.html \
json_worker.js \
test_location.html \
location_worker.js \
test_longThread.html \
longThread_worker.js \
test_navigator.html \

Просмотреть файл

@ -0,0 +1,4 @@
for (var string in self.location) {
postMessage({ "string": string, "value": self.location[string] });
}
postMessage({"string": "testfinished", "value": self.location.toString()});

Просмотреть файл

@ -0,0 +1,64 @@
<!DOCTYPE HTML>
<html>
<!--
Tests of DOM Worker Location
-->
<head>
<title>Test for DOM Worker Location</title>
<script type="text/javascript" src="/MochiKit/packed.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" language="javascript">
var thisFilename = "test_location.html";
var workerFilename = "location_worker.js";
var href = window.location.href
var baseHref = href.substr(0, href.lastIndexOf("/") + 1);
var path = window.location.pathname;
var basePath = path.substr(0, path.lastIndexOf("/") + 1);
var strings = {
"href": baseHref + workerFilename,
"protocol": window.location.protocol,
"host": window.location.host,
"hostname": window.location.hostname,
"port": window.location.port,
"pathname": basePath + workerFilename,
"search": "",
"hash": ""
};
is(thisFilename, href.substr(href.lastIndexOf("/") + 1));
var worker = new Worker(workerFilename);
worker.onmessage = function(event) {
if (event.data.string == "testfinished") {
is(event.data.value, strings["href"]);
SimpleTest.finish();
return;
}
ok(event.data.string in strings);
is(event.data.value, strings[event.data.string]);
};
worker.onerror = function(event) {
ok(false, "Worker had an error: " + event.data);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>