Bug 972312 part 2. Get rid of InternalScriptErrorEvent and just use mozilla::dom::ErrorEvent for the cases that used to use it. r=smaug

This commit is contained in:
Boris Zbarsky 2014-02-23 00:01:12 -05:00
Родитель e0c8cb2f45
Коммит b458b3ad8d
16 изменённых файлов: 181 добавлений и 156 удалений

Просмотреть файл

@ -15,6 +15,12 @@
class nsIScriptContext;
class nsIScriptGlobalObject;
namespace mozilla {
namespace dom {
class ErrorEventInit;
} // namespace dom
} // namespace mozilla
// A helper function for nsIScriptGlobalObject implementations to use
// when handling a script error. Generally called by the global when a context
// notifies it of an error via nsIScriptGlobalObject::HandleScriptError.
@ -22,13 +28,13 @@ class nsIScriptGlobalObject;
// aStatus will be filled in with the status.
bool
NS_HandleScriptError(nsIScriptGlobalObject *aScriptGlobal,
mozilla::InternalScriptErrorEvent *aErrorEvent,
const mozilla::dom::ErrorEventInit &aErrorEvent,
nsEventStatus *aStatus);
#define NS_ISCRIPTGLOBALOBJECT_IID \
{ 0x30c64680, 0x909a, 0x4435, \
{ 0x90, 0x3b, 0x29, 0x3e, 0xb5, 0x5d, 0xc7, 0xa0 } }
{ 0x6995e1ff, 0x9fc5, 0x44a7, \
{ 0xbd, 0x7c, 0xe7, 0xcd, 0x44, 0x47, 0x22, 0x87 } }
/**
* The global object which keeps a script context for each supported script
@ -74,9 +80,9 @@ public:
* Handle a script error. Generally called by a script context.
*/
virtual nsresult HandleScriptError(
mozilla::InternalScriptErrorEvent *aErrorEvent,
const mozilla::dom::ErrorEventInit &aErrorEventInit,
nsEventStatus *aEventStatus) {
NS_ENSURE_STATE(NS_HandleScriptError(this, aErrorEvent, aEventStatus));
NS_ENSURE_STATE(NS_HandleScriptError(this, aErrorEventInit, aEventStatus));
return NS_OK;
}

Просмотреть файл

@ -52,6 +52,8 @@
#include "nsGlobalWindow.h"
#include "nsScriptNameSpaceManager.h"
#include "StructuredCloneTags.h"
#include "mozilla/AutoRestore.h"
#include "mozilla/dom/ErrorEvent.h"
#include "mozilla/dom/ImageData.h"
#include "mozilla/dom/ImageDataBinding.h"
#include "nsAXPCNativeCallContext.h"
@ -312,7 +314,7 @@ private:
// XXXmarkh - This function is mis-placed!
bool
NS_HandleScriptError(nsIScriptGlobalObject *aScriptGlobal,
InternalScriptErrorEvent *aErrorEvent,
const ErrorEventInit &aErrorEventInit,
nsEventStatus *aStatus)
{
bool called = false;
@ -325,11 +327,17 @@ NS_HandleScriptError(nsIScriptGlobalObject *aScriptGlobal,
static int32_t errorDepth; // Recursion prevention
++errorDepth;
if (presContext && errorDepth < 2) {
if (errorDepth < 2) {
// Dispatch() must be synchronous for the recursion block
// (errorDepth) to work.
nsEventDispatcher::Dispatch(win, presContext, aErrorEvent, nullptr,
aStatus);
nsRefPtr<ErrorEvent> event =
ErrorEvent::Constructor(static_cast<nsGlobalWindow*>(win.get()),
NS_LITERAL_STRING("error"),
aErrorEventInit);
event->SetTrusted(true);
nsEventDispatcher::DispatchDOMEvent(win, nullptr, event, presContext,
aStatus);
called = true;
}
--errorDepth;
@ -444,44 +452,47 @@ public:
if (docShell &&
!JSREPORT_IS_WARNING(mFlags) &&
!sHandlingScriptError) {
sHandlingScriptError = true; // Recursion prevention
AutoRestore<bool> recursionGuard(sHandlingScriptError);
sHandlingScriptError = true;
nsRefPtr<nsPresContext> presContext;
docShell->GetPresContext(getter_AddRefs(presContext));
if (presContext) {
InternalScriptErrorEvent errorevent(true, NS_LOAD_ERROR);
ErrorEventInit init;
init.mCancelable = true;
init.mFilename = mFileName;
init.mBubbles = true;
errorevent.fileName = mFileName.get();
nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(win));
NS_ENSURE_STATE(sop);
nsIPrincipal* p = sop->GetPrincipal();
NS_ENSURE_STATE(p);
nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(win));
NS_ENSURE_STATE(sop);
nsIPrincipal* p = sop->GetPrincipal();
NS_ENSURE_STATE(p);
bool sameOrigin = !mOriginPrincipal;
bool sameOrigin = !mOriginPrincipal;
if (p && !sameOrigin) {
if (NS_FAILED(p->Subsumes(mOriginPrincipal, &sameOrigin))) {
sameOrigin = false;
}
if (p && !sameOrigin) {
if (NS_FAILED(p->Subsumes(mOriginPrincipal, &sameOrigin))) {
sameOrigin = false;
}
NS_NAMED_LITERAL_STRING(xoriginMsg, "Script error.");
if (sameOrigin) {
errorevent.errorMsg = mErrorMsg.get();
errorevent.lineNr = mLineNumber;
} else {
NS_WARNING("Not same origin error!");
errorevent.errorMsg = xoriginMsg.get();
errorevent.lineNr = 0;
}
nsEventDispatcher::Dispatch(win, presContext, &errorevent, nullptr,
&status);
}
sHandlingScriptError = false;
NS_NAMED_LITERAL_STRING(xoriginMsg, "Script error.");
if (sameOrigin) {
init.mMessage = mErrorMsg;
init.mLineno = mLineNumber;
} else {
NS_WARNING("Not same origin error!");
init.mMessage = xoriginMsg;
init.mLineno = 0;
}
nsRefPtr<ErrorEvent> event =
ErrorEvent::Constructor(static_cast<nsGlobalWindow*>(win.get()),
NS_LITERAL_STRING("error"), init);
event->SetTrusted(true);
nsEventDispatcher::DispatchDOMEvent(win, nullptr, event, presContext,
&status);
}
}

Просмотреть файл

@ -764,15 +764,6 @@ nsDOMEvent::GetEventPopupControlState(WidgetEvent* aEvent)
}
}
break;
case NS_SCRIPT_ERROR_EVENT :
switch(aEvent->message) {
case NS_LOAD_ERROR :
// Any error event will allow popups, if enabled in the pref.
if (::PopupAllowedForEvent("error"))
abuse = openControlled;
break;
}
break;
case NS_FORM_EVENT :
// For these following events only allow popups if they're
// triggered while handling user input. See

Просмотреть файл

@ -27,6 +27,7 @@ class nsPresContext;
namespace mozilla {
namespace dom {
class EventTarget;
class ErrorEvent;
}
}
@ -90,6 +91,11 @@ public:
return mozilla::dom::EventBinding::Wrap(aCx, aScope, this);
}
virtual mozilla::dom::ErrorEvent* AsErrorEvent()
{
return nullptr;
}
// nsIDOMEvent Interface
NS_DECL_NSIDOMEVENT

Просмотреть файл

@ -19,6 +19,7 @@
#include "nsDOMJSUtils.h"
#include "mozilla/ContentEvents.h"
#include "mozilla/Likely.h"
#include "mozilla/dom/ErrorEvent.h"
#include "mozilla/dom/UnionTypes.h"
#include "nsDOMEvent.h"
@ -167,19 +168,16 @@ nsJSEventListener::HandleEvent(nsIDOMEvent* aEvent)
Optional<uint32_t> columnNumber;
NS_ENSURE_TRUE(aEvent, NS_ERROR_UNEXPECTED);
InternalScriptErrorEvent* scriptEvent =
aEvent->GetInternalNSEvent()->AsScriptErrorEvent();
if (scriptEvent &&
(scriptEvent->message == NS_LOAD_ERROR ||
scriptEvent->typeString.EqualsLiteral("error"))) {
errorMsg = scriptEvent->errorMsg;
ErrorEvent* scriptEvent = aEvent->InternalDOMEvent()->AsErrorEvent();
if (scriptEvent) {
scriptEvent->GetMessage(errorMsg);
msgOrEvent.SetAsString().SetData(errorMsg.Data(), errorMsg.Length());
file = scriptEvent->fileName;
scriptEvent->GetFilename(file);
fileName = &file;
lineNumber.Construct();
lineNumber.Value() = scriptEvent->lineNr;
lineNumber.Value() = scriptEvent->Lineno();
} else {
msgOrEvent.SetAsEvent() = aEvent->InternalDOMEvent();
}

Просмотреть файл

@ -0,0 +1,15 @@
addEventListener("error", function(e) {
var obj = {};
for (var prop of ["message", "filename", "lineno"]) {
obj[prop] = e[prop]
}
obj.type = "event";
postMessage(obj);
});
onerror = function(message, filename, lineno) {
var obj = { message: message, filename: filename, lineno: lineno,
type: "callback" }
postMessage(obj);
return false;
}
throw new Error("workerhello");

Просмотреть файл

@ -6,6 +6,7 @@ support-files =
bug426082.html
bug457672.html
bug656379-1.html
error_event_worker.js
empty.js
window_bug493251.html
window_bug659071.html
@ -130,6 +131,7 @@ skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
[test_draggableprop.html]
skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
[test_dragstart.html]
[test_error_events.html]
skip-if = toolkit == 'android' #TIMED_OUT
[test_eventctors.html]
skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM

Просмотреть файл

@ -0,0 +1,62 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Test for error events being ErrorEvent</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
var errorEvent;
var file;
var line;
var msg;
window.addEventListener("error", function errorListener(e) {
window.removeEventListener("error", errorListener);
errorEvent = e;
});
var oldOnerror = window.onerror;
window.onerror = function(message, filename, lineno) {
window.onerror = oldOnerror;
file = filename;
line = lineno;
msg = message;
}
throw new Error("hello");
</script>
<script>
generate_tests(assert_equals, [
[ "Event filename", errorEvent.filename, location.href ],
[ "Callback filename", file, location.href ],
[ "Event line number", errorEvent.lineno, 23 ],
[ "Callback line number", line, 23 ],
[ "Event message", errorEvent.message, "Error: hello" ],
[ "Callback message", msg, "Error: hello" ]
]);
</script>
<script>
var workerLocation = location.protocol + "//" + location.host +
location.pathname.replace("test_error_events.html", "error_event_worker.js");
var eventFileTest = async_test("Worker event filename");
var eventLineTest = async_test("Worker event line number");
var eventMessageTest = async_test("Worker event message");
var callbackFileTest = async_test("Worker callback filename");
var callbackLineTest = async_test("Worker callback line number");
var callbackMessageTest = async_test("Worker callback message");
var w = new Worker("error_event_worker.js");
w.addEventListener("message", function(msg) {
if (msg.data.type == "event") {
eventFileTest.step(function() { assert_equals(msg.data.filename, workerLocation); });
eventFileTest.done();
eventLineTest.step(function() { assert_equals(msg.data.lineno, 15); });
eventLineTest.done();
eventMessageTest.step(function() { assert_equals(msg.data.message, "Error: workerhello"); });
eventMessageTest.done();
} else {
callbackFileTest.step(function() { assert_equals(msg.data.filename, workerLocation); });
callbackFileTest.done();
callbackLineTest.step(function() { assert_equals(msg.data.lineno, 15); });
callbackLineTest.done();
callbackMessageTest.step(function() { assert_equals(msg.data.message, "Error: workerhello"); });
callbackMessageTest.done();
}
});
</script>

Просмотреть файл

@ -9,6 +9,7 @@
#include "nsIScriptContext.h"
#include "mozilla/ContentEvents.h"
#include "mozilla/dom/ErrorEventBinding.h"
#include "mozilla/dom/IDBOpenDBRequestBinding.h"
#include "mozilla/dom/UnionTypes.h"
#include "nsComponentManagerUtils.h"
@ -300,10 +301,10 @@ IDBRequest::CaptureCaller()
}
void
IDBRequest::FillScriptErrorEvent(InternalScriptErrorEvent* aEvent) const
IDBRequest::FillScriptErrorEvent(ErrorEventInit& aEventInit) const
{
aEvent->lineNr = mLineNo;
aEvent->fileName = mFilename.get();
aEventInit.mLineno = mLineNo;
aEventInit.mFilename = mFilename;
}
mozilla::dom::IDBRequestReadyState

Просмотреть файл

@ -25,6 +25,7 @@ class nsPIDOMWindow;
namespace mozilla {
namespace dom {
class OwningIDBObjectStoreOrIDBIndexOrIDBCursor;
class ErrorEventInit;
}
}
@ -101,7 +102,7 @@ public:
void CaptureCaller();
void FillScriptErrorEvent(mozilla::InternalScriptErrorEvent* aEvent) const;
void FillScriptErrorEvent(ErrorEventInit& aEventInit) const;
bool
IsPending() const

Просмотреть файл

@ -17,6 +17,7 @@
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/CondVar.h"
#include "mozilla/ContentEvents.h"
#include "mozilla/dom/ErrorEventBinding.h"
#include "mozilla/dom/quota/OriginOrPatternString.h"
#include "mozilla/dom/quota/QuotaManager.h"
#include "mozilla/dom/quota/Utilities.h"
@ -340,19 +341,18 @@ IndexedDatabaseManager::FireWindowOnError(nsPIDOMWindow* aOwner,
error->GetName(errorName);
}
mozilla::InternalScriptErrorEvent event(true, NS_LOAD_ERROR);
request->FillScriptErrorEvent(&event);
NS_ABORT_IF_FALSE(event.fileName,
"FillScriptErrorEvent should give us a non-null string "
"for our error's fileName");
ErrorEventInit init;
request->FillScriptErrorEvent(init);
event.errorMsg = errorName.get();
init.mMessage = errorName;
init.mCancelable = true;
init.mBubbles = true;
nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryInterface(aOwner));
NS_ASSERTION(sgo, "How can this happen?!");
nsEventStatus status = nsEventStatus_eIgnore;
if (NS_FAILED(sgo->HandleScriptError(&event, &status))) {
if (NS_FAILED(sgo->HandleScriptError(init, &status))) {
NS_WARNING("Failed to dispatch script error event");
status = nsEventStatus_eIgnore;
}
@ -368,8 +368,8 @@ IndexedDatabaseManager::FireWindowOnError(nsPIDOMWindow* aOwner,
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(scriptError->InitWithWindowID(errorName,
nsDependentString(event.fileName),
EmptyString(), event.lineNr,
init.mFilename,
EmptyString(), init.mLineno,
0, 0,
"IndexedDB",
aOwner->WindowID()))) {

Просмотреть файл

@ -1186,16 +1186,16 @@ public:
// they show up in the error console.
if (!JSREPORT_IS_WARNING(aFlags)) {
// First fire an ErrorEvent at the worker.
if (aTarget) {
ErrorEventInit init;
init.mMessage = aMessage;
init.mFilename = aFilename;
init.mLineno = aLineNumber;
init.mCancelable = true;
ErrorEventInit init;
init.mMessage = aMessage;
init.mFilename = aFilename;
init.mLineno = aLineNumber;
init.mCancelable = true;
init.mBubbles = true;
if (aTarget) {
nsRefPtr<ErrorEvent> event =
ErrorEvent::Constructor(aTarget, NS_LITERAL_STRING("error"), init);
event->SetTrusted(true);
nsEventStatus status = nsEventStatus_eIgnore;
@ -1219,30 +1219,22 @@ public:
WorkerGlobalScope* globalTarget = aWorkerPrivate->GlobalScope();
MOZ_ASSERT(target == globalTarget->GetWrapperPreserveColor());
// Icky, we have to fire an InternalScriptErrorEvent...
MOZ_ASSERT(!NS_IsMainThread());
InternalScriptErrorEvent event(true, NS_USER_DEFINED_EVENT);
event.lineNr = aLineNumber;
event.errorMsg = aMessage.get();
event.fileName = aFilename.get();
event.typeString = NS_LITERAL_STRING("error");
nsRefPtr<ErrorEvent> event =
ErrorEvent::Constructor(aTarget, NS_LITERAL_STRING("error"), init);
event->SetTrusted(true);
nsIDOMEventTarget* target = static_cast<nsIDOMEventTarget*>(globalTarget);
if (NS_FAILED(nsEventDispatcher::Dispatch(target, nullptr, &event,
nullptr, &status))) {
if (NS_FAILED(nsEventDispatcher::DispatchDOMEvent(target, nullptr,
event, nullptr,
&status))) {
NS_WARNING("Failed to dispatch worker thread error event!");
status = nsEventStatus_eIgnore;
}
}
else if ((sgo = nsJSUtils::GetStaticScriptGlobal(target))) {
// Icky, we have to fire an InternalScriptErrorEvent...
MOZ_ASSERT(NS_IsMainThread());
InternalScriptErrorEvent event(true, NS_LOAD_ERROR);
event.lineNr = aLineNumber;
event.errorMsg = aMessage.get();
event.fileName = aFilename.get();
if (NS_FAILED(sgo->HandleScriptError(&event, &status))) {
if (NS_FAILED(sgo->HandleScriptError(init, &status))) {
NS_WARNING("Failed to dispatch main thread error event!");
status = nsEventStatus_eIgnore;
}
@ -3193,13 +3185,15 @@ WorkerPrivateParent<Derived>::BroadcastErrorToSharedWorkers(
MOZ_ASSERT(sgo);
MOZ_ASSERT(NS_IsMainThread());
InternalScriptErrorEvent event(true, NS_LOAD_ERROR);
event.lineNr = aLineNumber;
event.errorMsg = aMessage.BeginReading();
event.fileName = aFilename.BeginReading();
ErrorEventInit init;
init.mLineno = aLineNumber;
init.mFilename = aFilename;
init.mMessage = aMessage;
init.mCancelable = true;
init.mBubbles = true;
nsEventStatus status = nsEventStatus_eIgnore;
rv = sgo->HandleScriptError(&event, &status);
rv = sgo->HandleScriptError(init, &status);
if (NS_FAILED(rv)) {
Throw(cx, rv);
JS_ReportPendingException(cx);

Просмотреть файл

@ -49,7 +49,6 @@ enum nsEventStructType
NS_TOUCH_EVENT, // WidgetTouchEvent
// ContentEvents.h
NS_SCRIPT_ERROR_EVENT, // InternalScriptErrorEvent
NS_SCROLLPORT_EVENT, // InternalScrollPortEvent
NS_SCROLLAREA_EVENT, // InternalScrollAreaEvent
NS_FORM_EVENT, // InternalFormEvent

Просмотреть файл

@ -19,55 +19,6 @@ class nsIContent;
namespace mozilla {
/******************************************************************************
* mozilla::InternalScriptErrorEvent
******************************************************************************/
class InternalScriptErrorEvent : public WidgetEvent
{
public:
virtual InternalScriptErrorEvent* AsScriptErrorEvent() MOZ_OVERRIDE
{
return this;
}
InternalScriptErrorEvent(bool aIsTrusted, uint32_t aMessage) :
WidgetEvent(aIsTrusted, aMessage, NS_SCRIPT_ERROR_EVENT),
lineNr(0), errorMsg(nullptr), fileName(nullptr)
{
}
virtual WidgetEvent* Duplicate() const MOZ_OVERRIDE
{
MOZ_ASSERT(eventStructType == NS_SCRIPT_ERROR_EVENT,
"Duplicate() must be overridden by sub class");
InternalScriptErrorEvent* result =
new InternalScriptErrorEvent(false, message);
result->AssignScriptErrorEventData(*this, true);
result->mFlags = mFlags;
return result;
}
int32_t lineNr;
const char16_t* errorMsg;
const char16_t* fileName;
// XXX Not tested by test_assign_event_data.html
void AssignScriptErrorEventData(const InternalScriptErrorEvent& aEvent,
bool aCopyTargets)
{
AssignEventData(aEvent, aCopyTargets);
lineNr = aEvent.lineNr;
// We don't copy errorMsg and fileName. If it's necessary, perhaps, this
// should duplicate the characters and free them at destructing.
errorMsg = nullptr;
fileName = nullptr;
}
};
/******************************************************************************
* mozilla::InternalScrollPortEvent
******************************************************************************/

Просмотреть файл

@ -41,7 +41,6 @@ NS_EVENT_CLASS(Widget, SimpleGestureEvent)
NS_EVENT_CLASS(Widget, TouchEvent)
// ContentEvents.h
NS_EVENT_CLASS(Internal, ScriptErrorEvent)
NS_EVENT_CLASS(Internal, ScrollPortEvent)
NS_EVENT_CLASS(Internal, ScrollAreaEvent)
NS_EVENT_CLASS(Internal, FormEvent)

Просмотреть файл

@ -74,17 +74,6 @@ function onEvent(aEvent)
}
const kTests = [
{ description: "InternalScriptErrorEvent",
targetID: "input-text", eventType: "error",
dispatchEvent: function () {
return;
},
canRun: function () {
todo(false, "InternalScriptErrorEvent isn't tested");
return false;
},
todoMismatch: [],
},
{ description: "InternalScrollPortEvent (overflow, vertical)",
targetID: "scrollable-div", eventType: "overflow",
dispatchEvent: function () {