2010-12-13 Yury Semikhatsky <yurys@chromium.org>
authoryurys@chromium.org <yurys@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 13 Dec 2010 15:16:03 +0000 (15:16 +0000)
committeryurys@chromium.org <yurys@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 13 Dec 2010 15:16:03 +0000 (15:16 +0000)
        Reviewed by Adam Barth.

        WebCore doesn't fire window.onerror event when uncaught JavaScript exceptions are thrown
        https://bugs.webkit.org/show_bug.cgi?id=8519

        Uncaught exceptions are propagated to window.onerror hander if one is present.
        The handler is expected to be a function accepting three arguments: error message,
        resource url and line number where the exception occured.

        * fast/events/resources/window-onerror.js: Added.
        (throwException):
        * fast/events/window-onerror1-expected.txt: Added.
        * fast/events/window-onerror1.html: Added.
        * fast/events/window-onerror10-expected.txt: Added.
        * fast/events/window-onerror10.html: Added.
        * fast/events/window-onerror11-expected.txt: Added.
        * fast/events/window-onerror11.html: Added.
        * fast/events/window-onerror2-expected.txt: Added.
        * fast/events/window-onerror2.html: Added.
        * fast/events/window-onerror3-expected.txt: Added.
        * fast/events/window-onerror3.html: Added.
        * fast/events/window-onerror4-expected.txt: Added.
        * fast/events/window-onerror4.html: Added.
        * fast/events/window-onerror5-expected.txt: Added.
        * fast/events/window-onerror5.html: Added.
        * fast/events/window-onerror6-expected.txt: Added.
        * fast/events/window-onerror6.html: Added.
        * fast/events/window-onerror7-expected.txt: Added.
        * fast/events/window-onerror7.html: Added.
        * fast/events/window-onerror8-expected.txt: Added.
        * fast/events/window-onerror8.html: Added.
        * fast/events/window-onerror9-expected.txt: Added.
        * fast/events/window-onerror9.html: Added.
        * fast/workers/worker-script-error-expected.txt:
        * http/tests/security/resources/onerror-iframe.html: Added.
        * http/tests/security/window-onerror-exception-in-iframe-expected.txt: Added.
        * http/tests/security/window-onerror-exception-in-iframe.html: Added.
        * platform/chromium-win/fast/workers/worker-script-error-expected.txt:
        * platform/chromium/fast/events/window-onerror1-expected.txt: Added.
        * platform/chromium/fast/events/window-onerror10-expected.txt: Added.
        * platform/chromium/fast/events/window-onerror11-expected.txt: Added.
        * platform/chromium/fast/events/window-onerror2-expected.txt: Added.
        * platform/chromium/fast/events/window-onerror3-expected.txt: Added.
        * platform/chromium/fast/events/window-onerror4-expected.txt: Added.
        * platform/chromium/fast/events/window-onerror5-expected.txt: Added.
        * platform/chromium/fast/events/window-onerror6-expected.txt: Added.
        * platform/chromium/fast/events/window-onerror7-expected.txt: Added.
        * platform/chromium/fast/events/window-onerror8-expected.txt: Added.
        * platform/chromium/fast/events/window-onerror9-expected.txt: Added.
        * platform/chromium/http/tests/security/window-onerror-exception-in-iframe-expected.txt: Added.
        * platform/chromium/userscripts/window-onerror-for-isolated-world-1-expected.txt: Added.
        * platform/chromium/userscripts/window-onerror-for-isolated-world-2-expected.txt: Added.
        * userscripts/window-onerror-for-isolated-world-1-expected.txt: Added.
        * userscripts/window-onerror-for-isolated-world-1.html: Added.
        * userscripts/window-onerror-for-isolated-world-2-expected.txt: Added.
        * userscripts/window-onerror-for-isolated-world-2.html: Added.
2010-12-13  Yury Semikhatsky  <yurys@chromium.org>

        Reviewed by Adam Barth.

        WebCore doesn't fire window.onerror event when uncaught JavaScript exceptions are thrown
        https://bugs.webkit.org/show_bug.cgi?id=8519

        Uncaught exceptions are propagated to window.onerror hander if one is present.
        The handler is expected to be a function accepting three arguments: error message,
        resource url and line number where the exception occured.

        It was decided to dispatch ErrorEvent to all listeners/handlers no matter if they
        were created in the same isolated world where the exception occured or not.

        Tests: fast/events/window-onerror1.html
               fast/events/window-onerror10.html
               fast/events/window-onerror11.html
               fast/events/window-onerror2.html
               fast/events/window-onerror3.html
               fast/events/window-onerror4.html
               fast/events/window-onerror5.html
               fast/events/window-onerror6.html
               fast/events/window-onerror7.html
               fast/events/window-onerror8.html
               fast/events/window-onerror9.html
               http/tests/security/window-onerror-exception-in-iframe.html
               userscripts/window-onerror-for-isolated-world-1.html
               userscripts/window-onerror-for-isolated-world-2.html

        * Android.jscbindings.mk:
        * CMakeLists.txt:
        * GNUmakefile.am:
        * WebCore.gypi:
        * WebCore.order:
        * WebCore.pro:
        * WebCore.vcproj/WebCore.vcproj:
        * WebCore.xcodeproj/project.pbxproj:
        * bindings/js/JSBindingsAllInOne.cpp:
        * bindings/js/JSDOMBinding.cpp:
        (WebCore::reportException):
        * bindings/js/JSErrorHandler.cpp: Renamed from WebCore/bindings/js/JSWorkerContextErrorHandler.cpp.
        (WebCore::JSErrorHandler::JSErrorHandler):
        (WebCore::JSErrorHandler::~JSErrorHandler):
        (WebCore::JSErrorHandler::handleEvent):
        * bindings/js/JSErrorHandler.h: Copied from WebCore/bindings/js/JSWorkerContextErrorHandler.h.
        (WebCore::JSErrorHandler::create):
        (WebCore::createJSErrorHandler):
        * bindings/scripts/CodeGeneratorJS.pm:
        * bindings/scripts/CodeGeneratorV8.pm:
        * bindings/v8/V8ConsoleMessage.cpp:
        (WebCore::V8ConsoleMessage::dispatchNow):
        (WebCore::V8ConsoleMessage::handler): the method was changed to use generic WebCore exception
        reporting mechanism which is also used by JSC bindings.
        * bindings/v8/V8ConsoleMessage.h:
        * bindings/v8/V8WindowErrorHandler.cpp: Copied from WebCore/bindings/js/JSWorkerContextErrorHandler.h.
        (WebCore::V8WindowErrorHandler::V8WindowErrorHandler):
        (WebCore::V8WindowErrorHandler::callListenerFunction):
        * bindings/v8/V8WindowErrorHandler.h: Renamed from WebCore/bindings/js/JSWorkerContextErrorHandler.h.
        (WebCore::V8WindowErrorHandler::create):
        * bindings/v8/WorkerContextExecutionProxy.cpp:
        (WebCore::v8MessageHandler):
        * bindings/v8/WorkerScriptController.cpp:
        (WebCore::WorkerScriptController::evaluate):
        * dom/Document.cpp:
        (WebCore::Document::errorEventTarget):
        (WebCore::Document::logExceptionToConsole):
        * dom/Document.h:
        * dom/ScriptExecutionContext.cpp:
        (WebCore::ScriptExecutionContext::PendingException::PendingException):
        (WebCore::ScriptExecutionContext::ScriptExecutionContext):
        (WebCore::ScriptExecutionContext::reportException): this method is not virtual anymore to
        ensure that error event dispatching algorithm is the same in WorkerContext and in Document.
        (WebCore::ScriptExecutionContext::dispatchErrorEvent):
        * dom/ScriptExecutionContext.h:
        * workers/DefaultSharedWorkerRepository.cpp:
        (WebCore::postExceptionTask):
        * workers/WorkerContext.cpp:
        (WebCore::WorkerContext::WorkerContext):
        (WebCore::WorkerContext::errorEventTarget):
        (WebCore::WorkerContext::logExceptionToConsole):
        * workers/WorkerContext.h:
        * workers/WorkerMessagingProxy.cpp:
        (WebCore::WorkerExceptionTask::performTask):
2010-12-13  Yury Semikhatsky  <yurys@chromium.org>

        Reviewed by Adam Barth.

        WebCore doesn't fire window.onerror event when uncaught JavaScript exceptions are thrown
        https://bugs.webkit.org/show_bug.cgi?id=8519

        Uncaught exceptions are propagated to window.onerror hander if one is present.
        The handler is expected to be a function accepting three arguments: error message,
        resource url and line number where the exception occured.

        * src/WebWorkerClientImpl.cpp:
        (WebKit::WebWorkerClientImpl::postExceptionToWorkerObject):
        (WebKit::WebWorkerClientImpl::postExceptionToWorkerObjectTask):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@73914 268f45cc-cd09-0410-ab3c-d52691b4dbfc

83 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/events/resources/window-onerror.js [new file with mode: 0644]
LayoutTests/fast/events/window-onerror1-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/window-onerror1.html [new file with mode: 0644]
LayoutTests/fast/events/window-onerror10-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/window-onerror10.html [new file with mode: 0644]
LayoutTests/fast/events/window-onerror11-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/window-onerror11.html [new file with mode: 0644]
LayoutTests/fast/events/window-onerror2-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/window-onerror2.html [new file with mode: 0644]
LayoutTests/fast/events/window-onerror3-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/window-onerror3.html [new file with mode: 0644]
LayoutTests/fast/events/window-onerror4-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/window-onerror4.html [new file with mode: 0644]
LayoutTests/fast/events/window-onerror5-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/window-onerror5.html [new file with mode: 0644]
LayoutTests/fast/events/window-onerror6-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/window-onerror6.html [new file with mode: 0644]
LayoutTests/fast/events/window-onerror7-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/window-onerror7.html [new file with mode: 0644]
LayoutTests/fast/events/window-onerror8-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/window-onerror8.html [new file with mode: 0644]
LayoutTests/fast/events/window-onerror9-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/window-onerror9.html [new file with mode: 0644]
LayoutTests/fast/workers/worker-script-error-expected.txt
LayoutTests/http/tests/security/resources/onerror-iframe.html [new file with mode: 0644]
LayoutTests/http/tests/security/window-onerror-exception-in-iframe-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/window-onerror-exception-in-iframe.html [new file with mode: 0644]
LayoutTests/platform/chromium-win/fast/workers/worker-script-error-expected.txt
LayoutTests/platform/chromium/fast/events/window-onerror1-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/fast/events/window-onerror10-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/fast/events/window-onerror11-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/fast/events/window-onerror2-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/fast/events/window-onerror3-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/fast/events/window-onerror4-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/fast/events/window-onerror5-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/fast/events/window-onerror6-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/fast/events/window-onerror7-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/fast/events/window-onerror8-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/fast/events/window-onerror9-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/http/tests/security/window-onerror-exception-in-iframe-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/userscripts/window-onerror-for-isolated-world-1-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/userscripts/window-onerror-for-isolated-world-2-expected.txt [new file with mode: 0644]
LayoutTests/platform/gtk/Skipped
LayoutTests/userscripts/window-onerror-for-isolated-world-1-expected.txt [new file with mode: 0644]
LayoutTests/userscripts/window-onerror-for-isolated-world-1.html [new file with mode: 0644]
LayoutTests/userscripts/window-onerror-for-isolated-world-2-expected.txt [new file with mode: 0644]
LayoutTests/userscripts/window-onerror-for-isolated-world-2.html [new file with mode: 0644]
WebCore/Android.jscbindings.mk
WebCore/CMakeLists.txt
WebCore/ChangeLog
WebCore/GNUmakefile.am
WebCore/WebCore.gypi
WebCore/WebCore.order
WebCore/WebCore.pro
WebCore/WebCore.vcproj/WebCore.vcproj
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/bindings/js/JSBindingsAllInOne.cpp
WebCore/bindings/js/JSDOMBinding.cpp
WebCore/bindings/js/JSErrorHandler.cpp [moved from WebCore/bindings/js/JSWorkerContextErrorHandler.cpp with 86% similarity]
WebCore/bindings/js/JSErrorHandler.h [moved from WebCore/bindings/js/JSWorkerContextErrorHandler.h with 69% similarity]
WebCore/bindings/scripts/CodeGeneratorJS.pm
WebCore/bindings/scripts/CodeGeneratorV8.pm
WebCore/bindings/v8/V8ConsoleMessage.cpp
WebCore/bindings/v8/V8ConsoleMessage.h
WebCore/bindings/v8/V8WindowErrorHandler.cpp [new file with mode: 0755]
WebCore/bindings/v8/V8WindowErrorHandler.h [new file with mode: 0755]
WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
WebCore/bindings/v8/WorkerScriptController.cpp
WebCore/dom/Document.cpp
WebCore/dom/Document.h
WebCore/dom/ScriptExecutionContext.cpp
WebCore/dom/ScriptExecutionContext.h
WebCore/websockets/WebSocket.cpp
WebCore/websockets/WebSocketChannel.cpp
WebCore/websockets/WebSocketHandshake.cpp
WebCore/workers/DefaultSharedWorkerRepository.cpp
WebCore/workers/WorkerContext.cpp
WebCore/workers/WorkerContext.h
WebCore/workers/WorkerMessagingProxy.cpp
WebCore/xml/XMLHttpRequest.cpp
WebKit/chromium/ChangeLog
WebKit/chromium/src/WebWorkerClientImpl.cpp

index a58f503..551a284 100644 (file)
@@ -1,3 +1,62 @@
+2010-12-13  Yury Semikhatsky  <yurys@chromium.org>
+
+        Reviewed by Adam Barth.
+
+        WebCore doesn't fire window.onerror event when uncaught JavaScript exceptions are thrown
+        https://bugs.webkit.org/show_bug.cgi?id=8519
+
+        Uncaught exceptions are propagated to window.onerror hander if one is present.
+        The handler is expected to be a function accepting three arguments: error message,
+        resource url and line number where the exception occured.
+
+        * fast/events/resources/window-onerror.js: Added.
+        (throwException):
+        * fast/events/window-onerror1-expected.txt: Added.
+        * fast/events/window-onerror1.html: Added.
+        * fast/events/window-onerror10-expected.txt: Added.
+        * fast/events/window-onerror10.html: Added.
+        * fast/events/window-onerror11-expected.txt: Added.
+        * fast/events/window-onerror11.html: Added.
+        * fast/events/window-onerror2-expected.txt: Added.
+        * fast/events/window-onerror2.html: Added.
+        * fast/events/window-onerror3-expected.txt: Added.
+        * fast/events/window-onerror3.html: Added.
+        * fast/events/window-onerror4-expected.txt: Added.
+        * fast/events/window-onerror4.html: Added.
+        * fast/events/window-onerror5-expected.txt: Added.
+        * fast/events/window-onerror5.html: Added.
+        * fast/events/window-onerror6-expected.txt: Added.
+        * fast/events/window-onerror6.html: Added.
+        * fast/events/window-onerror7-expected.txt: Added.
+        * fast/events/window-onerror7.html: Added.
+        * fast/events/window-onerror8-expected.txt: Added.
+        * fast/events/window-onerror8.html: Added.
+        * fast/events/window-onerror9-expected.txt: Added.
+        * fast/events/window-onerror9.html: Added.
+        * fast/workers/worker-script-error-expected.txt:
+        * http/tests/security/resources/onerror-iframe.html: Added.
+        * http/tests/security/window-onerror-exception-in-iframe-expected.txt: Added.
+        * http/tests/security/window-onerror-exception-in-iframe.html: Added.
+        * platform/chromium-win/fast/workers/worker-script-error-expected.txt:
+        * platform/chromium/fast/events/window-onerror1-expected.txt: Added.
+        * platform/chromium/fast/events/window-onerror10-expected.txt: Added.
+        * platform/chromium/fast/events/window-onerror11-expected.txt: Added.
+        * platform/chromium/fast/events/window-onerror2-expected.txt: Added.
+        * platform/chromium/fast/events/window-onerror3-expected.txt: Added.
+        * platform/chromium/fast/events/window-onerror4-expected.txt: Added.
+        * platform/chromium/fast/events/window-onerror5-expected.txt: Added.
+        * platform/chromium/fast/events/window-onerror6-expected.txt: Added.
+        * platform/chromium/fast/events/window-onerror7-expected.txt: Added.
+        * platform/chromium/fast/events/window-onerror8-expected.txt: Added.
+        * platform/chromium/fast/events/window-onerror9-expected.txt: Added.
+        * platform/chromium/http/tests/security/window-onerror-exception-in-iframe-expected.txt: Added.
+        * platform/chromium/userscripts/window-onerror-for-isolated-world-1-expected.txt: Added.
+        * platform/chromium/userscripts/window-onerror-for-isolated-world-2-expected.txt: Added.
+        * userscripts/window-onerror-for-isolated-world-1-expected.txt: Added.
+        * userscripts/window-onerror-for-isolated-world-1.html: Added.
+        * userscripts/window-onerror-for-isolated-world-2-expected.txt: Added.
+        * userscripts/window-onerror-for-isolated-world-2.html: Added.
+
 2010-12-08  Alexander Pavlov  <apavlov@chromium.org>
 
         Reviewed by Joseph Pecoraro.
diff --git a/LayoutTests/fast/events/resources/window-onerror.js b/LayoutTests/fast/events/resources/window-onerror.js
new file mode 100644 (file)
index 0000000..344574b
--- /dev/null
@@ -0,0 +1,3 @@
+function throwException() {
+    throw new Error("An exception");
+}
diff --git a/LayoutTests/fast/events/window-onerror1-expected.txt b/LayoutTests/fast/events/window-onerror1-expected.txt
new file mode 100644 (file)
index 0000000..fe51b72
--- /dev/null
@@ -0,0 +1,3 @@
+This page tests setting onerror handlers through the DOM. If it passes, you will see "PASS" messages below.Bug 8519.
+
+PASS: caught global error: ReferenceError: Can't find variable: hahaha_good_luck_finding_me at window-onerror1.html:25
diff --git a/LayoutTests/fast/events/window-onerror1.html b/LayoutTests/fast/events/window-onerror1.html
new file mode 100644 (file)
index 0000000..59d2495
--- /dev/null
@@ -0,0 +1,35 @@
+<html>
+<head>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+function print(message, color)
+{
+    var paragraph = document.createElement("div");
+    paragraph.appendChild(document.createTextNode(message));
+    paragraph.style.fontFamily = "monospace";
+    if (color)
+        paragraph.style.color = color;
+    document.getElementById("console").appendChild(paragraph);
+}
+
+function test()
+{
+    // must be last because the exception ends JavaScript execution
+    window.onerror = function (error, url, line) {
+        url = url ? url.match( /[^\/]+\/?$/ )[0] : url;
+        print("PASS: caught global error: " + error + " at " + url + ":" + line, "green");
+        return false;
+    };
+    hahaha_good_luck_finding_me(); // caught by window.onerror
+}
+</script>
+</head>
+<body onload="test();">
+<p>This page tests setting onerror handlers through the DOM. If it passes, you will
+   see "PASS" messages below.<a href="https://bugs.webkit.org/show_bug.cgi?id=8519">Bug 8519</a>.</p>
+<hr>
+<div id='console'></div>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/window-onerror10-expected.txt b/LayoutTests/fast/events/window-onerror10-expected.txt
new file mode 100644 (file)
index 0000000..bff5636
--- /dev/null
@@ -0,0 +1,11 @@
+Test that "error" event listener added with window.addEventListener is invoked for uncaucht exceptions. Bug 8519.
+
+event passed to the listener is the same as window.event: true
+Event details:
+type: error
+phase: 2
+currentTarget is the global object: true
+message: Error: My fault.
+filename: window-onerror10.html
+lineno: 29
+
diff --git a/LayoutTests/fast/events/window-onerror10.html b/LayoutTests/fast/events/window-onerror10.html
new file mode 100644 (file)
index 0000000..26ed018
--- /dev/null
@@ -0,0 +1,33 @@
+<html>
+<body>
+<p>Test that "error" event listener added with window.addEventListener is invoked for uncaucht exceptions. <a href="https://bugs.webkit.org/show_bug.cgi?id=8519">Bug 8519</a>.</p>
+<div id="console"></div>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+function log(msg) {
+    document.getElementById("console").innerHTML += msg + "<br>";
+}
+
+function lastPathComponent(url) {
+    return url ? url.match( /[^\/]+\/?$/ )[0] : url;
+}
+
+window.addEventListener("error", function(e) {
+    log("event passed to the listener is the same as window.event: " + (window.event === e));
+    log("Event details:");
+    log("type: " + e.type);
+    log("phase: " + e.eventPhase)
+    log("currentTarget is the global object: " + (e.currentTarget === window));
+    log("message: " + e.message);
+    log("filename: " + lastPathComponent(e.filename));
+    log("lineno: " + e.lineno);
+    e.preventDefault();
+}, false);
+
+throw new Error("My fault.");
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/window-onerror11-expected.txt b/LayoutTests/fast/events/window-onerror11-expected.txt
new file mode 100644 (file)
index 0000000..96e20cc
--- /dev/null
@@ -0,0 +1,4 @@
+Test that window.onerror is called on window object. Bug 8519.
+
+Main frame window.onerror: Error: An exception at window-onerror.js:2
+
diff --git a/LayoutTests/fast/events/window-onerror11.html b/LayoutTests/fast/events/window-onerror11.html
new file mode 100644 (file)
index 0000000..7655fa7
--- /dev/null
@@ -0,0 +1,28 @@
+<html>
+<head>
+<script src="resources/window-onerror.js">
+</script>
+</head>
+<body>
+<p>Test that window.onerror is called on window object. <a href="https://bugs.webkit.org/show_bug.cgi?id=8519">Bug 8519</a>.</p>
+<div id="console"></div>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+function log(msg) {
+    document.getElementById("console").innerHTML += msg + "<br>";
+}
+
+window.onerror = function(msg, url, line)
+{
+    url = url ? url.match( /[^\/]+\/?$/ )[0] : url;
+    log("Main frame window.onerror: " + msg + " at " + url + ":" + line);
+    return false;
+}
+
+throwException();
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/window-onerror2-expected.txt b/LayoutTests/fast/events/window-onerror2-expected.txt
new file mode 100644 (file)
index 0000000..93a2d3f
--- /dev/null
@@ -0,0 +1,6 @@
+Test that uncaught exceptions will be reported to the window.onerror handler. Bug 8519.
+
+Main frame window.onerror: Error: Inline script exception at window-onerror2.html:35
+Main frame window.onerror: Exception in onload at undefined:0
+Main frame window.onerror: Error: Exception in setTimeout at window-onerror2.html:29
+
diff --git a/LayoutTests/fast/events/window-onerror2.html b/LayoutTests/fast/events/window-onerror2.html
new file mode 100644 (file)
index 0000000..db9fb75
--- /dev/null
@@ -0,0 +1,41 @@
+<html>
+<body onload="throw 'Exception in onload';">
+<p>Test that uncaught exceptions will be reported to the window.onerror handler. <a href="https://bugs.webkit.org/show_bug.cgi?id=8519">Bug 8519</a>.</p>
+<div id="result"></div>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+
+function log(msg) {
+    document.getElementById("result").innerHTML += msg + "<br>";
+}
+
+var unhandledErrorCount = 0;
+window.onerror = function(msg, url, line)
+{
+    url = url ? url.match( /[^\/]+\/?$/ )[0] : url;
+    log("Main frame window.onerror: " + msg + " at " + url + ":" + line);
+    
+    if (++unhandledErrorCount === 3 && window.layoutTestController)
+        layoutTestController.notifyDone();
+
+    return false;
+}
+
+function delayedThrowException()
+{
+    throw new Error("Exception in setTimeout");
+}
+setTimeout(delayedThrowException, 0);
+
+function throwException()
+{
+    throw new Error("Inline script exception");
+}
+throwException();
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/window-onerror3-expected.txt b/LayoutTests/fast/events/window-onerror3-expected.txt
new file mode 100644 (file)
index 0000000..7025dbb
--- /dev/null
@@ -0,0 +1,4 @@
+You should see a message if window.onerror is working properly for this test.Bug 8519.
+
+Error caught successfully: ReferenceError: Can't find variable: unknownObject File: window-onerror3.html Line: 16
+
diff --git a/LayoutTests/fast/events/window-onerror3.html b/LayoutTests/fast/events/window-onerror3.html
new file mode 100644 (file)
index 0000000..ee2893f
--- /dev/null
@@ -0,0 +1,23 @@
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+function log(msg) {
+    document.getElementById("console").innerHTML += msg + "<br>";
+}
+
+function test1()
+{
+    window.onerror = function (error, url, line) {
+        url = url ? url.match( /[^\/]+\/?$/ )[0] : url;
+        log("Error caught successfully: " + error + "\nFile: " + url + "\nLine: " + line)
+        return false;
+    };
+    unknownObject.unknownProperty++;
+}
+</script>
+<body onload="test1();">
+<p>You should see a message if window.onerror is working properly for this test.<a href="https://bugs.webkit.org/show_bug.cgi?id=8519">Bug 8519</a>.</p>
+<hr>
+<div id='console'></div>
+</body>
diff --git a/LayoutTests/fast/events/window-onerror4-expected.txt b/LayoutTests/fast/events/window-onerror4-expected.txt
new file mode 100644 (file)
index 0000000..26af8a1
--- /dev/null
@@ -0,0 +1,4 @@
+You should see a log record if window.onerror is working properly for this test.Bug 8519.
+
+Error caught successfully: ReferenceError: Left side of assignment is not a reference. File: undefined Line: 1
+
diff --git a/LayoutTests/fast/events/window-onerror4.html b/LayoutTests/fast/events/window-onerror4.html
new file mode 100644 (file)
index 0000000..c51887d
--- /dev/null
@@ -0,0 +1,23 @@
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+function log(msg) {
+    document.getElementById("console").innerHTML += msg + "<br>";
+}
+
+function test1()
+{
+    window.onerror = function (error, url, line) {
+        url = url ? url.match( /[^\/]+\/?$/ )[0] : url;
+        log("Error caught successfully: " + error + "\nFile: " + url + "\nLine: " + line)
+        return false;
+    };
+    eval("1=2");
+}
+</script>
+<body onload="test1();">
+<p>You should see a log record if window.onerror is working properly for this test.<a href="https://bugs.webkit.org/show_bug.cgi?id=8519">Bug 8519</a>.</p>
+<hr>
+<div id='console'></div>
+</body>
diff --git a/LayoutTests/fast/events/window-onerror5-expected.txt b/LayoutTests/fast/events/window-onerror5-expected.txt
new file mode 100644 (file)
index 0000000..3ec7f5e
--- /dev/null
@@ -0,0 +1,4 @@
+Test that window.onerror is invoked for syntax error in eval. You should see a log record if window.onerror is working properly for this test.Bug 8519.
+
+Error caught successfully: SyntaxError: Parse error File: undefined Line: 1
+
diff --git a/LayoutTests/fast/events/window-onerror5.html b/LayoutTests/fast/events/window-onerror5.html
new file mode 100644 (file)
index 0000000..932d438
--- /dev/null
@@ -0,0 +1,23 @@
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+function log(msg) {
+    document.getElementById("console").innerHTML += msg + "<br>";
+}
+
+function test1()
+{
+    window.onerror = function (error, url, line) {
+        url = url ? url.match( /[^\/]+\/?$/ )[0] : url;
+        log("Error caught successfully: " + error + "\nFile: " + url + "\nLine: " + line)
+        return false;
+    };
+    eval("a(");
+}
+</script>
+<body onload="test1();">
+<p>Test that window.onerror is invoked for syntax error in eval. You should see a log record if window.onerror is working properly for this test.<a href="https://bugs.webkit.org/show_bug.cgi?id=8519">Bug 8519</a>.</p>
+<hr>
+<div id='console'></div>
+</body>
diff --git a/LayoutTests/fast/events/window-onerror6-expected.txt b/LayoutTests/fast/events/window-onerror6-expected.txt
new file mode 100644 (file)
index 0000000..e7c27bb
--- /dev/null
@@ -0,0 +1,4 @@
+Test that syntax error will be reported to the window.onerror handler. Bug 8519.
+
+Main frame window.onerror: SyntaxError: Parse error at window-onerror6.html:22
+
diff --git a/LayoutTests/fast/events/window-onerror6.html b/LayoutTests/fast/events/window-onerror6.html
new file mode 100644 (file)
index 0000000..1978436
--- /dev/null
@@ -0,0 +1,26 @@
+<html>
+<body>
+<p>Test that syntax error will be reported to the window.onerror handler. <a href="https://bugs.webkit.org/show_bug.cgi?id=8519">Bug 8519</a>.</p>
+<div id="console"></div>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+function log(msg) {
+    document.getElementById("console").innerHTML += msg + "<br>";
+}
+
+window.onerror = function(msg, url, line)
+{
+    url = url ? url.match( /[^\/]+\/?$/ )[0] : url;
+    log("Main frame window.onerror: " + msg + " at " + url + ":" + line);
+    return false;
+}
+</script>
+<script>
+
+a) // syntax error
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/window-onerror7-expected.txt b/LayoutTests/fast/events/window-onerror7-expected.txt
new file mode 100644 (file)
index 0000000..5d22e7e
--- /dev/null
@@ -0,0 +1,6 @@
+CONSOLE MESSAGE: line 20: Error: Original error
+CONSOLE MESSAGE: line 17: Error: Nested error
+Test that exception in window.onerror won't lead to recursive window.onerror call. Bug 8519.
+
+Main frame window.onerror: Error: Original error at window-onerror7.html:20
+
diff --git a/LayoutTests/fast/events/window-onerror7.html b/LayoutTests/fast/events/window-onerror7.html
new file mode 100644 (file)
index 0000000..f665686
--- /dev/null
@@ -0,0 +1,24 @@
+<html>
+<body>
+<p>Test that exception in window.onerror won't lead to recursive window.onerror call. <a href="https://bugs.webkit.org/show_bug.cgi?id=8519">Bug 8519</a>.</p>
+<div id="console"></div>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+function log(msg) {
+    document.getElementById("console").innerHTML += msg + "<br>";
+}
+
+window.onerror = function(msg, url, line)
+{
+    url = url ? url.match( /[^\/]+\/?$/ )[0] : url;
+    log("Main frame window.onerror: " + msg + " at " + url + ":" + line);
+    throw new Error("Nested error");
+}
+
+throw new Error("Original error");
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/window-onerror8-expected.txt b/LayoutTests/fast/events/window-onerror8-expected.txt
new file mode 100644 (file)
index 0000000..efc6308
--- /dev/null
@@ -0,0 +1,5 @@
+Test that window.onerror is called on window object. Bug 8519.
+
+Main frame window.onerror: 2010 at undefined:0
+PASSED: this === window
+
diff --git a/LayoutTests/fast/events/window-onerror8.html b/LayoutTests/fast/events/window-onerror8.html
new file mode 100644 (file)
index 0000000..bade538
--- /dev/null
@@ -0,0 +1,28 @@
+<html>
+<body>
+<p>Test that window.onerror is called on window object. <a href="https://bugs.webkit.org/show_bug.cgi?id=8519">Bug 8519</a>.</p>
+<div id="console"></div>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+function log(msg) {
+    document.getElementById("console").innerHTML += msg + "<br>";
+}
+
+window.onerror = function(msg, url, line)
+{
+    url = url ? url.match( /[^\/]+\/?$/ )[0] : url;
+    log("Main frame window.onerror: " + msg + " at " + url + ":" + line);
+    if (this === window) 
+        log("PASSED: this === window");
+    else
+        log("FAILED: this === window");
+    return false;
+}
+
+throw 2010;
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/window-onerror9-expected.txt b/LayoutTests/fast/events/window-onerror9-expected.txt
new file mode 100644 (file)
index 0000000..94316d3
--- /dev/null
@@ -0,0 +1,8 @@
+Test that when window.onerror handler is called, window.event is the corresponding ErrorEvent object. Bug 8519.
+
+Main frame window.onerror: Error: 2010 at window-onerror9.html:31
+window.event.type = error
+window.event.message = Error: 2010
+window.event.filename = window-onerror9.html
+window.event.lineno = 31
+
diff --git a/LayoutTests/fast/events/window-onerror9.html b/LayoutTests/fast/events/window-onerror9.html
new file mode 100644 (file)
index 0000000..1086ace
--- /dev/null
@@ -0,0 +1,35 @@
+<html>
+<body>
+<p>Test that when window.onerror handler is called, window.event is the corresponding ErrorEvent object. <a href="https://bugs.webkit.org/show_bug.cgi?id=8519">Bug 8519</a>.</p>
+<div id="console"></div>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+
+function log(msg) {
+    document.getElementById("console").innerHTML += msg + "<br>";
+}
+
+function lastPathComponent(url) {
+    return url ? url.match( /[^\/]+\/?$/ )[0] : url;
+}
+
+window.onerror = function(msg, url, line)
+{
+    log("Main frame window.onerror: " + msg + " at " + lastPathComponent(url) + ":" + line);
+    log("window.event.type = " + window.event.type);
+    log("window.event.message = " + window.event.message);
+    log("window.event.filename = " + lastPathComponent(window.event.filename));
+    log("window.event.lineno = " + window.event.lineno);
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+    return false;
+}
+
+throw new Error(2010);
+
+</script>
+</body>
+</html>
index 10ab049..4041640 100644 (file)
@@ -4,8 +4,8 @@ Test Worker script error handling functionality. Should print a series of PASS m
 PASS: onerror invoked for a script that has invalid syntax.
 PASS: onerror invoked for a script that has script error 'ReferenceError: Can't find variable: foo' at line 1.
 PASS: event listener invoked for a script that has script error 'ReferenceError: Can't find variable: foo' at line 1.
-PASS: onerror invoked for a script that has script error 'ReferenceError: Can't find variable: bar' at line 3.
 PASS: onerror invoked for a script that has script error 'ReferenceError: Can't find variable: foo' at line 7.
+PASS: onerror invoked for a script that has script error 'ReferenceError: Can't find variable: bar' at line 3.
 PASS: onerror invoked for a script that has script error 'ReferenceError: Can't find variable: foo' at line 7.
 PASS: onerror invoked for a script that has script error 'ReferenceError: Can't find variable: foo' at line 7.
 PASS: message received from WorkerGlobalScope.onerror: onerror invoked for a script that has script error 'ReferenceError: Can't find variable: foo' at line 7.
diff --git a/LayoutTests/http/tests/security/resources/onerror-iframe.html b/LayoutTests/http/tests/security/resources/onerror-iframe.html
new file mode 100644 (file)
index 0000000..312fd12
--- /dev/null
@@ -0,0 +1,11 @@
+<script>
+function handleLoad()
+{
+    window.parent.postMessage("IFrameLoaded", "*");
+}
+
+throw "IframeException";
+
+</script>
+<body onload="handleLoad()">
+</body>
diff --git a/LayoutTests/http/tests/security/window-onerror-exception-in-iframe-expected.txt b/LayoutTests/http/tests/security/window-onerror-exception-in-iframe-expected.txt
new file mode 100644 (file)
index 0000000..8b17d92
--- /dev/null
@@ -0,0 +1,6 @@
+CONSOLE MESSAGE: line 0: IframeException
+Test that exceptions in iframe are not reported to the main frame window.onerror handler. window.onerror should print exactly one line.
+
+Main frame window.onerror: MainFrameException at undefined:0
+DONE
+
diff --git a/LayoutTests/http/tests/security/window-onerror-exception-in-iframe.html b/LayoutTests/http/tests/security/window-onerror-exception-in-iframe.html
new file mode 100644 (file)
index 0000000..0904e39
--- /dev/null
@@ -0,0 +1,39 @@
+<html>
+<body>
+<p>Test that exceptions in iframe are not reported to the main frame window.onerror handler.
+window.onerror should print exactly one line.</p>
+<div id="result"></div>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+
+function log(msg) {
+    document.getElementById("result").innerHTML += msg + "<br>";
+}
+
+window.onerror = function(msg, url, line)
+{
+    url = url ? url.match( /[^\/]+\/?$/ )[0] : url;
+    log("Main frame window.onerror: " + msg + " at " + url + ":" + line);
+    return false;
+}
+
+function receiveMessage(event) {
+    if (event.data === "IFrameLoaded") {
+        log("DONE");
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
+    } else
+        log("FAIL " + event.data);
+}
+
+window.addEventListener("message", receiveMessage, false);
+
+throw "MainFrameException";
+
+</script>
+<iframe src="http://localhost:8000/security/resources/onerror-iframe.html"/>
+</body>
+</html>
index fdf660b..ef0a391 100644 (file)
@@ -3,8 +3,8 @@ Test Worker script error handling functionality. Should print a series of PASS m
 PASS: onerror invoked for a script that has invalid syntax.
 PASS: onerror invoked for a script that has script error 'Uncaught ReferenceError: foo is not defined' at line 1.
 PASS: event listener invoked for a script that has script error 'Uncaught ReferenceError: foo is not defined' at line 1.
-PASS: onerror invoked for a script that has script error 'Uncaught ReferenceError: bar is not defined' at line 3.
 PASS: onerror invoked for a script that has script error 'Uncaught ReferenceError: foo is not defined' at line 7.
+PASS: onerror invoked for a script that has script error 'Uncaught ReferenceError: bar is not defined' at line 3.
 PASS: onerror invoked for a script that has script error 'Uncaught ReferenceError: foo is not defined' at line 7.
 PASS: onerror invoked for a script that has script error 'Uncaught ReferenceError: foo is not defined' at line 7.
 PASS: message received from WorkerGlobalScope.onerror: onerror invoked for a script that has script error 'Uncaught ReferenceError: foo is not defined' at line 7.
diff --git a/LayoutTests/platform/chromium/fast/events/window-onerror1-expected.txt b/LayoutTests/platform/chromium/fast/events/window-onerror1-expected.txt
new file mode 100644 (file)
index 0000000..65b624b
--- /dev/null
@@ -0,0 +1,3 @@
+This page tests setting onerror handlers through the DOM. If it passes, you will see "PASS" messages below.Bug 8519.\r
+\r
+PASS: caught global error: Uncaught ReferenceError: hahaha_good_luck_finding_me is not defined at window-onerror1.html:25\r
diff --git a/LayoutTests/platform/chromium/fast/events/window-onerror10-expected.txt b/LayoutTests/platform/chromium/fast/events/window-onerror10-expected.txt
new file mode 100644 (file)
index 0000000..b3d2d39
--- /dev/null
@@ -0,0 +1,11 @@
+Test that "error" event listener added with window.addEventListener is invoked for uncaucht exceptions. Bug 8519.\r
+\r
+event passed to the listener is the same as window.event: true\r
+Event details:\r
+type: error\r
+phase: 2\r
+currentTarget is the global object: true\r
+message: Uncaught Error: My fault.\r
+filename: window-onerror10.html\r
+lineno: 29\r
+\r
diff --git a/LayoutTests/platform/chromium/fast/events/window-onerror11-expected.txt b/LayoutTests/platform/chromium/fast/events/window-onerror11-expected.txt
new file mode 100644 (file)
index 0000000..92e3cf5
--- /dev/null
@@ -0,0 +1,4 @@
+Test that window.onerror is called on window object. Bug 8519.\r
+\r
+Main frame window.onerror: Uncaught Error: An exception at window-onerror.js:2\r
+\r
diff --git a/LayoutTests/platform/chromium/fast/events/window-onerror2-expected.txt b/LayoutTests/platform/chromium/fast/events/window-onerror2-expected.txt
new file mode 100644 (file)
index 0000000..f7b1621
--- /dev/null
@@ -0,0 +1,6 @@
+Test that uncaught exceptions will be reported to the window.onerror handler. Bug 8519.\r
+\r
+Main frame window.onerror: Uncaught Error: Inline script exception at window-onerror2.html:35\r
+Main frame window.onerror: Uncaught Exception in onload at window-onerror2.html:2\r
+Main frame window.onerror: Uncaught Error: Exception in setTimeout at window-onerror2.html:29\r
+\r
diff --git a/LayoutTests/platform/chromium/fast/events/window-onerror3-expected.txt b/LayoutTests/platform/chromium/fast/events/window-onerror3-expected.txt
new file mode 100644 (file)
index 0000000..a1b8bd5
--- /dev/null
@@ -0,0 +1,4 @@
+You should see a message if window.onerror is working properly for this test.Bug 8519.\r
+\r
+Error caught successfully: Uncaught ReferenceError: unknownObject is not defined File: window-onerror3.html Line: 16\r
+\r
diff --git a/LayoutTests/platform/chromium/fast/events/window-onerror4-expected.txt b/LayoutTests/platform/chromium/fast/events/window-onerror4-expected.txt
new file mode 100644 (file)
index 0000000..50f09e0
--- /dev/null
@@ -0,0 +1,4 @@
+You should see a log record if window.onerror is working properly for this test.Bug 8519.\r
+\r
+Error caught successfully: Uncaught ReferenceError: Invalid left-hand side in assignment File: window-onerror4.html Line: 1\r
+\r
diff --git a/LayoutTests/platform/chromium/fast/events/window-onerror5-expected.txt b/LayoutTests/platform/chromium/fast/events/window-onerror5-expected.txt
new file mode 100644 (file)
index 0000000..e45369e
--- /dev/null
@@ -0,0 +1,4 @@
+Test that window.onerror is invoked for syntax error in eval. You should see a log record if window.onerror is working properly for this test.Bug 8519.\r
+\r
+Error caught successfully: Uncaught SyntaxError: Unexpected end of input File: window-onerror5.html Line: 1\r
+\r
diff --git a/LayoutTests/platform/chromium/fast/events/window-onerror6-expected.txt b/LayoutTests/platform/chromium/fast/events/window-onerror6-expected.txt
new file mode 100644 (file)
index 0000000..18ed81a
--- /dev/null
@@ -0,0 +1,4 @@
+Test that syntax error will be reported to the window.onerror handler. Bug 8519.\r
+\r
+Main frame window.onerror: Uncaught SyntaxError: Unexpected token ) at window-onerror6.html:22\r
+\r
diff --git a/LayoutTests/platform/chromium/fast/events/window-onerror7-expected.txt b/LayoutTests/platform/chromium/fast/events/window-onerror7-expected.txt
new file mode 100644 (file)
index 0000000..23d0407
--- /dev/null
@@ -0,0 +1,6 @@
+CONSOLE MESSAGE: line 20: Uncaught Error: Original error\r
+CONSOLE MESSAGE: line 17: Uncaught Error: Nested error\r
+Test that exception in window.onerror won't lead to recursive window.onerror call. Bug 8519.\r
+\r
+Main frame window.onerror: Uncaught Error: Original error at window-onerror7.html:20\r
+\r
diff --git a/LayoutTests/platform/chromium/fast/events/window-onerror8-expected.txt b/LayoutTests/platform/chromium/fast/events/window-onerror8-expected.txt
new file mode 100644 (file)
index 0000000..13f2b32
--- /dev/null
@@ -0,0 +1,5 @@
+Test that window.onerror is called on window object. Bug 8519.\r
+\r
+Main frame window.onerror: Uncaught 2010 at window-onerror8.html:24\r
+PASSED: this === window\r
+\r
diff --git a/LayoutTests/platform/chromium/fast/events/window-onerror9-expected.txt b/LayoutTests/platform/chromium/fast/events/window-onerror9-expected.txt
new file mode 100644 (file)
index 0000000..1677e50
--- /dev/null
@@ -0,0 +1,8 @@
+Test that when window.onerror handler is called, window.event is the corresponding ErrorEvent object. Bug 8519.\r
+\r
+Main frame window.onerror: Uncaught Error: 2010 at window-onerror9.html:31\r
+window.event.type = error\r
+window.event.message = Uncaught Error: 2010\r
+window.event.filename = window-onerror9.html\r
+window.event.lineno = 31\r
+\r
diff --git a/LayoutTests/platform/chromium/http/tests/security/window-onerror-exception-in-iframe-expected.txt b/LayoutTests/platform/chromium/http/tests/security/window-onerror-exception-in-iframe-expected.txt
new file mode 100644 (file)
index 0000000..9e9c2ea
--- /dev/null
@@ -0,0 +1,6 @@
+CONSOLE MESSAGE: line 7: Uncaught IframeException\r
+Test that exceptions in iframe are not reported to the main frame window.onerror handler. window.onerror should print exactly one line.\r
+\r
+Main frame window.onerror: Uncaught MainFrameException at window-onerror-exception-in-iframe.html:34\r
+DONE\r
+\r
diff --git a/LayoutTests/platform/chromium/userscripts/window-onerror-for-isolated-world-1-expected.txt b/LayoutTests/platform/chromium/userscripts/window-onerror-for-isolated-world-1-expected.txt
new file mode 100644 (file)
index 0000000..2a3d068
--- /dev/null
@@ -0,0 +1,14 @@
+Test that window.onerror and "error" event listeners from main world are invoked for uncaught exceptions in user scripts running in isolate worlds as well as for exceptions in the main world.Bug 8519.\r
+\r
+Main world window.onerror: Uncaught Error: Error in main world inline script. at window-onerror-for-isolated-world-1.html:54\r
+Main world error event listener: Uncaught Error: Error in main world inline script. at window-onerror-for-isolated-world-1.html:54\r
+Main world window.onerror: Uncaught Error: Error in user script inline script. at :12\r
+Main world error event listener: Uncaught Error: Error in user script inline script. at :12\r
+Main world window.onerror: Uncaught Error: Error in main world load handler. at window-onerror-for-isolated-world-1.html:46\r
+Main world error event listener: Uncaught Error: Error in main world load handler. at window-onerror-for-isolated-world-1.html:46\r
+Main world window.onerror: Uncaught Error: Error in user script load handler. at :4\r
+Main world error event listener: Uncaught Error: Error in user script load handler. at :4\r
+Main world window.onerror: Uncaught Error: Error in main world setTimeout callback. at window-onerror-for-isolated-world-1.html:51\r
+Main world error event listener: Uncaught Error: Error in main world setTimeout callback. at window-onerror-for-isolated-world-1.html:51\r
+Main world window.onerror: Uncaught Error: Error in user script setTimeout callback. at :9\r
+Main world error event listener: Uncaught Error: Error in user script setTimeout callback. at :9\r
diff --git a/LayoutTests/platform/chromium/userscripts/window-onerror-for-isolated-world-2-expected.txt b/LayoutTests/platform/chromium/userscripts/window-onerror-for-isolated-world-2-expected.txt
new file mode 100644 (file)
index 0000000..93994db
--- /dev/null
@@ -0,0 +1,13 @@
+CONSOLE MESSAGE: line 30: Uncaught Error: Error in main world inline script.\r
+Test that window.onerror and "error" event listeners from isolated world are invoked for uncaught exceptions in user scripts running in isolate worlds as well as for exceptions in the main world.Bug 8519.\r
+\r
+user script window.onerror: Uncaught Error: Error in user script inline script. at :33\r
+user script error event listener: Uncaught Error: Error in user script inline script. at :33\r
+user script window.onerror: Uncaught Error: Error in main world load handler. at window-onerror-for-isolated-world-2.html:23\r
+user script error event listener: Uncaught Error: Error in main world load handler. at window-onerror-for-isolated-world-2.html:23\r
+user script window.onerror: Uncaught Error: Error in user script load handler. at :26\r
+user script error event listener: Uncaught Error: Error in user script load handler. at :26\r
+user script window.onerror: Uncaught Error: Error in main world setTimeout callback. at window-onerror-for-isolated-world-2.html:27\r
+user script error event listener: Uncaught Error: Error in main world setTimeout callback. at window-onerror-for-isolated-world-2.html:27\r
+user script window.onerror: Uncaught Error: Error in user script setTimeout callback. at :30\r
+user script error event listener: Uncaught Error: Error in user script setTimeout callback. at :30\r
index 2b45241..0f9106b 100644 (file)
@@ -4709,6 +4709,8 @@ userscripts/user-script-plugin-document.html
 userscripts/user-script-top-frame-only.html
 userscripts/user-script-video-document.html
 userscripts/user-style-top-frame-only.html
+userscripts/window-onerror-for-isolated-world-1.html
+userscripts/window-onerror-for-isolated-world-2.html
 
 # XHR sends sometimes yield null bytes sent instead of 0.
 http/tests/xmlhttprequest/workers/shared-worker-methods.html
diff --git a/LayoutTests/userscripts/window-onerror-for-isolated-world-1-expected.txt b/LayoutTests/userscripts/window-onerror-for-isolated-world-1-expected.txt
new file mode 100644 (file)
index 0000000..6895c41
--- /dev/null
@@ -0,0 +1,14 @@
+Test that window.onerror and "error" event listeners from main world are invoked for uncaught exceptions in user scripts running in isolate worlds as well as for exceptions in the main world.Bug 8519.
+
+Main world window.onerror: Error: Error in main world inline script. at window-onerror-for-isolated-world-1.html:54
+Main world error event listener: Error: Error in main world inline script. at window-onerror-for-isolated-world-1.html:54
+Main world window.onerror: Error: Error in user script inline script. at undefined:11
+Main world error event listener: Error: Error in user script inline script. at undefined:11
+Main world window.onerror: Error: Error in main world load handler. at window-onerror-for-isolated-world-1.html:46
+Main world error event listener: Error: Error in main world load handler. at window-onerror-for-isolated-world-1.html:46
+Main world window.onerror: Error: Error in user script load handler. at undefined:3
+Main world error event listener: Error: Error in user script load handler. at undefined:3
+Main world window.onerror: Error: Error in main world setTimeout callback. at window-onerror-for-isolated-world-1.html:51
+Main world error event listener: Error: Error in main world setTimeout callback. at window-onerror-for-isolated-world-1.html:51
+Main world window.onerror: Error: Error in user script setTimeout callback. at undefined:8
+Main world error event listener: Error: Error in user script setTimeout callback. at undefined:8
diff --git a/LayoutTests/userscripts/window-onerror-for-isolated-world-1.html b/LayoutTests/userscripts/window-onerror-for-isolated-world-1.html
new file mode 100644 (file)
index 0000000..3c6bac2
--- /dev/null
@@ -0,0 +1,67 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+</head>
+<body>
+<p>Test that window.onerror and "error" event listeners from main world are
+invoked for uncaught exceptions in user scripts running in isolate worlds as
+well as for exceptions in the main world.<a href="https://bugs.webkit.org/show_bug.cgi?id=8519">Bug 8519.</a>
+</p>
+<div id="console"></div>
+<script>
+
+var expectedRecordCount = 12;
+var recordCount = 0;
+document.getElementById("console").addEventListener("DOMNodeInserted", function(e) {
+    recordCount++;
+    if (recordCount === expectedRecordCount && window.layoutTestController)
+        layoutTestController.notifyDone();
+}, false);
+
+function log(msg) {
+    var record = document.createElement("div");
+    record.innerHTML = msg;
+    document.getElementById("console").appendChild(record);
+}
+
+function lastUrlComponent(url) {
+    return url ? url.match( /[^\/]+\/?$/ )[0] : url;
+}
+
+window.onerror = function(msg, url, line)
+{
+    log("Main world window.onerror: " + msg + " at " + lastUrlComponent(url) + ":" + line);
+    return false;
+}
+
+window.addEventListener("error", function(e)
+{
+    var url = lastUrlComponent(e.filename);
+    log("Main world error event listener: " + e.message + " at " + url + ":" + e.lineno);
+}, false);
+
+var exceptions = function(isolatedWorld)
+{
+    window.addEventListener("load", function(e) {
+        throw new Error("Error in " + isolatedWorld + " load handler.");
+    }, false);
+
+
+    setTimeout(function() {
+        throw new Error("Error in " + isolatedWorld + " setTimeout callback.");
+    }, 0);
+
+    throw new Error("Error in "+ isolatedWorld + " inline script.");
+}
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+    layoutTestController.addUserScript("(" + exceptions + ")('user script')", false, true);
+}
+
+exceptions("main world");
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/userscripts/window-onerror-for-isolated-world-2-expected.txt b/LayoutTests/userscripts/window-onerror-for-isolated-world-2-expected.txt
new file mode 100644 (file)
index 0000000..b909a99
--- /dev/null
@@ -0,0 +1,13 @@
+CONSOLE MESSAGE: line 30: Error: Error in main world inline script.
+Test that window.onerror and "error" event listeners from isolated world are invoked for uncaught exceptions in user scripts running in isolate worlds as well as for exceptions in the main world.Bug 8519.
+
+user script window.onerror: Error: Error in user script inline script. at undefined:31
+user script error event listener: Error: Error in user script inline script. at undefined:31
+user script window.onerror: Error: Error in main world load handler. at window-onerror-for-isolated-world-2.html:23
+user script error event listener: Error: Error in main world load handler. at window-onerror-for-isolated-world-2.html:23
+user script window.onerror: Error: Error in user script load handler. at undefined:24
+user script error event listener: Error: Error in user script load handler. at undefined:24
+user script window.onerror: Error: Error in main world setTimeout callback. at window-onerror-for-isolated-world-2.html:27
+user script error event listener: Error: Error in main world setTimeout callback. at window-onerror-for-isolated-world-2.html:27
+user script window.onerror: Error: Error in user script setTimeout callback. at undefined:28
+user script error event listener: Error: Error in user script setTimeout callback. at undefined:28
diff --git a/LayoutTests/userscripts/window-onerror-for-isolated-world-2.html b/LayoutTests/userscripts/window-onerror-for-isolated-world-2.html
new file mode 100644 (file)
index 0000000..a6ec699
--- /dev/null
@@ -0,0 +1,67 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+</head>
+<body>
+<p>Test that window.onerror and "error" event listeners from isolated world are
+invoked for uncaught exceptions in user scripts running in isolate worlds as
+well as for exceptions in the main world.<a href="https://bugs.webkit.org/show_bug.cgi?id=8519">Bug 8519.</a>
+</p>
+<div id="console"></div>
+<script>
+
+var expectedRecordCount = 10;
+var recordCount = 0;
+document.getElementById("console").addEventListener("DOMNodeInserted", function(e) {
+    if (++recordCount === expectedRecordCount && window.layoutTestController)
+        layoutTestController.notifyDone();
+}, false);
+
+var throwExceptions = function(isolatedWorld)
+{
+    window.addEventListener("load", function(e) {
+        throw new Error("Error in " + isolatedWorld + " load handler.");
+    }, false);
+
+    setTimeout(function() {
+        throw new Error("Error in " + isolatedWorld + " setTimeout callback.");
+    }, 0);
+    
+    throw new Error("Error in "+ isolatedWorld + " inline script.");
+};
+
+var errorHandlers = function(isolatedWorld)
+{
+    function lastUrlComponent(url) {
+        return url ? url.match( /[^\/]+\/?$/ )[0] : url;
+    }
+
+    function log(msg) {
+        var record = document.createElement("div");
+        record.innerHTML = msg;
+        document.getElementById("console").appendChild(record);
+    }
+
+    window.onerror = function(msg, url, line) {
+        log(isolatedWorld + " window.onerror: " + msg + " at " + lastUrlComponent(url) + ":" + line, "*");
+        return false;
+    }
+
+    window.addEventListener("error", function(e) {
+        var url = lastUrlComponent(e.filename);
+        log(isolatedWorld + " error event listener: " + e.message + " at " + url + ":" + e.lineno, "*");
+        e.preventDefault();
+    }, false);
+};
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+    layoutTestController.addUserScript("(" + errorHandlers + ")('user script'); (" + throwExceptions + ")('user script')", false, true);
+}
+
+throwExceptions("main world");
+
+</script>
+</body>
+</html>
index 653dfec..e7fd2fc 100644 (file)
@@ -102,6 +102,7 @@ LOCAL_SRC_FILES += \
        bindings/js/JSDeviceOrientationEventCustom.cpp \
        bindings/js/JSDocumentCustom.cpp \
        bindings/js/JSElementCustom.cpp \
+       bindings/js/JSErrorHandler.cpp \
        bindings/js/JSEventCustom.cpp \
        bindings/js/JSEventListener.cpp \
        bindings/js/JSEventTarget.cpp \
@@ -170,7 +171,6 @@ LOCAL_SRC_FILES += \
        bindings/js/JSWebKitPointCustom.cpp \
        bindings/js/JSWorkerContextBase.cpp \
        bindings/js/JSWorkerContextCustom.cpp \
-       bindings/js/JSWorkerContextErrorHandler.cpp \
        bindings/js/JSWorkerCustom.cpp \
        bindings/js/JSXMLHttpRequestCustom.cpp \
        bindings/js/JSXMLHttpRequestUploadCustom.cpp \
index 2b0ee30..e3ffc38 100644 (file)
@@ -634,6 +634,7 @@ SET(WebCore_SOURCES
     bindings/js/JSDeviceOrientationEventCustom.cpp
     bindings/js/JSDocumentCustom.cpp
     bindings/js/JSElementCustom.cpp
+    bindings/js/JSErrorHandler.cpp
     bindings/js/JSEventCustom.cpp
     bindings/js/JSEventListener.cpp
     bindings/js/JSEventSourceCustom.cpp
@@ -703,7 +704,6 @@ SET(WebCore_SOURCES
     bindings/js/JSWebSocketCustom.cpp
     bindings/js/JSWorkerContextBase.cpp
     bindings/js/JSWorkerContextCustom.cpp
-    bindings/js/JSWorkerContextErrorHandler.cpp
     bindings/js/JSWorkerCustom.cpp
     bindings/js/JSXMLHttpRequestCustom.cpp
     bindings/js/JSXMLHttpRequestUploadCustom.cpp
index 84c0627..d8aea82 100644 (file)
@@ -1,3 +1,87 @@
+2010-12-13  Yury Semikhatsky  <yurys@chromium.org>
+
+        Reviewed by Adam Barth.
+
+        WebCore doesn't fire window.onerror event when uncaught JavaScript exceptions are thrown
+        https://bugs.webkit.org/show_bug.cgi?id=8519
+
+        Uncaught exceptions are propagated to window.onerror hander if one is present.
+        The handler is expected to be a function accepting three arguments: error message,
+        resource url and line number where the exception occured.
+
+        It was decided to dispatch ErrorEvent to all listeners/handlers no matter if they
+        were created in the same isolated world where the exception occured or not.
+
+        Tests: fast/events/window-onerror1.html
+               fast/events/window-onerror10.html
+               fast/events/window-onerror11.html
+               fast/events/window-onerror2.html
+               fast/events/window-onerror3.html
+               fast/events/window-onerror4.html
+               fast/events/window-onerror5.html
+               fast/events/window-onerror6.html
+               fast/events/window-onerror7.html
+               fast/events/window-onerror8.html
+               fast/events/window-onerror9.html
+               http/tests/security/window-onerror-exception-in-iframe.html
+               userscripts/window-onerror-for-isolated-world-1.html
+               userscripts/window-onerror-for-isolated-world-2.html
+
+        * Android.jscbindings.mk:
+        * CMakeLists.txt:
+        * GNUmakefile.am:
+        * WebCore.gypi:
+        * WebCore.order:
+        * WebCore.pro:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/JSBindingsAllInOne.cpp:
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::reportException):
+        * bindings/js/JSErrorHandler.cpp: Renamed from WebCore/bindings/js/JSWorkerContextErrorHandler.cpp.
+        (WebCore::JSErrorHandler::JSErrorHandler):
+        (WebCore::JSErrorHandler::~JSErrorHandler):
+        (WebCore::JSErrorHandler::handleEvent):
+        * bindings/js/JSErrorHandler.h: Copied from WebCore/bindings/js/JSWorkerContextErrorHandler.h.
+        (WebCore::JSErrorHandler::create):
+        (WebCore::createJSErrorHandler):
+        * bindings/scripts/CodeGeneratorJS.pm:
+        * bindings/scripts/CodeGeneratorV8.pm:
+        * bindings/v8/V8ConsoleMessage.cpp:
+        (WebCore::V8ConsoleMessage::dispatchNow):
+        (WebCore::V8ConsoleMessage::handler): the method was changed to use generic WebCore exception
+        reporting mechanism which is also used by JSC bindings.
+        * bindings/v8/V8ConsoleMessage.h:
+        * bindings/v8/V8WindowErrorHandler.cpp: Copied from WebCore/bindings/js/JSWorkerContextErrorHandler.h.
+        (WebCore::V8WindowErrorHandler::V8WindowErrorHandler):
+        (WebCore::V8WindowErrorHandler::callListenerFunction):
+        * bindings/v8/V8WindowErrorHandler.h: Renamed from WebCore/bindings/js/JSWorkerContextErrorHandler.h.
+        (WebCore::V8WindowErrorHandler::create):
+        * bindings/v8/WorkerContextExecutionProxy.cpp:
+        (WebCore::v8MessageHandler):
+        * bindings/v8/WorkerScriptController.cpp:
+        (WebCore::WorkerScriptController::evaluate):
+        * dom/Document.cpp:
+        (WebCore::Document::errorEventTarget):
+        (WebCore::Document::logExceptionToConsole):
+        * dom/Document.h:
+        * dom/ScriptExecutionContext.cpp:
+        (WebCore::ScriptExecutionContext::PendingException::PendingException):
+        (WebCore::ScriptExecutionContext::ScriptExecutionContext):
+        (WebCore::ScriptExecutionContext::reportException): this method is not virtual anymore to
+        ensure that error event dispatching algorithm is the same in WorkerContext and in Document.
+        (WebCore::ScriptExecutionContext::dispatchErrorEvent):
+        * dom/ScriptExecutionContext.h:
+        * workers/DefaultSharedWorkerRepository.cpp:
+        (WebCore::postExceptionTask):
+        * workers/WorkerContext.cpp:
+        (WebCore::WorkerContext::WorkerContext):
+        (WebCore::WorkerContext::errorEventTarget):
+        (WebCore::WorkerContext::logExceptionToConsole):
+        * workers/WorkerContext.h:
+        * workers/WorkerMessagingProxy.cpp:
+        (WebCore::WorkerExceptionTask::performTask):
+
 2010-12-08  Alexander Pavlov  <apavlov@chromium.org>
 
         Reviewed by Joseph Pecoraro.
index 4d95df7..dcbe391 100644 (file)
@@ -773,6 +773,8 @@ webcore_sources += \
        WebCore/bindings/js/JSElementCustom.cpp \
        WebCore/bindings/js/JSEntryCustom.cpp \
        WebCore/bindings/js/JSEntrySyncCustom.cpp \
+       WebCore/bindings/js/JSErrorHandler.cpp \
+       WebCore/bindings/js/JSErrorHandler.h \
        WebCore/bindings/js/JSEventCustom.cpp \
        WebCore/bindings/js/JSEventListener.cpp \
        WebCore/bindings/js/JSEventListener.h \
@@ -870,8 +872,6 @@ webcore_sources += \
        WebCore/bindings/js/JSWorkerContextBase.cpp \
        WebCore/bindings/js/JSWorkerContextBase.h \
        WebCore/bindings/js/JSWorkerContextCustom.cpp \
-       WebCore/bindings/js/JSWorkerContextErrorHandler.cpp \
-       WebCore/bindings/js/JSWorkerContextErrorHandler.h \
        WebCore/bindings/js/JSWorkerCustom.cpp \
        WebCore/bindings/js/JSXMLHttpRequestCustom.cpp \
        WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp \
index ba9d627..425f084 100644 (file)
             'bindings/js/JSElementCustom.cpp',
             'bindings/js/JSEntryCustom.cpp',
             'bindings/js/JSEntrySyncCustom.cpp',
+            'bindings/js/JSErrorHandler.cpp',
+            'bindings/js/JSErrorHandler.h',
             'bindings/js/JSEventCustom.cpp',
             'bindings/js/JSEventListener.cpp',
             'bindings/js/JSEventListener.h',
             'bindings/js/JSWorkerContextBase.cpp',
             'bindings/js/JSWorkerContextBase.h',
             'bindings/js/JSWorkerContextCustom.cpp',
-            'bindings/js/JSWorkerContextErrorHandler.cpp',
-            'bindings/js/JSWorkerContextErrorHandler.h',
             'bindings/js/JSWorkerCustom.cpp',
             'bindings/js/JSXMLHttpRequestCustom.cpp',
             'bindings/js/JSXMLHttpRequestUploadCustom.cpp',
             'bindings/v8/V8Proxy.h',
             'bindings/v8/V8Utilities.cpp',
             'bindings/v8/V8Utilities.h',
+            'bindings/v8/V8WindowErrorHandler.cpp',
+            'bindings/v8/V8WindowErrorHandler.h',
             'bindings/v8/V8WorkerContextErrorHandler.cpp',
             'bindings/v8/V8WorkerContextErrorHandler.h',
             'bindings/v8/V8WorkerContextEventListener.cpp',
index 0fdabb1..2049fe1 100644 (file)
@@ -25209,13 +25209,9 @@ __ZN7WebCore15JSWorkerContext10setTimeoutEPN3JSC9ExecStateERKNS1_7ArgListE
 __ZN7WebCore13WorkerContext10setTimeoutEPNS_15ScheduledActionEi
 __ZN7WebCore17WorkerSharedTimer11setFireTimeEd
 __ZN7WebCore15ScheduledAction7executeEPNS_13WorkerContextE
-__ZN7WebCore27JSWorkerContextErrorHandlerC1EPN3JSC8JSObjectES3_bPNS_15DOMWrapperWorldE
-__ZN7WebCore27JSWorkerContextErrorHandlerC2EPN3JSC8JSObjectES3_bPNS_15DOMWrapperWorldE
 __ZN7WebCore10ErrorEventC1ERKNS_6StringES3_j
 __ZN7WebCore10ErrorEventC2ERKNS_6StringES3_j
-__ZN7WebCore27JSWorkerContextErrorHandler11handleEventEPNS_22ScriptExecutionContextEPNS_5EventE
 __ZN7WebCore10ErrorEventD0Ev
-__ZN7WebCore27JSWorkerContextErrorHandlerD0Ev
 __ZN7WebCore17jsWorkerOnmessageEPN3JSC9ExecStateENS0_7JSValueERKNS0_10IdentifierE
 __ZN7WebCore34jsWorkerPrototypeFunctionTerminateEPN3JSC9ExecStateEPNS0_8JSObjectENS0_7JSValueERKNS0_7ArgListE
 __ZThn8_N7WebCore20WorkerMessagingProxy19workerContextClosedEv
index bd57055..aa15b7b 100644 (file)
@@ -385,6 +385,7 @@ v8 {
         bindings/v8/V8NodeFilterCondition.cpp \
         bindings/v8/V8Proxy.cpp \
         bindings/v8/V8Utilities.cpp \
+        bindings/v8/V8WindowErrorHandler.cpp \
         bindings/v8/V8WorkerContextEventListener.cpp \
         bindings/v8/WorkerContextExecutionProxy.cpp \
         bindings/v8/WorkerScriptController.cpp \
@@ -529,6 +530,7 @@ v8 {
         bindings/js/JSDeviceOrientationEventCustom.cpp \
         bindings/js/JSDocumentCustom.cpp \
         bindings/js/JSElementCustom.cpp \
+        bindings/js/JSErrorHandler.cpp \
         bindings/js/JSEventCustom.cpp \
         bindings/js/JSEventListener.cpp \
         bindings/js/JSEventSourceCustom.cpp \
@@ -588,7 +590,6 @@ v8 {
         bindings/js/JSWebKitCSSKeyframesRuleCustom.cpp \
         bindings/js/JSWebKitCSSMatrixCustom.cpp \
         bindings/js/JSWebKitPointCustom.cpp \
-        bindings/js/JSWorkerContextErrorHandler.cpp \
         bindings/js/JSXMLHttpRequestCustom.cpp \
         bindings/js/JSXMLHttpRequestUploadCustom.cpp \
         bindings/js/ScheduledAction.cpp \
@@ -1460,6 +1461,7 @@ v8 {
         bindings/v8/V8NPUtils.h \
         bindings/v8/V8Proxy.h \
         bindings/v8/V8Utilities.h \
+        bindings/v8/V8WindowErrorHandler.h \
         bindings/v8/V8WorkerContextEventListener.h \
         bindings/v8/WorkerContextExecutionProxy.h \
         bindings/v8/WorkerScriptController.h \
@@ -1486,6 +1488,7 @@ v8 {
         bindings/js/JSDOMWindowCustom.h \
         bindings/js/JSDOMWindowShell.h \
         bindings/js/JSDOMWrapper.h \
+        bindings/js/JSErrorHandler.h \
         bindings/js/JSEventListener.h \
         bindings/js/JSEventTarget.h \
         bindings/js/JSHistoryCustom.h \
@@ -1503,7 +1506,6 @@ v8 {
         bindings/js/JSPluginElementFunctions.h \
         bindings/js/JSStorageCustom.h \
         bindings/js/JSWorkerContextBase.h \
-        bindings/js/JSWorkerContextErrorHandler.h \
         bindings/js/JavaScriptCallFrame.h \
         bindings/js/ScheduledAction.h \
         bindings/js/ScriptCachedFrameData.h \
index 8d74bcb..9d6b87c 100755 (executable)
                                </File>
                                <File
                                        RelativePath="..\bindings\js\JSDOMWindowShell.cpp"
+                                       RelativePath="..\bindings\js\JSErrorHandler.cpp"
+                                       >
+                                       <FileConfiguration
+                                               Name="Debug|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Release|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Debug_Internal|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Debug_Cairo|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Release_Cairo|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Debug_All|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                               </File>
+                               <File
+                                       RelativePath="..\bindings\js\JSErrorHandler.h"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\bindings\js\JSEventCustom.cpp"
                                        >
                                        <FileConfiguration
                                                Name="Debug|Win32"
                                        </FileConfiguration>
                                </File>
                                <File
-                                       RelativePath="..\bindings\js\JSWorkerContextErrorHandler.cpp"
-                                       >
-                                       <FileConfiguration
-                                               Name="Debug|Win32"
-                                               ExcludedFromBuild="true"
-                                               >
-                                               <Tool
-                                                       Name="VCCLCompilerTool"
-                                               />
-                                       </FileConfiguration>
-                                       <FileConfiguration
-                                               Name="Release|Win32"
-                                               ExcludedFromBuild="true"
-                                               >
-                                               <Tool
-                                                       Name="VCCLCompilerTool"
-                                               />
-                                       </FileConfiguration>
-                                       <FileConfiguration
-                                               Name="Debug_Cairo_CFLite|Win32"
-                                               ExcludedFromBuild="true"
-                                               >
-                                               <Tool
-                                                       Name="VCCLCompilerTool"
-                                               />
-                                       </FileConfiguration>
-                                       <FileConfiguration
-                                               Name="Release_Cairo_CFLite|Win32"
-                                               ExcludedFromBuild="true"
-                                               >
-                                               <Tool
-                                                       Name="VCCLCompilerTool"
-                                               />
-                                       </FileConfiguration>
-                                       <FileConfiguration
-                                               Name="Debug_All|Win32"
-                                               ExcludedFromBuild="true"
-                                               >
-                                               <Tool
-                                                       Name="VCCLCompilerTool"
-                                               />
-                                       </FileConfiguration>
-                                       <FileConfiguration
-                                               Name="Release_LTCG|Win32"
-                                               ExcludedFromBuild="true"
-                                               >
-                                               <Tool
-                                                       Name="VCCLCompilerTool"
-                                               />
-                                       </FileConfiguration>
-                               </File>
-                               <File
-                                       RelativePath="..\bindings\js\JSWorkerContextErrorHandler.h"
-                                       >
-                               </File>
-                               <File
                                        RelativePath="..\bindings\js\JSWorkerCustom.cpp"
                                        >
                                        <FileConfiguration
index e6d0cd0..9d9992c 100644 (file)
                F392249D126F11AE00A926D9 /* ScriptCallStackFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = F392249B126F11AE00A926D9 /* ScriptCallStackFactory.h */; };
                F39BE95B12673BF400E0A674 /* ScriptArguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F39BE95912673BF400E0A674 /* ScriptArguments.cpp */; };
                F39BE95C12673BF400E0A674 /* ScriptArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = F39BE95A12673BF400E0A674 /* ScriptArguments.h */; };
-               F3D461481161D53200CA0D09 /* JSWorkerContextErrorHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F3D461461161D53200CA0D09 /* JSWorkerContextErrorHandler.cpp */; };
-               F3D461491161D53200CA0D09 /* JSWorkerContextErrorHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = F3D461471161D53200CA0D09 /* JSWorkerContextErrorHandler.h */; };
+               F3D461481161D53200CA0D09 /* JSErrorHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F3D461461161D53200CA0D09 /* JSErrorHandler.cpp */; };
+               F3D461491161D53200CA0D09 /* JSErrorHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = F3D461471161D53200CA0D09 /* JSErrorHandler.h */; };
                F4EAF4AE10C742B1009100D3 /* OpenTypeSanitizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F4EAF4AC10C742B1009100D3 /* OpenTypeSanitizer.cpp */; };
                F4EAF4AF10C742B1009100D3 /* OpenTypeSanitizer.h in Headers */ = {isa = PBXBuildFile; fileRef = F4EAF4AD10C742B1009100D3 /* OpenTypeSanitizer.h */; };
                F55B3DAD1251F12D003EF269 /* BaseTextInputType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F55B3D791251F12D003EF269 /* BaseTextInputType.cpp */; };
                F392249B126F11AE00A926D9 /* ScriptCallStackFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptCallStackFactory.h; sourceTree = "<group>"; };
                F39BE95912673BF400E0A674 /* ScriptArguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptArguments.cpp; sourceTree = "<group>"; };
                F39BE95A12673BF400E0A674 /* ScriptArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptArguments.h; sourceTree = "<group>"; };
-               F3D461461161D53200CA0D09 /* JSWorkerContextErrorHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWorkerContextErrorHandler.cpp; sourceTree = "<group>"; };
-               F3D461471161D53200CA0D09 /* JSWorkerContextErrorHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWorkerContextErrorHandler.h; sourceTree = "<group>"; };
+               F3D461461161D53200CA0D09 /* JSErrorHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSErrorHandler.cpp; sourceTree = "<group>"; };
+               F3D461471161D53200CA0D09 /* JSErrorHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSErrorHandler.h; sourceTree = "<group>"; };
                F4EAF4AC10C742B1009100D3 /* OpenTypeSanitizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OpenTypeSanitizer.cpp; path = opentype/OpenTypeSanitizer.cpp; sourceTree = "<group>"; };
                F4EAF4AD10C742B1009100D3 /* OpenTypeSanitizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenTypeSanitizer.h; path = opentype/OpenTypeSanitizer.h; sourceTree = "<group>"; };
                F523D23B02DE4396018635CA /* HTMLDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLDocument.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                                BCBFB53B0DCD29CF0019B3E5 /* JSDOMWindowShell.h */,
                                BC53DAC611433064000D817E /* JSDOMWrapper.cpp */,
                                65E0E9431133C89F00B4CB10 /* JSDOMWrapper.h */,
+                               F3D461461161D53200CA0D09 /* JSErrorHandler.cpp */,
+                               F3D461471161D53200CA0D09 /* JSErrorHandler.h */,
                                BC60901E0E91B8EC000C68B5 /* JSEventTarget.cpp */,
                                BC60901D0E91B8EC000C68B5 /* JSEventTarget.h */,
                                3314ACE910892086000F0E56 /* JSExceptionBase.cpp */,
                                14CD8D81106B529000A46D23 /* JSSharedWorkerCustom.cpp */,
                                E1C36D320EB0A094007410BC /* JSWorkerContextBase.cpp */,
                                E1C36D330EB0A094007410BC /* JSWorkerContextBase.h */,
-                               F3D461461161D53200CA0D09 /* JSWorkerContextErrorHandler.cpp */,
-                               F3D461471161D53200CA0D09 /* JSWorkerContextErrorHandler.h */,
                                BCA378BA0D15F64200B793D6 /* ScheduledAction.cpp */,
                                BCA378BB0D15F64200B793D6 /* ScheduledAction.h */,
                                41F1D21E0EF35C2A00DA8753 /* ScriptCachedFrameData.cpp */,
                                E1CAA5C60E8BD23600A73ECA /* JSWorker.h in Headers */,
                                E18256900EF2B02D00933242 /* JSWorkerContext.h in Headers */,
                                E1C36D350EB0A094007410BC /* JSWorkerContextBase.h in Headers */,
-                               F3D461491161D53200CA0D09 /* JSWorkerContextErrorHandler.h in Headers */,
+                               F3D461491161D53200CA0D09 /* JSErrorHandler.h in Headers */,
                                E1C362EF0EAF2AA9007410BC /* JSWorkerLocation.h in Headers */,
                                E1271A580EEECDE400F61213 /* JSWorkerNavigator.h in Headers */,
                                BC348BD40DB7F804004ABAB9 /* JSXMLHttpRequest.h in Headers */,
                                E182568F0EF2B02D00933242 /* JSWorkerContext.cpp in Sources */,
                                E1C36D340EB0A094007410BC /* JSWorkerContextBase.cpp in Sources */,
                                E18258AC0EF3CD7000933242 /* JSWorkerContextCustom.cpp in Sources */,
-                               F3D461481161D53200CA0D09 /* JSWorkerContextErrorHandler.cpp in Sources */,
+                               F3D461481161D53200CA0D09 /* JSErrorHandler.cpp in Sources */,
                                E1CA5CBC0E8CDCAF00E8EF90 /* JSWorkerCustom.cpp in Sources */,
                                E1C362F00EAF2AA9007410BC /* JSWorkerLocation.cpp in Sources */,
                                E1271A590EEECDE400F61213 /* JSWorkerNavigator.cpp in Sources */,
index 7fc5740..d2c27a9 100644 (file)
@@ -72,6 +72,7 @@
 #include "JSDeviceOrientationEventCustom.cpp"
 #include "JSDocumentCustom.cpp"
 #include "JSElementCustom.cpp"
+#include "JSErrorHandler.cpp"
 #include "JSEventCustom.cpp"
 #include "JSEventListener.cpp"
 #include "JSEventSourceCustom.cpp"
 #include "JSWebSocketCustom.cpp"
 #include "JSWorkerContextBase.cpp"
 #include "JSWorkerContextCustom.cpp"
-#include "JSWorkerContextErrorHandler.cpp"
 #include "JSWorkerCustom.cpp"
 #include "JSXMLHttpRequestCustom.cpp"
 #include "JSXMLHttpRequestUploadCustom.cpp"
index 267d18a..6d3e3c5 100644 (file)
@@ -55,6 +55,7 @@
 #include "ProcessingInstruction.h"
 #include "RangeException.h"
 #include "ScriptCachedFrameData.h"
+#include "ScriptCallStack.h"
 #include "ScriptController.h"
 #include "Settings.h"
 #include "WebCoreJSClientData.h"
@@ -598,7 +599,7 @@ void reportException(ExecState* exec, JSValue exception)
     if (!scriptExecutionContext)
         return;
 
-    scriptExecutionContext->reportException(ustringToString(errorMessage), lineNumber, ustringToString(exceptionSourceURL));
+    scriptExecutionContext->reportException(ustringToString(errorMessage), lineNumber, ustringToString(exceptionSourceURL), 0);
 }
 
 void reportCurrentException(ExecState* exec)
similarity index 86%
rename from WebCore/bindings/js/JSWorkerContextErrorHandler.cpp
rename to WebCore/bindings/js/JSErrorHandler.cpp
index f7d2b02..b6f39c1 100644 (file)
@@ -30,9 +30,7 @@
 
 #include "config.h"
 
-#if ENABLE(WORKERS)
-
-#include "JSWorkerContextErrorHandler.h"
+#include "JSErrorHandler.h"
 
 #include "ErrorEvent.h"
 #include "Event.h"
@@ -43,21 +41,24 @@ using namespace JSC;
 
 namespace WebCore {
 
-JSWorkerContextErrorHandler::JSWorkerContextErrorHandler(JSObject* function, JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld)
+JSErrorHandler::JSErrorHandler(JSObject* function, JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld)
     : JSEventListener(function, wrapper, isAttribute, isolatedWorld)
 {
 }
 
-JSWorkerContextErrorHandler::~JSWorkerContextErrorHandler()
+JSErrorHandler::~JSErrorHandler()
 {
 }
 
-void JSWorkerContextErrorHandler::handleEvent(ScriptExecutionContext* scriptExecutionContext, Event* event)
+void JSErrorHandler::handleEvent(ScriptExecutionContext* scriptExecutionContext, Event* event)
 {
     ASSERT(scriptExecutionContext);
     if (!scriptExecutionContext)
         return;
 
+    ASSERT(event->isErrorEvent());
+    ErrorEvent* errorEvent = static_cast<ErrorEvent*>(event);
+
     JSLock lock(SilenceAssertionsOnly);
 
     JSObject* jsFunction = this->jsFunction(scriptExecutionContext);
@@ -74,15 +75,11 @@ void JSWorkerContextErrorHandler::handleEvent(ScriptExecutionContext* scriptExec
     CallType callType = jsFunction->getCallData(callData);
 
     if (callType != CallTypeNone) {
-
-        ref();
+        RefPtr<JSErrorHandler> protectedctor(this);
 
         Event* savedEvent = globalObject->currentEvent();
         globalObject->setCurrentEvent(event);
 
-        ASSERT(event->isErrorEvent());
-        ErrorEvent* errorEvent = static_cast<ErrorEvent*>(event);
-
         MarkedArgumentBuffer args;
         args.append(jsString(exec, errorEvent->message()));
         args.append(jsString(exec, errorEvent->filename()));
@@ -106,11 +103,7 @@ void JSWorkerContextErrorHandler::handleEvent(ScriptExecutionContext* scriptExec
             if (returnValue.getBoolean(retvalbool) && !retvalbool)
                 event->preventDefault();
         }
-
-        deref();
     }
 }
 
 } // namespace WebCore
-
-#endif // ENABLE(WORKERS)
similarity index 69%
rename from WebCore/bindings/js/JSWorkerContextErrorHandler.h
rename to WebCore/bindings/js/JSErrorHandler.h
index a188299..957fd81 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef JSWorkerContextErrorHandler_h
-#define JSWorkerContextErrorHandler_h
+#ifndef JSErrorHandler_h
+#define JSErrorHandler_h
 
 #include "JSEventListener.h"
 
 namespace WebCore {
 
-class JSWorkerContextErrorHandler : public JSEventListener {
+class JSErrorHandler : public JSEventListener {
 public:
-    static PassRefPtr<JSWorkerContextErrorHandler> create(JSC::JSObject* listener, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld)
+    static PassRefPtr<JSErrorHandler> create(JSC::JSObject* listener, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld)
     {
-        return adoptRef(new JSWorkerContextErrorHandler(listener, wrapper, isAttribute, isolatedWorld));
+        return adoptRef(new JSErrorHandler(listener, wrapper, isAttribute, isolatedWorld));
     }
 
-    virtual ~JSWorkerContextErrorHandler();
+    virtual ~JSErrorHandler();
 
 private:
-    JSWorkerContextErrorHandler(JSC::JSObject* function, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld);
+    JSErrorHandler(JSC::JSObject* function, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld);
     virtual void handleEvent(ScriptExecutionContext*, Event*);
 };
 
 // Creates a JS EventListener for "onerror" event handler in worker context. It has custom implementation because
 // unlike other event listeners it accepts three parameters.
-inline PassRefPtr<JSWorkerContextErrorHandler> createJSWorkerContextErrorHandler(JSC::ExecState* exec, JSC::JSValue listener, JSC::JSObject* wrapper)
+inline PassRefPtr<JSErrorHandler> createJSErrorHandler(JSC::ExecState* exec, JSC::JSValue listener, JSC::JSObject* wrapper)
 {
     if (!listener.isObject())
         return 0;
 
-    return JSWorkerContextErrorHandler::create(asObject(listener), wrapper, true, currentWorld(exec));
+    return JSErrorHandler::create(asObject(listener), wrapper, true, currentWorld(exec));
 }
 
 } // namespace WebCore
 
-#endif // JSWorkerContextErrorHandler_h
+#endif // JSErrorHandler_h
index 132518f..52a6291 100644 (file)
@@ -1709,9 +1709,9 @@ sub GenerateImplementation
                                 push(@implContent, "    JSDOMGlobalObject* globalObject = castedThis->globalObject();\n");
                             }
                             push(@implContent, "    $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(thisObject)->impl());\n");
-                            if ($interfaceName eq "WorkerContext" and $name eq "onerror") {
-                                $implIncludes{"JSWorkerContextErrorHandler.h"} = 1;
-                                push(@implContent, "    imp->set$implSetterFunctionName(createJSWorkerContextErrorHandler(exec, value, thisObject));\n");
+                            if ((($interfaceName eq "DOMWindow") or ($interfaceName eq "WorkerContext")) and $name eq "onerror") {
+                                $implIncludes{"JSErrorHandler.h"} = 1;
+                                push(@implContent, "    imp->set$implSetterFunctionName(createJSErrorHandler(exec, value, thisObject));\n");
                             } else {
                                 push(@implContent, GenerateAttributeEventListenerCall($className, $implSetterFunctionName, $windowEventListener));
                             }
index d339d6a..9093757 100644 (file)
@@ -1001,6 +1001,10 @@ END
                 $implIncludes{"V8EventListenerList.h"} = 1;
                 $implIncludes{"V8WorkerContextErrorHandler.h"} = 1;
                 push(@implContentDecls, "    imp->set$implSetterFunctionName(V8EventListenerList::findOrCreateWrapper<V8WorkerContextErrorHandler>(value, true)");
+            } elsif ($interfaceName eq "DOMWindow" and $attribute->signature->name eq "onerror") {
+                $implIncludes{"V8EventListenerList.h"} = 1;
+                $implIncludes{"V8WindowErrorHandler.h"} = 1;
+                push(@implContentDecls, "    imp->set$implSetterFunctionName(V8EventListenerList::findOrCreateWrapper<V8WindowErrorHandler>(value, true)");
             } else {
                 push(@implContentDecls, "    imp->set$implSetterFunctionName(V8DOMWrapper::getEventListener(value, true, ListenerFindOrCreate)");
             }
index e6871fd..d92822c 100644 (file)
@@ -54,7 +54,14 @@ V8ConsoleMessage::V8ConsoleMessage(const String& string, const String& sourceID,
 
 void V8ConsoleMessage::dispatchNow(Page* page)
 {
-    dispatchNow(page, 0);
+    ASSERT(page);
+
+    // Process any delayed messages to make sure that messages
+    // appear in the right order in the console.
+    processDelayed();
+
+    Console* console = page->mainFrame()->domWindow()->console();
+    console->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, m_string, m_lineNumber, m_sourceID);
 }
 
 void V8ConsoleMessage::dispatchLater()
@@ -105,8 +112,8 @@ void V8ConsoleMessage::handler(v8::Handle<v8::Message> message, v8::Handle<v8::V
     Frame* frame = V8Proxy::retrieveFrameForEnteredContext();
     if (!frame)
         return;
-    Page* page = frame->page();
-    if (!page)
+    Document* document = frame->document();
+    if (!document)
         return;
 
     v8::Handle<v8::String> errorMessageString = message->Get();
@@ -122,21 +129,7 @@ void V8ConsoleMessage::handler(v8::Handle<v8::Message> message, v8::Handle<v8::V
     v8::Handle<v8::Value> resourceName = message->GetScriptResourceName();
     bool useURL = resourceName.IsEmpty() || !resourceName->IsString();
     String resourceNameString = useURL ? frame->document()->url() : toWebCoreString(resourceName);
-    V8ConsoleMessage consoleMessage(errorMessage, resourceNameString, message->GetLineNumber());
-    consoleMessage.dispatchNow(page, callStack);
-}
-
-void V8ConsoleMessage::dispatchNow(Page* page, PassRefPtr<ScriptCallStack> callStack)
-{
-    ASSERT(page);
-
-    // Process any delayed messages to make sure that messages
-    // appear in the right order in the console.
-    processDelayed();
-
-    Console* console = page->mainFrame()->domWindow()->console();
-    MessageType messageType = callStack ? UncaughtExceptionMessageType : LogMessageType;
-    console->addMessage(JSMessageSource, messageType, ErrorMessageLevel, m_string, m_lineNumber, m_sourceID, callStack);
+    document->reportException(errorMessage, message->GetLineNumber(), resourceNameString, callStack);
 }
 
 } // namespace WebCore
index 97de24f..6183fc6 100644 (file)
@@ -82,8 +82,6 @@ namespace WebCore {
         const String m_sourceID;
         const unsigned m_lineNumber;
 
-        void dispatchNow(Page*, PassRefPtr<ScriptCallStack>);
-
         // All delayed messages are stored in this vector. If the vector
         // is 0, there are no delayed messages.
         static Vector<V8ConsoleMessage>* m_delayedMessages;
diff --git a/WebCore/bindings/v8/V8WindowErrorHandler.cpp b/WebCore/bindings/v8/V8WindowErrorHandler.cpp
new file mode 100755 (executable)
index 0000000..a74bad4
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "V8WindowErrorHandler.h"
+
+#include "ErrorEvent.h"
+#include "V8Binding.h"
+
+namespace WebCore {
+
+V8WindowErrorHandler::V8WindowErrorHandler(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext)
+    : V8EventListener(listener, isInline, worldContext)
+{
+}
+
+v8::Local<v8::Value> V8WindowErrorHandler::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
+{
+    ASSERT(event->isErrorEvent());
+    ErrorEvent* errorEvent = static_cast<ErrorEvent*>(event);
+    v8::Local<v8::Object> listener = getListenerObject(context);
+    v8::Local<v8::Value> returnValue;
+    if (!listener.IsEmpty() && listener->IsFunction()) {
+        v8::Local<v8::Function> callFunction = v8::Local<v8::Function>::Cast(listener);
+        v8::Local<v8::Object> thisValue = v8::Context::GetCurrent()->Global();
+        v8::Handle<v8::Value> parameters[3] = { v8String(errorEvent->message()), v8String(errorEvent->filename()), v8::Integer::New(errorEvent->lineno()) };
+        returnValue = callFunction->Call(thisValue, 3, parameters);
+        if (!returnValue.IsEmpty() && returnValue->IsBoolean() && !returnValue->BooleanValue())
+            event->preventDefault();
+    }
+    return returnValue;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8WindowErrorHandler.h b/WebCore/bindings/v8/V8WindowErrorHandler.h
new file mode 100755 (executable)
index 0000000..167ca0d
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8WindowErrorHandler_h
+#define V8WindowErrorHandler_h
+
+#include "V8CustomEventListener.h"
+#include <v8.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+class V8WindowErrorHandler : public V8EventListener {
+public:
+    static PassRefPtr<V8WindowErrorHandler> create(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext)
+    {
+        return adoptRef(new V8WindowErrorHandler(listener, isInline, worldContext));
+    }
+
+private:
+    V8WindowErrorHandler(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext);
+
+    virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
+};
+
+} // namespace WebCore
+
+#endif // V8WindowErrorHandler_h
index cefb2fa..eb25814 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "DedicatedWorkerContext.h"
 #include "Event.h"
+#include "ScriptCallStack.h"
 #include "SharedWorker.h"
 #include "SharedWorkerContext.h"
 #include "V8Binding.h"
@@ -72,7 +73,7 @@ static void v8MessageHandler(v8::Handle<v8::Message> message, v8::Handle<v8::Val
         String errorMessage = toWebCoreString(message->Get());
         int lineNumber = message->GetLineNumber();
         String sourceURL = toWebCoreString(message->GetScriptResourceName());
-        context->reportException(errorMessage, lineNumber, sourceURL);
+        context->reportException(errorMessage, lineNumber, sourceURL, 0);
     }
 
     isReportingException = false;
index b56d383..42e02e6 100644 (file)
 
 #include "WorkerScriptController.h"
 
-#include <v8.h>
-
+#include "DOMTimer.h"
+#include "ScriptCallStack.h"
 #include "ScriptSourceCode.h"
 #include "ScriptValue.h"
-#include "DOMTimer.h"
 #include "V8DOMMap.h"
 #include "V8Proxy.h"
 #include "V8WorkerContext.h"
@@ -46,6 +45,7 @@
 #include "WorkerContextExecutionProxy.h"
 #include "WorkerObjectProxy.h"
 #include "WorkerThread.h"
+#include <v8.h>
 
 namespace WebCore {
 
@@ -80,7 +80,7 @@ ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode,
         if (exception)
             *exception = state.exception;
         else
-            m_workerContext->reportException(state.errorMessage, state.lineNumber, state.sourceURL);
+            m_workerContext->reportException(state.errorMessage, state.lineNumber, state.sourceURL, 0);
     }
 
     return result;
index 775a2ad..743e287 100644 (file)
 #include "RenderTextControl.h"
 #include "RenderView.h"
 #include "RenderWidget.h"
+#include "ScriptCallStack.h"
 #include "ScriptController.h"
 #include "ScriptElement.h"
 #include "ScriptEventListener.h"
@@ -2271,6 +2272,17 @@ KURL Document::virtualCompleteURL(const String& url) const
     return completeURL(url);
 }
 
+EventTarget* Document::errorEventTarget()
+{
+    return domWindow();
+}
+
+void Document::logExceptionToConsole(const String& errorMessage, int lineNumber, const String& sourceURL, PassRefPtr<ScriptCallStack> callStack)
+{
+    MessageType messageType = callStack ? UncaughtExceptionMessageType : LogMessageType;
+    addMessage(JSMessageSource, messageType, ErrorMessageLevel, errorMessage, lineNumber, sourceURL, callStack);
+}
+
 void Document::setURL(const KURL& url)
 {
     const KURL& newURL = url.isEmpty() ? blankURL() : url;
@@ -4660,15 +4672,10 @@ void Document::parseDNSPrefetchControlHeader(const String& dnsPrefetchControl)
     m_haveExplicitlyDisabledDNSPrefetch = true;
 }
 
-void Document::reportException(const String& errorMessage, int lineNumber, const String& sourceURL)
-{
-    addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, errorMessage, lineNumber, sourceURL);
-}
-
-void Document::addMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL)
+void Document::addMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL, PassRefPtr<ScriptCallStack> callStack)
 {
     if (DOMWindow* window = domWindow())
-        window->console()->addMessage(source, type, level, message, lineNumber, sourceURL);
+        window->console()->addMessage(source, type, level, message, lineNumber, sourceURL, callStack);
 }
 
 struct PerformTaskContext : Noncopyable {
index f1fe44c..3b86b97 100644 (file)
@@ -930,8 +930,7 @@ public:
     bool isDNSPrefetchEnabled() const { return m_isDNSPrefetchEnabled; }
     void parseDNSPrefetchControlHeader(const String&);
 
-    virtual void reportException(const String& errorMessage, int lineNumber, const String& sourceURL);
-    virtual void addMessage(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL);
+    virtual void addMessage(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL, PassRefPtr<ScriptCallStack>);
     virtual void postTask(PassOwnPtr<Task>); // Executes the task on context's thread asynchronously.
 
 #if USE(JSC)
@@ -1116,6 +1115,9 @@ private:
     virtual const KURL& virtualURL() const; // Same as url(), but needed for ScriptExecutionContext to implement it without a performance loss for direct calls.
     virtual KURL virtualCompleteURL(const String&) const; // Same as completeURL() for the same reason as above.
 
+    virtual EventTarget* errorEventTarget();
+    virtual void logExceptionToConsole(const String& errorMessage, int lineNumber, const String& sourceURL, PassRefPtr<ScriptCallStack>);
+
     void initDNSPrefetch();
 
     String encoding() const;
index bfda17b..e0bac1e 100644 (file)
 #include "Database.h"
 #include "DatabaseTask.h"
 #include "DatabaseThread.h"
+#include "ErrorEvent.h"
+#include "EventListener.h"
+#include "EventTarget.h"
 #include "FileThread.h"
 #include "MessagePort.h"
+#include "ScriptCallStack.h"
 #include "SecurityOrigin.h"
 #include "ThreadableBlobRegistry.h"
 #include "WorkerContext.h"
 #include "WorkerThread.h"
 #include <wtf/MainThread.h>
 #include <wtf/PassRefPtr.h>
+#include <wtf/Vector.h>
 
 #if USE(JSC)
 #include "JSDOMWindow.h"
@@ -61,10 +66,26 @@ public:
     }
 };
 
+class ScriptExecutionContext::PendingException : public Noncopyable {
+public:
+    PendingException(const String& errorMessage, int lineNumber, const String& sourceURL, PassRefPtr<ScriptCallStack> callStack)
+        : m_errorMessage(errorMessage)
+        , m_lineNumber(lineNumber)
+        , m_sourceURL(sourceURL)
+        , m_callStack(callStack)
+    {
+    }
+    String m_errorMessage;
+    int m_lineNumber;
+    String m_sourceURL;
+    RefPtr<ScriptCallStack> m_callStack;
+};
+
 ScriptExecutionContext::ScriptExecutionContext()
 #if ENABLE(DATABASE)
     : m_hasOpenDatabases(false)
 #endif
+    , m_inDispatchErrorEvent(false)
 {
 }
 
@@ -243,6 +264,43 @@ void ScriptExecutionContext::setSecurityOrigin(PassRefPtr<SecurityOrigin> securi
     m_securityOrigin = securityOrigin;
 }
 
+void ScriptExecutionContext::reportException(const String& errorMessage, int lineNumber, const String& sourceURL, PassRefPtr<ScriptCallStack> callStack)
+{
+    if (m_inDispatchErrorEvent) {
+        if (!m_pendingExceptions)
+            m_pendingExceptions = adoptPtr(new Vector<OwnPtr<PendingException> >());
+        m_pendingExceptions->append(adoptPtr(new PendingException(errorMessage, lineNumber, sourceURL, callStack)));
+        return;
+    }
+
+    // First report the original exception and only then all the nested ones.
+    if (!dispatchErrorEvent(errorMessage, lineNumber, sourceURL))
+        logExceptionToConsole(errorMessage, lineNumber, sourceURL, callStack);
+
+    if (!m_pendingExceptions)
+        return;
+
+    for (size_t i = 0; i < m_pendingExceptions->size(); i++) {
+        PendingException* e = m_pendingExceptions->at(i).get();
+        logExceptionToConsole(e->m_errorMessage, e->m_lineNumber, e->m_sourceURL, e->m_callStack);
+    }
+    m_pendingExceptions.clear();
+}
+
+bool ScriptExecutionContext::dispatchErrorEvent(const String& errorMessage, int lineNumber, const String& sourceURL)
+{
+    EventTarget* target = errorEventTarget();
+    if (!target)
+        return false;
+
+    ASSERT(!m_inDispatchErrorEvent);
+    m_inDispatchErrorEvent = true;
+    RefPtr<ErrorEvent> errorEvent = ErrorEvent::create(errorMessage, sourceURL, lineNumber);
+    target->dispatchEvent(errorEvent);
+    m_inDispatchErrorEvent = false;
+    return errorEvent->defaultPrevented();
+}
+
 void ScriptExecutionContext::addTimeout(int timeoutId, DOMTimer* timer)
 {
     ASSERT(!m_timeouts.contains(timeoutId));
index b46a0f4..de97042 100644 (file)
@@ -33,6 +33,7 @@
 #include <wtf/Forward.h>
 #include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
 #include <wtf/PassOwnPtr.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefPtr.h>
@@ -52,11 +53,14 @@ namespace WebCore {
     class DatabaseThread;
 #endif
     class DOMTimer;
+    class EventListener;
+    class EventTarget;
 #if ENABLE(BLOB) || ENABLE(FILE_SYSTEM)
     class FileThread;
 #endif
     class MessagePort;
     class SecurityOrigin;
+    class ScriptCallStack;
 #if ENABLE(INSPECTOR)
     class InspectorController;
 #endif
@@ -91,8 +95,8 @@ namespace WebCore {
         virtual InspectorController* inspectorController() const { return 0; }
 #endif
 
-        virtual void reportException(const String& errorMessage, int lineNumber, const String& sourceURL) = 0;
-        virtual void addMessage(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL) = 0;
+        void reportException(const String& errorMessage, int lineNumber, const String& sourceURL, PassRefPtr<ScriptCallStack>);
+        virtual void addMessage(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL, PassRefPtr<ScriptCallStack>) = 0;
 
         // Active objects are not garbage collected even if inaccessible, e.g. because their activity may result in callbacks being invoked.
         bool canSuspendActiveDOMObjects();
@@ -154,6 +158,10 @@ namespace WebCore {
         virtual const KURL& virtualURL() const = 0;
         virtual KURL virtualCompleteURL(const String&) const = 0;
 
+        virtual EventTarget* errorEventTarget() = 0;
+        virtual void logExceptionToConsole(const String& errorMessage, int lineNumber, const String& sourceURL, PassRefPtr<ScriptCallStack>) = 0;
+        bool dispatchErrorEvent(const String& errorMessage, int lineNumber, const String& sourceURL);
+
         void closeMessagePorts();
 
         RefPtr<SecurityOrigin> m_securityOrigin;
@@ -179,6 +187,9 @@ namespace WebCore {
 #if ENABLE(BLOB) || ENABLE(FILE_SYSTEM)
         RefPtr<FileThread> m_fileThread;
 #endif
+        bool m_inDispatchErrorEvent;
+        class PendingException;
+        OwnPtr<Vector<OwnPtr<PendingException> > > m_pendingExceptions;
     };
 
 } // namespace WebCore
index 358a742..e15d079 100644 (file)
@@ -41,6 +41,7 @@
 #include "EventNames.h"
 #include "Logging.h"
 #include "MessageEvent.h"
+#include "ScriptCallStack.h"
 #include "ScriptExecutionContext.h"
 #include "ThreadableWebSocketChannel.h"
 #include "WebSocketChannel.h"
@@ -116,32 +117,32 @@ void WebSocket::connect(const KURL& url, const String& protocol, ExceptionCode&
     m_protocol = protocol;
 
     if (!m_url.isValid()) {
-        scriptExecutionContext()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Invalid url for WebSocket " + url.string(), 0, scriptExecutionContext()->securityOrigin()->toString());
+        scriptExecutionContext()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Invalid url for WebSocket " + url.string(), 0, scriptExecutionContext()->securityOrigin()->toString(), 0);
         m_state = CLOSED;
         ec = SYNTAX_ERR;
         return;
     }
 
     if (!m_url.protocolIs("ws") && !m_url.protocolIs("wss")) {
-        scriptExecutionContext()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Wrong url scheme for WebSocket " + url.string(), 0, scriptExecutionContext()->securityOrigin()->toString());
+        scriptExecutionContext()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Wrong url scheme for WebSocket " + url.string(), 0, scriptExecutionContext()->securityOrigin()->toString(), 0);
         m_state = CLOSED;
         ec = SYNTAX_ERR;
         return;
     }
     if (m_url.hasFragmentIdentifier()) {
-        scriptExecutionContext()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "URL has fragment component " + url.string(), 0, scriptExecutionContext()->securityOrigin()->toString());
+        scriptExecutionContext()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "URL has fragment component " + url.string(), 0, scriptExecutionContext()->securityOrigin()->toString(), 0);
         m_state = CLOSED;
         ec = SYNTAX_ERR;
         return;
     }
     if (!isValidProtocolString(m_protocol)) {
-        scriptExecutionContext()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Wrong protocol for WebSocket '" + encodeProtocolString(m_protocol) + "'", 0, scriptExecutionContext()->securityOrigin()->toString());
+        scriptExecutionContext()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Wrong protocol for WebSocket '" + encodeProtocolString(m_protocol) + "'", 0, scriptExecutionContext()->securityOrigin()->toString(), 0);
         m_state = CLOSED;
         ec = SYNTAX_ERR;
         return;
     }
     if (!portAllowed(url)) {
-        scriptExecutionContext()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, makeString("WebSocket port ", String::number(url.port()), " blocked"), 0, scriptExecutionContext()->securityOrigin()->toString());
+        scriptExecutionContext()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, makeString("WebSocket port ", String::number(url.port()), " blocked"), 0, scriptExecutionContext()->securityOrigin()->toString(), 0);
         m_state = CLOSED;
         ec = SECURITY_ERR;
         return;
index 01c2bef..785f124 100644 (file)
@@ -41,6 +41,7 @@
 #include "Page.h"
 #include "PlatformString.h"
 #include "ProgressTracker.h"
+#include "ScriptCallStack.h"
 #include "ScriptExecutionContext.h"
 #include "SocketStreamError.h"
 #include "SocketStreamHandle.h"
@@ -155,7 +156,7 @@ void WebSocketChannel::didOpen(SocketStreamHandle* handle)
         InspectorInstrumentation::willSendWebSocketHandshakeRequest(m_context, m_identifier, m_handshake.clientHandshakeRequest());
     CString handshakeMessage = m_handshake.clientHandshakeMessage();
     if (!handle->send(handshakeMessage.data(), handshakeMessage.length())) {
-        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Error sending handshake message.", 0, m_handshake.clientOrigin());
+        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Error sending handshake message.", 0, m_handshake.clientOrigin(), 0);
         handle->close();
     }
 }
@@ -239,7 +240,7 @@ bool WebSocketChannel::appendToBuffer(const char* data, size_t len)
         m_bufferSize = newBufferSize;
         return true;
     }
-    m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, makeString("WebSocket frame (at ", String::number(static_cast<unsigned long>(newBufferSize)), " bytes) is too long."), 0, m_handshake.clientOrigin());
+    m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, makeString("WebSocket frame (at ", String::number(static_cast<unsigned long>(newBufferSize)), " bytes) is too long."), 0, m_handshake.clientOrigin(), 0);
     return false;
 }
 
index 5049098..ed98834 100644 (file)
@@ -41,6 +41,7 @@
 #include "HTTPHeaderMap.h"
 #include "KURL.h"
 #include "Logging.h"
+#include "ScriptCallStack.h"
 #include "ScriptExecutionContext.h"
 #include "SecurityOrigin.h"
 
@@ -319,7 +320,7 @@ int WebSocketHandshake::readServerHandshake(const char* header, size_t len)
     m_response.setStatusText(statusText);
     if (statusCode != 101) {
         m_mode = Failed;
-        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, makeString("Unexpected response code: ", String::number(statusCode)), 0, clientOrigin());
+        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, makeString("Unexpected response code: ", String::number(statusCode)), 0, clientOrigin(), 0);
         return len;
     }
     m_mode = Normal;
@@ -449,19 +450,19 @@ int WebSocketHandshake::readStatusLine(const char* header, size_t headerLength,
 
     const char* end = p + 1;
     if (end - header > INT_MAX) {
-        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Status line is too long: " + trimConsoleMessage(header, maxConsoleMessageSize + 1), 0, clientOrigin());
+        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Status line is too long: " + trimConsoleMessage(header, maxConsoleMessageSize + 1), 0, clientOrigin(), 0);
         return INT_MAX;
     }
     int lineLength = end - header;
 
     if (!space1 || !space2) {
-        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "No response code found: " + trimConsoleMessage(header, lineLength - 1), 0, clientOrigin());
+        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "No response code found: " + trimConsoleMessage(header, lineLength - 1), 0, clientOrigin(), 0);
         return lineLength;
     }
 
     // The line must end with "\r\n".
     if (*(end - 2) != '\r') {
-        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Status line does not end with CRLF", 0, clientOrigin());
+        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Status line does not end with CRLF", 0, clientOrigin(), 0);
         return lineLength;
     }
 
@@ -470,7 +471,7 @@ int WebSocketHandshake::readStatusLine(const char* header, size_t headerLength,
         return lineLength;
     for (int i = 0; i < 3; ++i)
         if (statusCodeString[i] < '0' || statusCodeString[i] > '9') {
-            m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Invalid status code: " + statusCodeString, 0, clientOrigin());
+            m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Invalid status code: " + statusCodeString, 0, clientOrigin(), 0);
             return lineLength;
         }
 
@@ -498,13 +499,13 @@ const char* WebSocketHandshake::readHTTPHeaders(const char* start, const char* e
                 if (name.isEmpty()) {
                     if (p + 1 < end && *(p + 1) == '\n')
                         return p + 2;
-                    m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "CR doesn't follow LF at " + trimConsoleMessage(p, end - p), 0, clientOrigin());
+                    m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "CR doesn't follow LF at " + trimConsoleMessage(p, end - p), 0, clientOrigin(), 0);
                     return 0;
                 }
-                m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Unexpected CR in name at " + trimConsoleMessage(name.data(), name.size()), 0, clientOrigin());
+                m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Unexpected CR in name at " + trimConsoleMessage(name.data(), name.size()), 0, clientOrigin(), 0);
                 return 0;
             case '\n':
-                m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Unexpected LF in name at " + trimConsoleMessage(name.data(), name.size()), 0, clientOrigin());
+                m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Unexpected LF in name at " + trimConsoleMessage(name.data(), name.size()), 0, clientOrigin(), 0);
                 return 0;
             case ':':
                 break;
@@ -525,7 +526,7 @@ const char* WebSocketHandshake::readHTTPHeaders(const char* start, const char* e
             case '\r':
                 break;
             case '\n':
-                m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Unexpected LF in value at " + trimConsoleMessage(value.data(), value.size()), 0, clientOrigin());
+                m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Unexpected LF in value at " + trimConsoleMessage(value.data(), value.size()), 0, clientOrigin(), 0);
                 return 0;
             default:
                 value.append(*p);
@@ -536,17 +537,17 @@ const char* WebSocketHandshake::readHTTPHeaders(const char* start, const char* e
             }
         }
         if (p >= end || *p != '\n') {
-            m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "CR doesn't follow LF after value at " + trimConsoleMessage(p, end - p), 0, clientOrigin());
+            m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "CR doesn't follow LF after value at " + trimConsoleMessage(p, end - p), 0, clientOrigin(), 0);
             return 0;
         }
         AtomicString nameStr(String::fromUTF8(name.data(), name.size()));
         String valueStr = String::fromUTF8(value.data(), value.size());
         if (nameStr.isNull()) {
-            m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "invalid UTF-8 sequence in header name", 0, clientOrigin());
+            m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "invalid UTF-8 sequence in header name", 0, clientOrigin(), 0);
             return 0;
         }
         if (valueStr.isNull()) {
-            m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "invalid UTF-8 sequence in header value", 0, clientOrigin());
+            m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "invalid UTF-8 sequence in header value", 0, clientOrigin(), 0);
             return 0;
         }
         LOG(Network, "name=%s value=%s", nameStr.string().utf8().data(), valueStr.utf8().data());
@@ -570,24 +571,24 @@ void WebSocketHandshake::processHeaders()
 bool WebSocketHandshake::checkResponseHeaders()
 {
     if (m_wsOrigin.isNull()) {
-        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Error during WebSocket handshake: 'sec-websocket-origin' header is missing", 0, clientOrigin());
+        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Error during WebSocket handshake: 'sec-websocket-origin' header is missing", 0, clientOrigin(), 0);
         return false;
     }
     if (m_wsLocation.isNull()) {
-        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Error during WebSocket handshake: 'sec-websocket-location' header is missing", 0, clientOrigin());
+        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Error during WebSocket handshake: 'sec-websocket-location' header is missing", 0, clientOrigin(), 0);
         return false;
     }
 
     if (clientOrigin() != m_wsOrigin) {
-        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Error during WebSocket handshake: origin mismatch: " + clientOrigin() + " != " + m_wsOrigin, 0, clientOrigin());
+        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Error during WebSocket handshake: origin mismatch: " + clientOrigin() + " != " + m_wsOrigin, 0, clientOrigin(), 0);
         return false;
     }
     if (clientLocation() != m_wsLocation) {
-        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Error during WebSocket handshake: location mismatch: " + clientLocation() + " != " + m_wsLocation, 0, clientOrigin());
+        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Error during WebSocket handshake: location mismatch: " + clientLocation() + " != " + m_wsLocation, 0, clientOrigin(), 0);
         return false;
     }
     if (!m_clientProtocol.isEmpty() && m_clientProtocol != m_wsProtocol) {
-        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Error during WebSocket handshake: protocol mismatch: " + m_clientProtocol + " != " + m_wsProtocol, 0, clientOrigin());
+        m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Error during WebSocket handshake: protocol mismatch: " + m_clientProtocol + " != " + m_wsProtocol, 0, clientOrigin(), 0);
         return false;
     }
     return true;
index 4a8e947..8e1c106 100644 (file)
@@ -42,6 +42,7 @@
 #include "MessagePort.h"
 #include "NotImplemented.h"
 #include "PlatformString.h"
+#include "ScriptCallStack.h"
 #include "SecurityOrigin.h"
 #include "SecurityOriginHash.h"
 #include "SharedWorker.h"
@@ -155,7 +156,7 @@ void SharedWorkerProxy::postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutio
 
 static void postExceptionTask(ScriptExecutionContext* context, const String& errorMessage, int lineNumber, const String& sourceURL)
 {
-    context->reportException(errorMessage, lineNumber, sourceURL);
+    context->reportException(errorMessage, lineNumber, sourceURL, 0);
 }
 
 void SharedWorkerProxy::postExceptionToWorkerObject(const String& errorMessage, int lineNumber, const String& sourceURL)
@@ -167,7 +168,7 @@ void SharedWorkerProxy::postExceptionToWorkerObject(const String& errorMessage,
 
 static void postConsoleMessageTask(ScriptExecutionContext* document, MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL)
 {
-    document->addMessage(source, type, level, message, lineNumber, sourceURL);
+    document->addMessage(source, type, level, message, lineNumber, sourceURL, 0);
 }
 
 void SharedWorkerProxy::postConsoleMessageToWorkerObject(MessageSource source, MessageType type, MessageLevel level, const String& message, int lineNumber, const String& sourceURL)
index 345e5b7..03defc7 100644 (file)
@@ -46,6 +46,7 @@
 #include "KURL.h"
 #include "MessagePort.h"
 #include "NotImplemented.h"
+#include "ScriptCallStack.h"
 #include "ScriptSourceCode.h"
 #include "ScriptValue.h"
 #include "SecurityOrigin.h"
@@ -102,7 +103,6 @@ WorkerContext::WorkerContext(const KURL& url, const String& userAgent, WorkerThr
     , m_script(new WorkerScriptController(this))
     , m_thread(thread)
     , m_closing(false)
-    , m_reportingException(false)
 {
     setSecurityOrigin(SecurityOrigin::create(url));
 }
@@ -259,23 +259,17 @@ void WorkerContext::importScripts(const Vector<String>& urls, ExceptionCode& ec)
     }
 }
 
-void WorkerContext::reportException(const String& errorMessage, int lineNumber, const String& sourceURL)
+EventTarget* WorkerContext::errorEventTarget()
 {
-    bool errorHandled = false;
-    if (!m_reportingException) {
-        if (onerror()) {
-            m_reportingException = true;
-            RefPtr<ErrorEvent> errorEvent(ErrorEvent::create(errorMessage, sourceURL, lineNumber));
-            onerror()->handleEvent(this, errorEvent.get());
-            errorHandled = errorEvent->defaultPrevented();
-            m_reportingException = false;
-        }
-    }
-    if (!errorHandled)
-        thread()->workerReportingProxy().postExceptionToWorkerObject(errorMessage, lineNumber, sourceURL);
+    return this;
+}
+
+void WorkerContext::logExceptionToConsole(const String& errorMessage, int lineNumber, const String& sourceURL, PassRefPtr<ScriptCallStack>)
+{
+    thread()->workerReportingProxy().postExceptionToWorkerObject(errorMessage, lineNumber, sourceURL);
 }
 
-void WorkerContext::addMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL)
+void WorkerContext::addMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL, PassRefPtr<ScriptCallStack>)
 {
     thread()->workerReportingProxy().postConsoleMessageToWorkerObject(source, type, level, message, lineNumber, sourceURL);
 }
index 5d15d94..e42b82a 100644 (file)
@@ -100,8 +100,7 @@ namespace WebCore {
         void clearInterval(int timeoutId);
 
         // ScriptExecutionContext
-        virtual void reportException(const String& errorMessage, int lineNumber, const String& sourceURL);
-        virtual void addMessage(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL);
+        virtual void addMessage(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL, PassRefPtr<ScriptCallStack>);
 
 #if ENABLE(NOTIFICATIONS)
         NotificationCenter* webkitNotifications() const;
@@ -174,6 +173,9 @@ namespace WebCore {
         virtual const KURL& virtualURL() const;
         virtual KURL virtualCompleteURL(const String&) const;
 
+        virtual EventTarget* errorEventTarget();
+        virtual void logExceptionToConsole(const String& errorMessage, int lineNumber, const String& sourceURL, PassRefPtr<ScriptCallStack>);
+
         KURL m_url;
         String m_userAgent;
 
@@ -187,7 +189,6 @@ namespace WebCore {
         mutable RefPtr<NotificationCenter> m_notifications;
 #endif
         bool m_closing;
-        bool m_reportingException;
         EventTargetData m_eventTargetData;
 
         HashSet<Observer*> m_workerObservers;
index 10700c6..735d143 100644 (file)
@@ -40,6 +40,7 @@
 #include "ExceptionCode.h"
 #include "InspectorController.h"
 #include "MessageEvent.h"
+#include "ScriptCallStack.h"
 #include "ScriptExecutionContext.h"
 #include "Worker.h"
 
@@ -131,7 +132,7 @@ private:
 
         bool errorHandled = !workerObject->dispatchEvent(ErrorEvent::create(m_errorMessage, m_sourceURL, m_lineNumber));
         if (!errorHandled)
-            context->reportException(m_errorMessage, m_lineNumber, m_sourceURL);
+            context->reportException(m_errorMessage, m_lineNumber, m_sourceURL, 0);
     }
 
     String m_errorMessage;
@@ -283,7 +284,7 @@ static void postConsoleMessageTask(ScriptExecutionContext* context, WorkerMessag
 {
     if (messagingProxy->askedToTerminate())
         return;
-    context->addMessage(source, type, level, message, lineNumber, sourceURL);
+    context->addMessage(source, type, level, message, lineNumber, sourceURL, 0);
 }
 
 void WorkerMessagingProxy::postConsoleMessageToWorkerObject(MessageSource source, MessageType type, MessageLevel level, const String& message, int lineNumber, const String& sourceURL)
index fc7eb9e..f5b2d8d 100644 (file)
@@ -39,6 +39,7 @@
 #include "InspectorInstrumentation.h"
 #include "ResourceError.h"
 #include "ResourceRequest.h"
+#include "ScriptCallStack.h"
 #include "SecurityOrigin.h"
 #include "Settings.h"
 #include "SharedBuffer.h"
@@ -811,7 +812,7 @@ static void reportUnsafeUsage(ScriptExecutionContext* context, const String& mes
         return;
     // FIXME: It's not good to report the bad usage without indicating what source line it came from.
     // We should pass additional parameters so we can tell the console where the mistake occurred.
-    context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message, 1, String());
+    context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message, 1, String(), 0);
 }
 
 void XMLHttpRequest::setRequestHeader(const AtomicString& name, const String& value, ExceptionCode& ec)
index 4fd3c76..33b991b 100644 (file)
@@ -1,3 +1,18 @@
+2010-12-13  Yury Semikhatsky  <yurys@chromium.org>
+
+        Reviewed by Adam Barth.
+
+        WebCore doesn't fire window.onerror event when uncaught JavaScript exceptions are thrown
+        https://bugs.webkit.org/show_bug.cgi?id=8519
+
+        Uncaught exceptions are propagated to window.onerror hander if one is present.
+        The handler is expected to be a function accepting three arguments: error message,
+        resource url and line number where the exception occured.
+
+        * src/WebWorkerClientImpl.cpp:
+        (WebKit::WebWorkerClientImpl::postExceptionToWorkerObject):
+        (WebKit::WebWorkerClientImpl::postExceptionToWorkerObjectTask):
+
 2010-12-13  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r73898.
index 18282e3..f90e7e8 100644 (file)
@@ -41,6 +41,7 @@
 #include "MessageEvent.h"
 #include "MessagePort.h"
 #include "MessagePortChannel.h"
+#include "ScriptCallStack.h"
 #include "ScriptExecutionContext.h"
 #include "Worker.h"
 #include "WorkerContext.h"
@@ -247,7 +248,7 @@ void WebWorkerClientImpl::postExceptionToWorkerObject(const WebString& errorMess
                                                                 sourceURL,
                                                                 lineNumber));
     if (unhandled)
-        m_scriptExecutionContext->reportException(errorMessage, lineNumber, sourceURL);
+        m_scriptExecutionContext->reportException(errorMessage, lineNumber, sourceURL, 0);
 }
 
 void WebWorkerClientImpl::postConsoleMessageToWorkerObject(int destination,
@@ -274,7 +275,7 @@ void WebWorkerClientImpl::postConsoleMessageToWorkerObject(int destination,
                                          static_cast<MessageType>(messageType),
                                          static_cast<MessageLevel>(messageLevel),
                                          String(message), lineNumber,
-                                         String(sourceURL));
+                                         String(sourceURL), 0);
 }
 
 void WebWorkerClientImpl::postConsoleMessageToWorkerObject(int sourceId,
@@ -381,9 +382,7 @@ void WebWorkerClientImpl::postExceptionToWorkerObjectTask(
                                                                       sourceURL,
                                                                       lineNumber));
     if (!handled)
-        thisPtr->m_scriptExecutionContext->reportException(errorMessage,
-                                                           lineNumber,
-                                                           sourceURL);
+        thisPtr->m_scriptExecutionContext->reportException(errorMessage, lineNumber, sourceURL, 0);
 }
 
 void WebWorkerClientImpl::postConsoleMessageToWorkerObjectTask(ScriptExecutionContext* context,
@@ -398,8 +397,7 @@ void WebWorkerClientImpl::postConsoleMessageToWorkerObjectTask(ScriptExecutionCo
     thisPtr->m_scriptExecutionContext->addMessage(static_cast<MessageSource>(sourceId),
                                                   static_cast<MessageType>(messageType),
                                                   static_cast<MessageLevel>(messageLevel),
-                                                  message, lineNumber,
-                                                  sourceURL);
+                                                  message, lineNumber, sourceURL, 0);
 }
 
 void WebWorkerClientImpl::confirmMessageFromWorkerObjectTask(ScriptExecutionContext* context,