summaryrefslogtreecommitdiffstats
path: root/dom/console/ConsoleUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/console/ConsoleUtils.cpp')
-rw-r--r--dom/console/ConsoleUtils.cpp167
1 files changed, 167 insertions, 0 deletions
diff --git a/dom/console/ConsoleUtils.cpp b/dom/console/ConsoleUtils.cpp
new file mode 100644
index 0000000000..9767dd30dd
--- /dev/null
+++ b/dom/console/ConsoleUtils.cpp
@@ -0,0 +1,167 @@
+/* -*- 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 "ConsoleUtils.h"
+#include "ConsoleCommon.h"
+#include "nsContentUtils.h"
+#include "nsIConsoleAPIStorage.h"
+#include "nsIXPConnect.h"
+#include "nsServiceManagerUtils.h"
+
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/NullPrincipal.h"
+#include "mozilla/dom/ConsoleBinding.h"
+#include "mozilla/dom/RootedDictionary.h"
+#include "mozilla/dom/ScriptSettings.h"
+#include "js/PropertyAndElement.h" // JS_DefineProperty
+
+namespace mozilla::dom {
+
+namespace {
+
+StaticRefPtr<ConsoleUtils> gConsoleUtilsService;
+
+}
+
+/* static */
+ConsoleUtils* ConsoleUtils::GetOrCreate() {
+ if (!gConsoleUtilsService) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ gConsoleUtilsService = new ConsoleUtils();
+ ClearOnShutdown(&gConsoleUtilsService);
+ }
+
+ return gConsoleUtilsService;
+}
+
+ConsoleUtils::ConsoleUtils() = default;
+ConsoleUtils::~ConsoleUtils() = default;
+
+/* static */
+void ConsoleUtils::ReportForServiceWorkerScope(const nsAString& aScope,
+ const nsAString& aMessage,
+ const nsAString& aFilename,
+ uint32_t aLineNumber,
+ uint32_t aColumnNumber,
+ Level aLevel) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ RefPtr<ConsoleUtils> service = ConsoleUtils::GetOrCreate();
+ if (NS_WARN_IF(!service)) {
+ return;
+ }
+
+ service->ReportForServiceWorkerScopeInternal(
+ aScope, aMessage, aFilename, aLineNumber, aColumnNumber, aLevel);
+}
+
+void ConsoleUtils::ReportForServiceWorkerScopeInternal(
+ const nsAString& aScope, const nsAString& aMessage,
+ const nsAString& aFilename, uint32_t aLineNumber, uint32_t aColumnNumber,
+ Level aLevel) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ AutoJSAPI jsapi;
+ jsapi.Init();
+
+ JSContext* cx = jsapi.cx();
+
+ ConsoleCommon::ClearException ce(cx);
+ JS::Rooted<JSObject*> global(cx, GetOrCreateSandbox(cx));
+ if (NS_WARN_IF(!global)) {
+ return;
+ }
+
+ // The GetOrCreateSandbox call returns a proxy to the actual sandbox object.
+ // We don't need a proxy here.
+ global = js::UncheckedUnwrap(global);
+
+ JSAutoRealm ar(cx, global);
+
+ RootedDictionary<ConsoleEvent> event(cx);
+
+ event.mID.Construct();
+ event.mID.Value().SetAsString() = aScope;
+
+ event.mInnerID.Construct();
+ event.mInnerID.Value().SetAsString() = u"ServiceWorker"_ns;
+
+ switch (aLevel) {
+ case eLog:
+ event.mLevel = u"log"_ns;
+ break;
+
+ case eWarning:
+ event.mLevel = u"warn"_ns;
+ break;
+
+ case eError:
+ event.mLevel = u"error"_ns;
+ break;
+ }
+
+ event.mFilename = aFilename;
+ event.mLineNumber = aLineNumber;
+ event.mColumnNumber = aColumnNumber;
+ event.mTimeStamp = JS_Now() / PR_USEC_PER_MSEC;
+ event.mMicroSecondTimeStamp = JS_Now();
+
+ JS::Rooted<JS::Value> messageValue(cx);
+ if (!dom::ToJSValue(cx, aMessage, &messageValue)) {
+ return;
+ }
+
+ event.mArguments.Construct();
+ if (!event.mArguments.Value().AppendElement(messageValue, fallible)) {
+ return;
+ }
+
+ nsCOMPtr<nsIConsoleAPIStorage> storage =
+ do_GetService("@mozilla.org/consoleAPI-storage;1");
+
+ if (NS_WARN_IF(!storage)) {
+ return;
+ }
+
+ JS::Rooted<JS::Value> eventValue(cx);
+ if (!ToJSValue(cx, event, &eventValue)) {
+ return;
+ }
+
+ // This is a legacy property.
+ JS::Rooted<JSObject*> eventObj(cx, &eventValue.toObject());
+ if (NS_WARN_IF(!JS_DefineProperty(cx, eventObj, "wrappedJSObject", eventObj,
+ JSPROP_ENUMERATE))) {
+ return;
+ }
+
+ storage->RecordEvent(u"ServiceWorker"_ns, eventValue);
+}
+
+JSObject* ConsoleUtils::GetOrCreateSandbox(JSContext* aCx) {
+ AssertIsOnMainThread();
+
+ if (!mSandbox) {
+ nsIXPConnect* xpc = nsContentUtils::XPConnect();
+ MOZ_ASSERT(xpc, "This should never be null!");
+
+ RefPtr<NullPrincipal> nullPrincipal =
+ NullPrincipal::CreateWithoutOriginAttributes();
+
+ JS::Rooted<JSObject*> sandbox(aCx);
+ nsresult rv = xpc->CreateSandbox(aCx, nullPrincipal, sandbox.address());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return nullptr;
+ }
+
+ mSandbox = new JSObjectHolder(aCx, sandbox);
+ }
+
+ return mSandbox->GetJSObject();
+}
+
+} // namespace mozilla::dom