diff options
Diffstat (limited to 'dom/console/ConsoleReportCollector.cpp')
-rw-r--r-- | dom/console/ConsoleReportCollector.cpp | 190 |
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 |