Bug 1323948 - PaintWorkletGlobalScope, r=smaug

This commit is contained in:
Andrea Marchesini 2016-12-16 22:21:51 +01:00
Родитель f76ac32127
Коммит 4623102eac
14 изменённых файлов: 215 добавлений и 6 удалений

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

@ -1626,6 +1626,7 @@ nsGlobalWindow::CleanUp()
mConsole = nullptr;
mAudioWorklet = nullptr;
mPaintWorklet = nullptr;
mExternal = nullptr;
@ -1994,6 +1995,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mU2F)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsole)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioWorklet)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPaintWorklet)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExternal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMozSelfSupport)
@ -2072,6 +2074,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mU2F)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsole)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAudioWorklet)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPaintWorklet)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mExternal)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMozSelfSupport)
@ -14271,12 +14274,30 @@ nsGlobalWindow::GetAudioWorklet(ErrorResult& aRv)
return nullptr;
}
mAudioWorklet = new Worklet(AsInner(), principal);
mAudioWorklet = new Worklet(AsInner(), principal, Worklet::eAudioWorklet);
}
return mAudioWorklet;
}
Worklet*
nsGlobalWindow::GetPaintWorklet(ErrorResult& aRv)
{
MOZ_RELEASE_ASSERT(IsInnerWindow());
if (!mPaintWorklet) {
nsIPrincipal* principal = GetPrincipal();
if (!principal) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
mPaintWorklet = new Worklet(AsInner(), principal, Worklet::ePaintWorklet);
}
return mPaintWorklet;
}
template class nsPIDOMWindow<mozIDOMWindowProxy>;
template class nsPIDOMWindow<mozIDOMWindow>;
template class nsPIDOMWindow<nsISupports>;

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

@ -928,6 +928,9 @@ public:
mozilla::dom::Worklet*
GetAudioWorklet(mozilla::ErrorResult& aRv);
mozilla::dom::Worklet*
GetPaintWorklet(mozilla::ErrorResult& aRv);
protected:
bool AlertOrConfirm(bool aAlert, const nsAString& aMessage,
nsIPrincipal& aSubjectPrincipal,
@ -1801,6 +1804,7 @@ protected:
RefPtr<mozilla::dom::cache::CacheStorage> mCacheStorage;
RefPtr<mozilla::dom::Console> mConsole;
RefPtr<mozilla::dom::Worklet> mAudioWorklet;
RefPtr<mozilla::dom::Worklet> mPaintWorklet;
// We need to store an nsISupports pointer to this object because the
// mozilla::dom::External class doesn't exist on b2g and using the type
// forward declared here means that ~nsGlobalWindow wouldn't compile because

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

@ -0,0 +1,13 @@
/* -*- Mode: IDL; 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/.
*
* The origin of this IDL file is
* https://drafts.css-houdini.org/css-paint-api-1/#paintworkletglobalscope
*/
[Global=(Worklet,PaintWorklet),Exposed=PaintWorklet]
interface PaintWorkletGlobalScope : WorkletGlobalScope {
void registerPaint(DOMString name, VoidFunction paintCtor);
};

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

@ -15,6 +15,7 @@
* http://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html
* https://w3c.github.io/webappsec-secure-contexts/#monkey-patching-global-object
* https://w3c.github.io/requestidlecallback/
* https://drafts.css-houdini.org/css-paint-api-1/#dom-window-paintworklet
*/
interface ApplicationCache;
@ -485,6 +486,12 @@ partial interface Window {
readonly attribute Worklet audioWorklet;
};
// https://drafts.css-houdini.org/css-paint-api-1/#dom-window-paintworklet
partial interface Window {
[Pref="dom.paintWorklet.enabled", Throws, SameObject]
readonly attribute Worklet paintWorklet;
};
Window implements ChromeWindow;
Window implements WindowOrWorkerGlobalScope;

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

@ -341,6 +341,7 @@ WEBIDL_FILES = [
'OscillatorNode.webidl',
'PaintRequest.webidl',
'PaintRequestList.webidl',
'PaintWorkletGlobalScope.webidl',
'PannerNode.webidl',
'ParentNode.webidl',
'Performance.webidl',

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

@ -0,0 +1,43 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 "PaintWorkletGlobalScope.h"
#include "mozilla/dom/PaintWorkletGlobalScopeBinding.h"
#include "mozilla/dom/RTCPeerConnectionBinding.h" // For VoidFunction
namespace mozilla {
namespace dom {
PaintWorkletGlobalScope::PaintWorkletGlobalScope(nsPIDOMWindowInner* aWindow)
: WorkletGlobalScope(aWindow)
{
}
PaintWorkletGlobalScope::~PaintWorkletGlobalScope()
{
}
bool
PaintWorkletGlobalScope::WrapGlobalObject(JSContext* aCx,
nsIPrincipal* aPrincipal,
JS::MutableHandle<JSObject*> aReflector)
{
JS::CompartmentOptions options;
return PaintWorkletGlobalScopeBinding::Wrap(aCx, this, this,
options,
nsJSPrincipals::get(aPrincipal),
true, aReflector);
}
void
PaintWorkletGlobalScope::RegisterPaint(const nsAString& aType,
VoidFunction& aProcessorCtor)
{
// Nothing to do here, yet.
}
} // dom namespace
} // mozilla namespace

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

@ -0,0 +1,36 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_dom_PaintWorkletGlobalScope_h
#define mozilla_dom_PaintWorkletGlobalScope_h
#include "mozilla/dom/WorkletGlobalScope.h"
namespace mozilla {
namespace dom {
class VoidFunction;
class PaintWorkletGlobalScope final : public WorkletGlobalScope
{
public:
explicit PaintWorkletGlobalScope(nsPIDOMWindowInner* aWindow);
bool
WrapGlobalObject(JSContext* aCx, nsIPrincipal* aPrincipal,
JS::MutableHandle<JSObject*> aReflector) override;
void
RegisterPaint(const nsAString& aType, VoidFunction& aProcessorCtor);
private:
~PaintWorkletGlobalScope();
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_PaintWorkletGlobalScope_h

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

@ -5,7 +5,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Worklet.h"
#include "WorkletGlobalScope.h"
#include "AudioWorkletGlobalScope.h"
#include "PaintWorkletGlobalScope.h"
#include "mozilla/dom/WorkletBinding.h"
#include "mozilla/dom/BlobBinding.h"
#include "mozilla/dom/Fetch.h"
@ -322,9 +324,11 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Worklet)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
Worklet::Worklet(nsPIDOMWindowInner* aWindow, nsIPrincipal* aPrincipal)
Worklet::Worklet(nsPIDOMWindowInner* aWindow, nsIPrincipal* aPrincipal,
WorkletType aWorkletType)
: mWindow(aWindow)
, mPrincipal(aPrincipal)
, mWorkletType(aWorkletType)
{
MOZ_ASSERT(aWindow);
MOZ_ASSERT(aPrincipal);
@ -353,8 +357,14 @@ WorkletGlobalScope*
Worklet::GetOrCreateGlobalScope(JSContext* aCx)
{
if (!mScope) {
// So far we don't have any other global scope to implement.
mScope = new AudioWorkletGlobalScope(mWindow);
switch (mWorkletType) {
case eAudioWorklet:
mScope = new AudioWorkletGlobalScope(mWindow);
break;
case ePaintWorklet:
mScope = new PaintWorkletGlobalScope(mWindow);
break;
}
JS::Rooted<JSObject*> global(aCx);
NS_ENSURE_TRUE(mScope->WrapGlobalObject(aCx, mPrincipal, &global), nullptr);

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

@ -30,7 +30,13 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Worklet)
Worklet(nsPIDOMWindowInner* aWindow, nsIPrincipal* aPrincipal);
enum WorkletType {
eAudioWorklet,
ePaintWorklet,
};
Worklet(nsPIDOMWindowInner* aWindow, nsIPrincipal* aPrincipal,
WorkletType aWorkletType);
nsPIDOMWindowInner* GetParentObject() const
{
@ -58,6 +64,8 @@ private:
nsCOMPtr<nsPIDOMWindowInner> mWindow;
nsCOMPtr<nsIPrincipal> mPrincipal;
WorkletType mWorkletType;
RefPtr<WorkletGlobalScope> mScope;
nsRefPtrHashtable<nsCStringHashKey, WorkletFetchHandler> mImportHandlers;

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

@ -6,12 +6,14 @@
EXPORTS.mozilla.dom += [
'AudioWorkletGlobalScope.h',
'PaintWorkletGlobalScope.h',
'Worklet.h',
'WorkletGlobalScope.h',
]
UNIFIED_SOURCES += [
'AudioWorkletGlobalScope.cpp',
'PaintWorkletGlobalScope.cpp',
'Worklet.cpp',
'WorkletGlobalScope.cpp',
]

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

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for PaintWorklet</title>
<script type="application/javascript" src="common.js"></script>
</head>
<body>
<script type="application/javascript">
setupTest();
paintWorklet.import("worklet_paintWorklet.js")
</script>
</body>
</html>

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

@ -15,3 +15,5 @@ support-files=file_dump.html worklet_dump.js
support-files=file_audioWorklet.html worklet_audioWorklet.js
[test_exception.html]
support-files=file_exception.html worklet_exception.js
[test_paintWorklet.html]
support-files=file_paintWorklet.html worklet_paintWorklet.js

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

@ -0,0 +1,42 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for PaintWorklet</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] == "So far so good") {
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.paintWorklet.enabled", true],
["dom.worklet.enabled", true]]},
function() { loadTest("file_paintWorklet.html"); });
</script>
</body>
</html>

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

@ -0,0 +1,3 @@
// This should work for real... at some point.
registerPaint("sure!", () => {});
console.log(this instanceof PaintWorkletGlobalScope ? "So far so good" : "error");