michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* vim: set ts=8 sts=4 et sw=4 tw=99: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * nsIScriptError implementation. Defined here, lacking a JS-specific michael@0: * place to put XPCOM things. michael@0: */ michael@0: michael@0: #include "xpcprivate.h" michael@0: #include "jsprf.h" michael@0: #include "nsGlobalWindow.h" michael@0: #include "nsPIDOMWindow.h" michael@0: #include "nsILoadContext.h" michael@0: #include "nsIDocShell.h" michael@0: michael@0: NS_IMPL_ISUPPORTS(nsScriptError, nsIConsoleMessage, nsIScriptError) michael@0: michael@0: nsScriptError::nsScriptError() michael@0: : mMessage(), michael@0: mSourceName(), michael@0: mLineNumber(0), michael@0: mSourceLine(), michael@0: mColumnNumber(0), michael@0: mFlags(0), michael@0: mCategory(), michael@0: mOuterWindowID(0), michael@0: mInnerWindowID(0), michael@0: mTimeStamp(0), michael@0: mIsFromPrivateWindow(false) michael@0: { michael@0: } michael@0: michael@0: nsScriptError::~nsScriptError() {} michael@0: michael@0: // nsIConsoleMessage methods michael@0: NS_IMETHODIMP michael@0: nsScriptError::GetMessageMoz(char16_t **result) { michael@0: nsresult rv; michael@0: michael@0: nsAutoCString message; michael@0: rv = ToString(message); michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: michael@0: *result = UTF8ToNewUnicode(message); michael@0: if (!*result) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: // nsIScriptError methods michael@0: NS_IMETHODIMP michael@0: nsScriptError::GetErrorMessage(nsAString& aResult) { michael@0: aResult.Assign(mMessage); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsScriptError::GetSourceName(nsAString& aResult) { michael@0: aResult.Assign(mSourceName); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsScriptError::GetSourceLine(nsAString& aResult) { michael@0: aResult.Assign(mSourceLine); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsScriptError::GetLineNumber(uint32_t *result) { michael@0: *result = mLineNumber; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsScriptError::GetColumnNumber(uint32_t *result) { michael@0: *result = mColumnNumber; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsScriptError::GetFlags(uint32_t *result) { michael@0: *result = mFlags; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsScriptError::GetCategory(char **result) { michael@0: *result = ToNewCString(mCategory); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsScriptError::Init(const nsAString& message, michael@0: const nsAString& sourceName, michael@0: const nsAString& sourceLine, michael@0: uint32_t lineNumber, michael@0: uint32_t columnNumber, michael@0: uint32_t flags, michael@0: const char *category) michael@0: { michael@0: return InitWithWindowID(message, sourceName, sourceLine, lineNumber, michael@0: columnNumber, flags, michael@0: category ? nsDependentCString(category) michael@0: : EmptyCString(), michael@0: 0); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsScriptError::InitWithWindowID(const nsAString& message, michael@0: const nsAString& sourceName, michael@0: const nsAString& sourceLine, michael@0: uint32_t lineNumber, michael@0: uint32_t columnNumber, michael@0: uint32_t flags, michael@0: const nsACString& category, michael@0: uint64_t aInnerWindowID) michael@0: { michael@0: mMessage.Assign(message); michael@0: mSourceName.Assign(sourceName); michael@0: mLineNumber = lineNumber; michael@0: mSourceLine.Assign(sourceLine); michael@0: mColumnNumber = columnNumber; michael@0: mFlags = flags; michael@0: mCategory = category; michael@0: mTimeStamp = JS_Now() / 1000; michael@0: mInnerWindowID = aInnerWindowID; michael@0: michael@0: if (aInnerWindowID) { michael@0: nsGlobalWindow* window = michael@0: nsGlobalWindow::GetInnerWindowWithId(aInnerWindowID); michael@0: if (window) { michael@0: nsPIDOMWindow* outer = window->GetOuterWindow(); michael@0: if (outer) michael@0: mOuterWindowID = outer->WindowID(); michael@0: michael@0: nsIDocShell* docShell = window->GetDocShell(); michael@0: nsCOMPtr loadContext = do_QueryInterface(docShell); michael@0: michael@0: if (loadContext) { michael@0: // Never mark exceptions from chrome windows as having come from michael@0: // private windows, since we always want them to be reported. michael@0: nsIPrincipal* winPrincipal = window->GetPrincipal(); michael@0: mIsFromPrivateWindow = loadContext->UsePrivateBrowsing() && michael@0: !nsContentUtils::IsSystemPrincipal(winPrincipal); michael@0: } michael@0: michael@0: } michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsScriptError::ToString(nsACString& /*UTF8*/ aResult) michael@0: { michael@0: static const char format0[] = michael@0: "[%s: \"%s\" {file: \"%s\" line: %d column: %d source: \"%s\"}]"; michael@0: static const char format1[] = michael@0: "[%s: \"%s\" {file: \"%s\" line: %d}]"; michael@0: static const char format2[] = michael@0: "[%s: \"%s\"]"; michael@0: michael@0: static const char error[] = "JavaScript Error"; michael@0: static const char warning[] = "JavaScript Warning"; michael@0: michael@0: const char* severity = !(mFlags & JSREPORT_WARNING) ? error : warning; michael@0: michael@0: char* temp; michael@0: char* tempMessage = nullptr; michael@0: char* tempSourceName = nullptr; michael@0: char* tempSourceLine = nullptr; michael@0: michael@0: if (!mMessage.IsEmpty()) michael@0: tempMessage = ToNewUTF8String(mMessage); michael@0: if (!mSourceName.IsEmpty()) michael@0: tempSourceName = ToNewUTF8String(mSourceName); michael@0: if (!mSourceLine.IsEmpty()) michael@0: tempSourceLine = ToNewUTF8String(mSourceLine); michael@0: michael@0: if (nullptr != tempSourceName && nullptr != tempSourceLine) michael@0: temp = JS_smprintf(format0, michael@0: severity, michael@0: tempMessage, michael@0: tempSourceName, michael@0: mLineNumber, michael@0: mColumnNumber, michael@0: tempSourceLine); michael@0: else if (!mSourceName.IsEmpty()) michael@0: temp = JS_smprintf(format1, michael@0: severity, michael@0: tempMessage, michael@0: tempSourceName, michael@0: mLineNumber); michael@0: else michael@0: temp = JS_smprintf(format2, michael@0: severity, michael@0: tempMessage); michael@0: michael@0: if (nullptr != tempMessage) michael@0: nsMemory::Free(tempMessage); michael@0: if (nullptr != tempSourceName) michael@0: nsMemory::Free(tempSourceName); michael@0: if (nullptr != tempSourceLine) michael@0: nsMemory::Free(tempSourceLine); michael@0: michael@0: if (!temp) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: michael@0: aResult.Assign(temp); michael@0: JS_smprintf_free(temp); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsScriptError::GetOuterWindowID(uint64_t *aOuterWindowID) michael@0: { michael@0: *aOuterWindowID = mOuterWindowID; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsScriptError::GetInnerWindowID(uint64_t *aInnerWindowID) michael@0: { michael@0: *aInnerWindowID = mInnerWindowID; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsScriptError::GetTimeStamp(int64_t *aTimeStamp) michael@0: { michael@0: *aTimeStamp = mTimeStamp; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsScriptError::GetIsFromPrivateWindow(bool *aIsFromPrivateWindow) michael@0: { michael@0: *aIsFromPrivateWindow = mIsFromPrivateWindow; michael@0: return NS_OK; michael@0: }