summaryrefslogtreecommitdiffstats
path: root/dom/console/ConsoleReportCollector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/console/ConsoleReportCollector.cpp')
-rw-r--r--dom/console/ConsoleReportCollector.cpp190
1 files changed, 190 insertions, 0 deletions
diff --git a/dom/console/ConsoleReportCollector.cpp b/dom/console/ConsoleReportCollector.cpp
new file mode 100644
index 000000000..268f7f8de
--- /dev/null
+++ b/dom/console/ConsoleReportCollector.cpp
@@ -0,0 +1,190 @@
+/* -*- 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 "mozilla/ConsoleReportCollector.h"
+
+#include "nsIConsoleService.h"
+#include "nsIScriptError.h"
+#include "nsNetUtil.h"
+
+namespace mozilla {
+
+NS_IMPL_ISUPPORTS(ConsoleReportCollector, nsIConsoleReportCollector)
+
+ConsoleReportCollector::ConsoleReportCollector()
+ : mMutex("mozilla::ConsoleReportCollector")
+{
+}
+
+void
+ConsoleReportCollector::AddConsoleReport(uint32_t aErrorFlags,
+ const nsACString& aCategory,
+ nsContentUtils::PropertiesFile aPropertiesFile,
+ const nsACString& aSourceFileURI,
+ uint32_t aLineNumber,
+ uint32_t aColumnNumber,
+ const nsACString& aMessageName,
+ const nsTArray<nsString>& aStringParams)
+{
+ // any thread
+ MutexAutoLock lock(mMutex);
+
+ mPendingReports.AppendElement(PendingReport(aErrorFlags, aCategory,
+ aPropertiesFile, aSourceFileURI,
+ aLineNumber, aColumnNumber,
+ aMessageName, aStringParams));
+}
+
+void
+ConsoleReportCollector::FlushConsoleReports(nsIDocument* aDocument,
+ ReportAction aAction)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsTArray<PendingReport> reports;
+
+ {
+ MutexAutoLock lock(mMutex);
+ if (aAction == ReportAction::Forget) {
+ mPendingReports.SwapElements(reports);
+ } else {
+ reports = mPendingReports;
+ }
+ }
+
+ for (uint32_t i = 0; i < reports.Length(); ++i) {
+ PendingReport& report = reports[i];
+
+ // It would be nice if we did not have to do this since ReportToConsole()
+ // just turns around and converts it back to a spec.
+ nsCOMPtr<nsIURI> uri;
+ if (!report.mSourceFileURI.IsEmpty()) {
+ nsresult rv = NS_NewURI(getter_AddRefs(uri), report.mSourceFileURI);
+ MOZ_ALWAYS_SUCCEEDS(rv);
+ if (NS_FAILED(rv)) {
+ continue;
+ }
+ }
+
+ // Convert back from nsTArray<nsString> to the char16_t** format required
+ // by our l10n libraries and ReportToConsole. (bug 1219762)
+ UniquePtr<const char16_t*[]> params;
+ uint32_t paramsLength = report.mStringParams.Length();
+ if (paramsLength > 0) {
+ params = MakeUnique<const char16_t*[]>(paramsLength);
+ for (uint32_t j = 0; j < paramsLength; ++j) {
+ params[j] = report.mStringParams[j].get();
+ }
+ }
+
+ nsContentUtils::ReportToConsole(report.mErrorFlags, report.mCategory,
+ aDocument, report.mPropertiesFile,
+ report.mMessageName.get(),
+ params.get(),
+ paramsLength, uri, EmptyString(),
+ report.mLineNumber, report.mColumnNumber);
+ }
+}
+
+void
+ConsoleReportCollector::FlushConsoleReports(nsIConsoleReportCollector* aCollector)
+{
+ MOZ_ASSERT(aCollector);
+
+ nsTArray<PendingReport> reports;
+
+ {
+ MutexAutoLock lock(mMutex);
+ mPendingReports.SwapElements(reports);
+ }
+
+ for (uint32_t i = 0; i < reports.Length(); ++i) {
+ PendingReport& report = reports[i];
+ aCollector->AddConsoleReport(report.mErrorFlags, report.mCategory,
+ report.mPropertiesFile, report.mSourceFileURI,
+ report.mLineNumber, report.mColumnNumber,
+ report.mMessageName, report.mStringParams);
+ }
+}
+
+void
+ConsoleReportCollector::FlushReportsByWindowId(uint64_t aWindowId,
+ ReportAction aAction)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsTArray<PendingReport> reports;
+
+ {
+ MutexAutoLock lock(mMutex);
+ if (aAction == ReportAction::Forget) {
+ mPendingReports.SwapElements(reports);
+ } else {
+ reports = mPendingReports;
+ }
+ }
+
+ nsCOMPtr<nsIConsoleService> consoleService =
+ do_GetService(NS_CONSOLESERVICE_CONTRACTID);
+ if (!consoleService) {
+ NS_WARNING("GetConsoleService failed");
+ return;
+ }
+
+ nsresult rv;
+ for (uint32_t i = 0; i < reports.Length(); ++i) {
+ PendingReport& report = reports[i];
+
+ nsXPIDLString errorText;
+ if (!report.mStringParams.IsEmpty()) {
+ rv = nsContentUtils::FormatLocalizedString(report.mPropertiesFile,
+ report.mMessageName.get(),
+ report.mStringParams,
+ errorText);
+ } else {
+ rv = nsContentUtils::GetLocalizedString(report.mPropertiesFile,
+ report.mMessageName.get(),
+ errorText);
+ }
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ continue;
+ }
+
+ nsCOMPtr<nsIScriptError> errorObject =
+ do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ continue;
+ }
+
+ rv = errorObject->InitWithWindowID(errorText,
+ NS_ConvertUTF8toUTF16(report.mSourceFileURI),
+ EmptyString(),
+ report.mLineNumber,
+ report.mColumnNumber,
+ report.mErrorFlags,
+ report.mCategory,
+ aWindowId);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ continue;
+ }
+
+ consoleService->LogMessage(errorObject);
+ }
+}
+
+void
+ConsoleReportCollector::ClearConsoleReports()
+{
+ MutexAutoLock lock(mMutex);
+
+ mPendingReports.Clear();
+}
+
+ConsoleReportCollector::~ConsoleReportCollector()
+{
+}
+
+} // namespace mozilla