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/. */
7 #include "ConsoleUtils.h"
8 #include "ConsoleCommon.h"
9 #include "nsContentUtils.h"
10 #include "nsIConsoleAPIStorage.h"
11 #include "nsIXPConnect.h"
12 #include "nsServiceManagerUtils.h"
14 #include "mozilla/ClearOnShutdown.h"
15 #include "mozilla/NullPrincipal.h"
16 #include "mozilla/dom/ConsoleBinding.h"
17 #include "mozilla/dom/RootedDictionary.h"
18 #include "mozilla/dom/ScriptSettings.h"
19 #include "js/PropertyAndElement.h" // JS_DefineProperty
21 namespace mozilla::dom
{
25 StaticRefPtr
<ConsoleUtils
> gConsoleUtilsService
;
30 ConsoleUtils
* ConsoleUtils::GetOrCreate() {
31 if (!gConsoleUtilsService
) {
32 MOZ_ASSERT(NS_IsMainThread());
34 gConsoleUtilsService
= new ConsoleUtils();
35 ClearOnShutdown(&gConsoleUtilsService
);
38 return gConsoleUtilsService
;
41 ConsoleUtils::ConsoleUtils() = default;
42 ConsoleUtils::~ConsoleUtils() = default;
45 void ConsoleUtils::ReportForServiceWorkerScope(const nsAString
& aScope
,
46 const nsAString
& aMessage
,
47 const nsAString
& aFilename
,
49 uint32_t aColumnNumber
,
51 MOZ_ASSERT(NS_IsMainThread());
53 RefPtr
<ConsoleUtils
> service
= ConsoleUtils::GetOrCreate();
54 if (NS_WARN_IF(!service
)) {
58 service
->ReportForServiceWorkerScopeInternal(
59 aScope
, aMessage
, aFilename
, aLineNumber
, aColumnNumber
, aLevel
);
62 void ConsoleUtils::ReportForServiceWorkerScopeInternal(
63 const nsAString
& aScope
, const nsAString
& aMessage
,
64 const nsAString
& aFilename
, uint32_t aLineNumber
, uint32_t aColumnNumber
,
66 MOZ_ASSERT(NS_IsMainThread());
71 JSContext
* cx
= jsapi
.cx();
73 ConsoleCommon::ClearException
ce(cx
);
74 JS::Rooted
<JSObject
*> global(cx
, GetOrCreateSandbox(cx
));
75 if (NS_WARN_IF(!global
)) {
79 // The GetOrCreateSandbox call returns a proxy to the actual sandbox object.
80 // We don't need a proxy here.
81 global
= js::UncheckedUnwrap(global
);
83 JSAutoRealm
ar(cx
, global
);
85 RootedDictionary
<ConsoleEvent
> event(cx
);
87 event
.mID
.Construct();
88 event
.mID
.Value().SetAsString() = aScope
;
90 event
.mInnerID
.Construct();
91 event
.mInnerID
.Value().SetAsString() = u
"ServiceWorker"_ns
;
95 event
.mLevel
= u
"log"_ns
;
99 event
.mLevel
= u
"warn"_ns
;
103 event
.mLevel
= u
"error"_ns
;
107 event
.mFilename
= aFilename
;
108 event
.mLineNumber
= aLineNumber
;
109 event
.mColumnNumber
= aColumnNumber
;
110 event
.mTimeStamp
= JS_Now() / PR_USEC_PER_MSEC
;
111 event
.mMicroSecondTimeStamp
= JS_Now();
113 JS::Rooted
<JS::Value
> messageValue(cx
);
114 if (!dom::ToJSValue(cx
, aMessage
, &messageValue
)) {
118 event
.mArguments
.Construct();
119 if (!event
.mArguments
.Value().AppendElement(messageValue
, fallible
)) {
123 nsCOMPtr
<nsIConsoleAPIStorage
> storage
=
124 do_GetService("@mozilla.org/consoleAPI-storage;1");
126 if (NS_WARN_IF(!storage
)) {
130 JS::Rooted
<JS::Value
> eventValue(cx
);
131 if (!ToJSValue(cx
, event
, &eventValue
)) {
135 // This is a legacy property.
136 JS::Rooted
<JSObject
*> eventObj(cx
, &eventValue
.toObject());
137 if (NS_WARN_IF(!JS_DefineProperty(cx
, eventObj
, "wrappedJSObject", eventObj
,
138 JSPROP_ENUMERATE
))) {
142 storage
->RecordEvent(u
"ServiceWorker"_ns
, eventValue
);
145 JSObject
* ConsoleUtils::GetOrCreateSandbox(JSContext
* aCx
) {
146 AssertIsOnMainThread();
149 nsIXPConnect
* xpc
= nsContentUtils::XPConnect();
150 MOZ_ASSERT(xpc
, "This should never be null!");
152 RefPtr
<NullPrincipal
> nullPrincipal
=
153 NullPrincipal::CreateWithoutOriginAttributes();
155 JS::Rooted
<JSObject
*> sandbox(aCx
);
156 nsresult rv
= xpc
->CreateSandbox(aCx
, nullPrincipal
, sandbox
.address());
157 if (NS_WARN_IF(NS_FAILED(rv
))) {
161 mSandbox
= new JSObjectHolder(aCx
, sandbox
);
164 return mSandbox
->GetJSObject();
167 } // namespace mozilla::dom