Bug 1290021 - Implement a prototype version of Houdini "Worklets Level 1" spec - part 3 - Console API in worklet, r=smaug

This commit is contained in:
Andrea Marchesini 2016-11-06 09:54:52 +01:00
Родитель 8524257019
Коммит f8cf3b6565
12 изменённых файлов: 202 добавлений и 72 удалений

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

@ -14852,12 +14852,14 @@ nsGlobalWindow::TemporarilyDisableDialogs::~TemporarilyDisableDialogs()
already_AddRefed<Worklet>
nsGlobalWindow::CreateWorklet(ErrorResult& aRv)
{
MOZ_RELEASE_ASSERT(IsInnerWindow());
if (!mDoc) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
RefPtr<Worklet> worklet = new Worklet(this, mDoc->NodePrincipal());
RefPtr<Worklet> worklet = new Worklet(AsInner(), mDoc->NodePrincipal());
return worklet.forget();
}

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

@ -14,6 +14,7 @@
#include "mozilla/dom/Performance.h"
#include "mozilla/dom/StructuredCloneHolder.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/WorkletGlobalScope.h"
#include "mozilla/Maybe.h"
#include "nsCycleCollectionParticipant.h"
#include "nsDocument.h"
@ -2363,60 +2364,13 @@ Console::IsShuttingDown() const
/* static */ already_AddRefed<Console>
Console::GetConsole(const GlobalObject& aGlobal)
{
RefPtr<Console> console;
if (NS_IsMainThread()) {
nsCOMPtr<nsPIDOMWindowInner> innerWindow =
do_QueryInterface(aGlobal.GetAsSupports());
if (NS_WARN_IF(!innerWindow)) {
return nullptr;
}
nsGlobalWindow* window = nsGlobalWindow::Cast(innerWindow);
ErrorResult rv;
console = window->GetConsole(rv);
if (NS_WARN_IF(rv.Failed())) {
rv.SuppressException();
return nullptr;
}
} else {
JSContext* cx = aGlobal.Context();
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
MOZ_ASSERT(workerPrivate);
nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(aGlobal.GetAsSupports());
if (NS_WARN_IF(!global)) {
return nullptr;
}
WorkerGlobalScope* scope = workerPrivate->GlobalScope();
MOZ_ASSERT(scope);
// Normal worker scope.
ErrorResult rv;
if (scope == global) {
console = scope->GetConsole(rv);
}
// Debugger worker scope
else {
WorkerDebuggerGlobalScope* debuggerScope =
workerPrivate->DebuggerGlobalScope();
MOZ_ASSERT(debuggerScope);
MOZ_ASSERT(debuggerScope == global, "Which kind of global do we have?");
console = debuggerScope->GetConsole(rv);
}
if (NS_WARN_IF(rv.Failed())) {
rv.SuppressException();
return nullptr;
}
ErrorResult rv;
RefPtr<Console> console = GetConsoleInternal(aGlobal, rv);
if (NS_WARN_IF(rv.Failed()) || !console) {
rv.SuppressException();
return nullptr;
}
MOZ_ASSERT(console);
console->AssertIsOnOwningThread();
if (console->IsShuttingDown()) {
@ -2426,5 +2380,61 @@ Console::GetConsole(const GlobalObject& aGlobal)
return console.forget();
}
/* static */ Console*
Console::GetConsoleInternal(const GlobalObject& aGlobal, ErrorResult& aRv)
{
// Worklet
if (NS_IsMainThread()) {
nsCOMPtr<WorkletGlobalScope> workletScope =
do_QueryInterface(aGlobal.GetAsSupports());
if (workletScope) {
return workletScope->GetConsole(aRv);
}
}
// Window
if (NS_IsMainThread()) {
nsCOMPtr<nsPIDOMWindowInner> innerWindow =
do_QueryInterface(aGlobal.GetAsSupports());
if (NS_WARN_IF(!innerWindow)) {
return nullptr;
}
nsGlobalWindow* window = nsGlobalWindow::Cast(innerWindow);
return window->GetConsole(aRv);
}
// Workers
MOZ_ASSERT(!NS_IsMainThread());
JSContext* cx = aGlobal.Context();
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
MOZ_ASSERT(workerPrivate);
nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(aGlobal.GetAsSupports());
if (NS_WARN_IF(!global)) {
return nullptr;
}
WorkerGlobalScope* scope = workerPrivate->GlobalScope();
MOZ_ASSERT(scope);
// Normal worker scope.
if (scope == global) {
return scope->GetConsole(aRv);
}
// Debugger worker scope
else {
WorkerDebuggerGlobalScope* debuggerScope =
workerPrivate->DebuggerGlobalScope();
MOZ_ASSERT(debuggerScope);
MOZ_ASSERT(debuggerScope == global, "Which kind of global do we have?");
return debuggerScope->GetConsole(aRv);
}
}
} // namespace dom
} // namespace mozilla

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

@ -161,6 +161,9 @@ private:
static already_AddRefed<Console>
GetConsole(const GlobalObject& aGlobal);
static Console*
GetConsoleInternal(const GlobalObject& aGlobal, ErrorResult &aRv);
static void
ProfileMethod(const GlobalObject& aGlobal, const nsAString& aAction,
const Sequence<JS::Value>& aData);

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

@ -4,7 +4,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/. */
[Exposed=(Window,Worker,WorkerDebugger),
[Exposed=(Window,Worker,WorkerDebugger,Worklet),
ClassString="Console",
ProtoObjectHack]
namespace console {

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

@ -32,7 +32,11 @@ public:
static already_AddRefed<Promise>
Fetch(Worklet* aWorklet, const nsAString& aModuleURL, ErrorResult& aRv)
{
RefPtr<Promise> promise = Promise::Create(aWorklet->GetParentObject(), aRv);
nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(aWorklet->GetParentObject());
MOZ_ASSERT(global);
RefPtr<Promise> promise = Promise::Create(global, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
@ -42,8 +46,7 @@ public:
RequestInit init;
RefPtr<Promise> fetchPromise =
FetchRequest(aWorklet->GetParentObject(), request, init, aRv);
RefPtr<Promise> fetchPromise = FetchRequest(global, request, init, aRv);
if (NS_WARN_IF(aRv.Failed())) {
promise->MaybeReject(aRv);
return promise.forget();
@ -205,7 +208,7 @@ NS_IMPL_ISUPPORTS(WorkletFetchHandler, nsIStreamLoaderObserver)
} // anonymous namespace
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Worklet, mGlobal, mScope)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Worklet, mWindow, mScope)
NS_IMPL_CYCLE_COLLECTING_ADDREF(Worklet)
NS_IMPL_CYCLE_COLLECTING_RELEASE(Worklet)
@ -214,10 +217,13 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Worklet)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
Worklet::Worklet(nsIGlobalObject* aGlobal, nsIPrincipal* aPrincipal)
: mGlobal(aGlobal)
Worklet::Worklet(nsPIDOMWindowInner* aWindow, nsIPrincipal* aPrincipal)
: mWindow(aWindow)
, mPrincipal(aPrincipal)
{}
{
MOZ_ASSERT(aWindow);
MOZ_ASSERT(aPrincipal);
}
Worklet::~Worklet()
{}
@ -238,7 +244,7 @@ WorkletGlobalScope*
Worklet::GetOrCreateGlobalScope(JSContext* aCx)
{
if (!mScope) {
mScope = new WorkletGlobalScope();
mScope = new WorkletGlobalScope(mWindow);
JS::Rooted<JSObject*> global(aCx);
NS_ENSURE_TRUE(mScope->WrapGlobalObject(aCx, mPrincipal, &global), nullptr);

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

@ -12,7 +12,7 @@
#include "nsWrapperCache.h"
#include "nsCOMPtr.h"
class nsIGlobalObject;
class nsPIDOMWindowInner;
class nsIPrincipal;
namespace mozilla {
@ -28,11 +28,11 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Worklet)
Worklet(nsIGlobalObject* aGlobal, nsIPrincipal* aPrincipal);
Worklet(nsPIDOMWindowInner* aWindow, nsIPrincipal* aPrincipal);
nsIGlobalObject* GetParentObject() const
nsPIDOMWindowInner* GetParentObject() const
{
return mGlobal;
return mWindow;
}
virtual JSObject*
@ -47,7 +47,7 @@ public:
private:
~Worklet();
nsCOMPtr<nsIGlobalObject> mGlobal;
nsCOMPtr<nsPIDOMWindowInner> mWindow;
nsCOMPtr<nsIPrincipal> mPrincipal;
RefPtr<WorkletGlobalScope> mScope;

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

@ -6,6 +6,7 @@
#include "WorkletGlobalScope.h"
#include "mozilla/dom/WorkletGlobalScopeBinding.h"
#include "mozilla/dom/Console.h"
namespace mozilla {
namespace dom {
@ -14,12 +15,16 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(WorkletGlobalScope)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WorkletGlobalScope)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsole)
tmp->UnlinkHostObjectURIs();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(WorkletGlobalScope)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsole)
tmp->TraverseHostObjectURIs(cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@ -30,8 +35,19 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(WorkletGlobalScope)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WorkletGlobalScope)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
NS_INTERFACE_MAP_ENTRY(WorkletGlobalScope)
NS_INTERFACE_MAP_END
WorkletGlobalScope::WorkletGlobalScope(nsPIDOMWindowInner* aWindow)
: mWindow(aWindow)
{
MOZ_ASSERT(aWindow);
}
WorkletGlobalScope::~WorkletGlobalScope()
{
}
JSObject*
WorkletGlobalScope::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
@ -50,5 +66,19 @@ WorkletGlobalScope::WrapGlobalObject(JSContext* aCx,
nsJSPrincipals::get(aPrincipal),
true, aReflector);
}
Console*
WorkletGlobalScope::GetConsole(ErrorResult& aRv)
{
if (!mConsole) {
mConsole = Console::Create(mWindow, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
}
return mConsole;
}
} // dom namespace
} // mozilla namespace

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

@ -12,20 +12,28 @@
#include "nsIGlobalObject.h"
#include "nsWrapperCache.h"
#define WORKLET_IID \
{ 0x1b3f62e7, 0xe357, 0x44be, \
{ 0xbf, 0xe0, 0xdf, 0x85, 0xe6, 0x56, 0x85, 0xac } }
class nsIPrincipal;
class nsPIDOMWindowInner;
namespace mozilla {
namespace dom {
class Console;
class WorkletGlobalScope final : public nsIGlobalObject
, public nsWrapperCache
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(WORKLET_IID)
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WorkletGlobalScope)
WorkletGlobalScope()
{}
explicit WorkletGlobalScope(nsPIDOMWindowInner* aWindow);
nsIGlobalObject* GetParentObject() const
{
@ -45,11 +53,18 @@ public:
return GetWrapper();
}
Console*
GetConsole(ErrorResult& aRv);
private:
~WorkletGlobalScope()
{}
~WorkletGlobalScope();
nsCOMPtr<nsPIDOMWindowInner> mWindow;
RefPtr<Console> mConsole;
};
NS_DEFINE_STATIC_IID_ACCESSOR(WorkletGlobalScope, WORKLET_IID)
} // namespace dom
} // namespace mozilla

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

@ -0,0 +1,19 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Worklet</title>
<script type="application/javascript" src="common.js"></script>
</head>
<body>
<script type="application/javascript">
setupTest();
var worklet = window.createWorklet();
ok(!!worklet, "We have a Worklet");
worklet.import("worklet_console.js");
</script>
</body>
</html>

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

@ -1,6 +1,8 @@
[DEFAULT]
support-files =
common.js
file_basic.html
[test_basic.html]
support-files=file_basic.html
[test_console.html]
support-files=file_console.html worklet_console.js

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

@ -0,0 +1,42 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Worklet - Console</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="common.js"></script>
</head>
<body>
<script type="application/javascript">
function consoleListener() {
SpecialPowers.addObserver(this, "console-api-log-event", false);
}
consoleListener.prototype = {
observe: function(aSubject, aTopic, aData) {
if (aTopic == "console-api-log-event") {
var obj = aSubject.wrappedJSObject;
if (obj.arguments[0] == "Hello world from a worklet") {
ok(true, "Message received \\o/");
SpecialPowers.removeObserver(this, "console-api-log-event");
SimpleTest.finish();
return;
}
}
}
}
var cl = new consoleListener();
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{"set": [["dom.worklet.testing.enabled", true],
["dom.worklet.enabled", true]]},
function() { loadTest("file_console.html"); });
</script>
</body>
</html>

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

@ -0,0 +1 @@
console.log("Hello world from a worklet");