1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "ChromeWorker.h"
8
9 #include "mozilla/dom/WorkerBinding.h"
10 #include "nsContentUtils.h"
11 #include "WorkerPrivate.h"
12
13 namespace mozilla {
14 namespace dom {
15
16 /* static */
Constructor(const GlobalObject & aGlobal,const nsAString & aScriptURL,ErrorResult & aRv)17 already_AddRefed<ChromeWorker> ChromeWorker::Constructor(
18 const GlobalObject& aGlobal, const nsAString& aScriptURL,
19 ErrorResult& aRv) {
20 JSContext* cx = aGlobal.Context();
21
22 RefPtr<WorkerPrivate> workerPrivate = WorkerPrivate::Constructor(
23 cx, aScriptURL, true /* aIsChromeWorker */, WorkerKindDedicated, u""_ns,
24 VoidCString(), nullptr /*aLoadInfo */, aRv);
25 if (NS_WARN_IF(aRv.Failed())) {
26 return nullptr;
27 }
28
29 nsCOMPtr<nsIGlobalObject> globalObject =
30 do_QueryInterface(aGlobal.GetAsSupports());
31
32 RefPtr<ChromeWorker> worker =
33 new ChromeWorker(globalObject, workerPrivate.forget());
34 return worker.forget();
35 }
36
37 /* static */
WorkerAvailable(JSContext * aCx,JSObject *)38 bool ChromeWorker::WorkerAvailable(JSContext* aCx, JSObject* /* unused */) {
39 // Chrome is always allowed to use workers, and content is never
40 // allowed to use ChromeWorker, so all we have to check is the
41 // caller. However, chrome workers apparently might not have a
42 // system principal, so we have to check for them manually.
43 if (NS_IsMainThread()) {
44 return nsContentUtils::IsSystemCaller(aCx);
45 }
46
47 return GetWorkerPrivateFromContext(aCx)->IsChromeWorker();
48 }
49
ChromeWorker(nsIGlobalObject * aGlobalObject,already_AddRefed<WorkerPrivate> aWorkerPrivate)50 ChromeWorker::ChromeWorker(nsIGlobalObject* aGlobalObject,
51 already_AddRefed<WorkerPrivate> aWorkerPrivate)
52 : Worker(aGlobalObject, std::move(aWorkerPrivate)) {}
53
54 ChromeWorker::~ChromeWorker() = default;
55
WrapObject(JSContext * aCx,JS::Handle<JSObject * > aGivenProto)56 JSObject* ChromeWorker::WrapObject(JSContext* aCx,
57 JS::Handle<JSObject*> aGivenProto) {
58 JS::Rooted<JSObject*> wrapper(
59 aCx, ChromeWorker_Binding::Wrap(aCx, this, aGivenProto));
60 if (wrapper) {
61 // Most DOM objects don't assume they have a reflector. If they don't have
62 // one and need one, they create it. But in workers code, we assume that the
63 // reflector is always present. In order to guarantee that it's always
64 // present, we have to preserve it. Otherwise the GC will happily collect it
65 // as needed.
66 MOZ_ALWAYS_TRUE(TryPreserveWrapper(wrapper));
67 }
68
69 return wrapper;
70 }
71
72 } // namespace dom
73 } // namespace mozilla
74