Title: [193646] trunk/Source
Revision
193646
Author
bb...@apple.com
Date
2015-12-07 12:57:35 -0800 (Mon, 07 Dec 2015)

Log Message

Web Inspector: Uncaught Exception page should have better styles and handle more error cases
https://bugs.webkit.org/show_bug.cgi?id=151923

Reviewed by Timothy Hatcher.

Source/WebCore:

Add a check for InspectorFrontendAPI before calling it. This can fail
easily if an uncaught exception stalls initial loading, or whenever
the Inspector frontend is reloaded.

* inspector/InspectorFrontendClientLocal.cpp:
(WebCore::InspectorFrontendClientLocal::evaluateOnLoad):

Source/WebInspectorUI:

Restructure the Uncaught Exception reporting page to act more like
a modal sheet. Distinguish between uncaught exceptions before and
after the frontend is initially loaded. If the frontend is loaded,
add a clickable link that dismisses the sheet and ignores the error.
If the inspector finished loading, then only show at most one
exception at a time, since subsequent interactions can cause spurious
errors when the sheet is active.

Split existing code into multiple functions so it's easier to follow.
Add miscellaneous guards against internal corruption and weird cases.

* UserInterface/Base/Main.js:
(WebInspector.contentLoaded): Store the flag on the global object
in case WebInspector becomes shadowed or otherwise unusable.

* UserInterface/Debug/UncaughtExceptionReporter.css: Renamed from Source/WebInspectorUI/UserInterface/Debug/CatchEarlyErrors.css.
(div.sheet-container):
(div.uncaught-exception-sheet):
(div.uncaught-exception-sheet a):
(div.uncaught-exception-sheet a:active):
(div.uncaught-exception-sheet h2):
(div.uncaught-exception-sheet h1 > img):
(div.uncaught-exception-sheet h2 > img):
(div.uncaught-exception-sheet dl):
(div.uncaught-exception-sheet dt):
(div.uncaught-exception-sheet dd):
(div.uncaught-exception-sheet ul):
(div.uncaught-exception-sheet li):
* UserInterface/Debug/UncaughtExceptionReporter.js: Renamed from CatchEarlyErrors.js.
(stopEventPropagation): Allow clicking whitelisted links on the sheet.
(blockEventHandlers):
(unblockEventHandlers):
(handleUncaughtException):
(dismissErrorSheet):
(createErrorSheet.insertWordBreakCharacters):
(createErrorSheet):
(handleLinkClick):
* UserInterface/Main.html:
* UserInterface/Protocol/MessageDispatcher.js:
(WebInspector.dispatchMessageFromBackend): Don't try to dispatch
messages from the backend when showing the error sheet. They will
probably fail, so suspend dispatching until the sheet is dismissed.

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (193645 => 193646)


--- trunk/Source/WebCore/ChangeLog	2015-12-07 20:37:03 UTC (rev 193645)
+++ trunk/Source/WebCore/ChangeLog	2015-12-07 20:57:35 UTC (rev 193646)
@@ -1,3 +1,17 @@
+2015-12-07  Brian Burg  <bb...@apple.com>
+
+        Web Inspector: Uncaught Exception page should have better styles and handle more error cases
+        https://bugs.webkit.org/show_bug.cgi?id=151923
+
+        Reviewed by Timothy Hatcher.
+
+        Add a check for InspectorFrontendAPI before calling it. This can fail
+        easily if an uncaught exception stalls initial loading, or whenever
+        the Inspector frontend is reloaded.
+
+        * inspector/InspectorFrontendClientLocal.cpp:
+        (WebCore::InspectorFrontendClientLocal::evaluateOnLoad):
+
 2015-12-07  Beth Dakin  <bda...@apple.com>
 
         Hook up request and show for typing candidates in WK1

Modified: trunk/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp (193645 => 193646)


--- trunk/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp	2015-12-07 20:37:03 UTC (rev 193645)
+++ trunk/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp	2015-12-07 20:57:35 UTC (rev 193646)
@@ -371,7 +371,7 @@
 void InspectorFrontendClientLocal::evaluateOnLoad(const String& _expression_)
 {
     if (m_frontendLoaded)
-        m_frontendPage->mainFrame().script().executeScript("InspectorFrontendAPI.dispatch(" + _expression_ + ")");
+        m_frontendPage->mainFrame().script().executeScript("if (InspectorFrontendAPI) InspectorFrontendAPI.dispatch(" + _expression_ + ")");
     else
         m_evaluateOnLoad.append(_expression_);
 }

Modified: trunk/Source/WebInspectorUI/ChangeLog (193645 => 193646)


--- trunk/Source/WebInspectorUI/ChangeLog	2015-12-07 20:37:03 UTC (rev 193645)
+++ trunk/Source/WebInspectorUI/ChangeLog	2015-12-07 20:57:35 UTC (rev 193646)
@@ -1,3 +1,53 @@
+2015-12-07  Brian Burg  <bb...@apple.com>
+
+        Web Inspector: Uncaught Exception page should have better styles and handle more error cases
+        https://bugs.webkit.org/show_bug.cgi?id=151923
+
+        Reviewed by Timothy Hatcher.
+
+        Restructure the Uncaught Exception reporting page to act more like
+        a modal sheet. Distinguish between uncaught exceptions before and
+        after the frontend is initially loaded. If the frontend is loaded,
+        add a clickable link that dismisses the sheet and ignores the error.
+        If the inspector finished loading, then only show at most one
+        exception at a time, since subsequent interactions can cause spurious
+        errors when the sheet is active.
+
+        Split existing code into multiple functions so it's easier to follow.
+        Add miscellaneous guards against internal corruption and weird cases.
+
+        * UserInterface/Base/Main.js:
+        (WebInspector.contentLoaded): Store the flag on the global object
+        in case WebInspector becomes shadowed or otherwise unusable.
+
+        * UserInterface/Debug/UncaughtExceptionReporter.css: Renamed from Source/WebInspectorUI/UserInterface/Debug/CatchEarlyErrors.css.
+        (div.sheet-container):
+        (div.uncaught-exception-sheet):
+        (div.uncaught-exception-sheet a):
+        (div.uncaught-exception-sheet a:active):
+        (div.uncaught-exception-sheet h2):
+        (div.uncaught-exception-sheet h1 > img):
+        (div.uncaught-exception-sheet h2 > img):
+        (div.uncaught-exception-sheet dl):
+        (div.uncaught-exception-sheet dt):
+        (div.uncaught-exception-sheet dd):
+        (div.uncaught-exception-sheet ul):
+        (div.uncaught-exception-sheet li):
+        * UserInterface/Debug/UncaughtExceptionReporter.js: Renamed from CatchEarlyErrors.js.
+        (stopEventPropagation): Allow clicking whitelisted links on the sheet.
+        (blockEventHandlers):
+        (unblockEventHandlers):
+        (handleUncaughtException):
+        (dismissErrorSheet):
+        (createErrorSheet.insertWordBreakCharacters):
+        (createErrorSheet):
+        (handleLinkClick):
+        * UserInterface/Main.html:
+        * UserInterface/Protocol/MessageDispatcher.js:
+        (WebInspector.dispatchMessageFromBackend): Don't try to dispatch
+        messages from the backend when showing the error sheet. They will
+        probably fail, so suspend dispatching until the sheet is dismissed.
+
 2015-12-06  Devin Rousso  <dcrousso+web...@gmail.com>
 
         Web Inspector: Regression (r192936) - changing selectors in the visual styles sidebar is broken

Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Main.js (193645 => 193646)


--- trunk/Source/WebInspectorUI/UserInterface/Base/Main.js	2015-12-07 20:37:03 UTC (rev 193645)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Main.js	2015-12-07 20:57:35 UTC (rev 193646)
@@ -175,8 +175,9 @@
 
 WebInspector.contentLoaded = function()
 {
-    // If a loading error page was already shown, then don't set up the Inspector UI.
-    if (window.__earlyErrors)
+    // If there was an uncaught exception earlier during loading, then
+    // abort loading more content. We could be in an inconsistent state.
+    if (window.__uncaughtExceptions)
         return;
 
     // Register for global events.
@@ -430,7 +431,8 @@
     if (this._showingSplitConsoleSetting.value)
         this.showSplitConsole();
 
-    this._contentLoaded = true;
+    // Store this on the window in case the WebInspector global gets corrupted.
+    window.__frontendCompletedLoad = true;
 
     if (this.runBootstrapOperations)
         this.runBootstrapOperations();

Deleted: trunk/Source/WebInspectorUI/UserInterface/Debug/CatchEarlyErrors.css (193645 => 193646)


--- trunk/Source/WebInspectorUI/UserInterface/Debug/CatchEarlyErrors.css	2015-12-07 20:37:03 UTC (rev 193645)
+++ trunk/Source/WebInspectorUI/UserInterface/Debug/CatchEarlyErrors.css	2015-12-07 20:57:35 UTC (rev 193646)
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2015 Apple 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:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
- */
-
-body.caught-early-error {
-    margin: 50px 65px;
-    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
-    font-size: 11pt;
-    max-width: 700px;
-    min-width: 400px;
-    background-color: #fefefe;
-    overflow: scroll;
-}
-
-body.caught-early-error h1,
-body.caught-early-error h2 {
-    font-size: 16pt;
-    font-weight: bold;
-    margin-bottom: 0px;
-    margin-top: 10px;
-}
-
-body.caught-early-error h1 > img {
-    height: 35px;
-    position: relative;
-    margin-left: -50px;
-    margin-top: -7px;
-    float: left;
-}
-
-body.caught-early-error h2 > img {
-    height: 25px;
-    position: relative;
-    margin-left: -45px;
-    margin-top: 0px;
-    float: left;
-}
-
-body.caught-early-error dt {
-    font-weight: 600;
-    font-style: italic;
-}
-
-body.caught-early-error dd {
-    margin: 10px 0 20px 10px;
-}
-
-body.caught-early-error ul {
-    font-family: Menlo, monospace;
-    font-size: 75%;
-    margin: 0;
-    padding: 0;
-}
-
-body.caught-early-error li {
-    margin-bottom: 20px;
-}

Deleted: trunk/Source/WebInspectorUI/UserInterface/Debug/CatchEarlyErrors.js (193645 => 193646)


--- trunk/Source/WebInspectorUI/UserInterface/Debug/CatchEarlyErrors.js	2015-12-07 20:37:03 UTC (rev 193645)
+++ trunk/Source/WebInspectorUI/UserInterface/Debug/CatchEarlyErrors.js	2015-12-07 20:57:35 UTC (rev 193646)
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2015 Apple 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:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
- */
-
-window._onerror_ = function(message, url, lineNumber, columnNumber) {
-    if (!window.__earlyErrors) {
-        window.__earlyErrors = [];
-        // Early errors like parse errors may happen in the <head>, so attach
-        // a body if none exists yet. Code below expects document.body to exist.
-        if (!document.body)
-            document.write("<body></body></html>");
-
-        // Prevent any event handlers from running in an inconsistent state.
-        function stopEventPropagation(event) {
-            event.stopPropagation();
-        }
-
-        let windowEvents = ["beforecopy", "copy", "click", "dragover", "focus"];
-        let documentEvents = ["focus", "blur", "resize", "keydown", "keyup", "mousemove", "pagehide", "contextmenu"];
-        for (let name of windowEvents)
-            window.addEventListener(name, stopEventPropagation, true);
-        for (let name of documentEvents)
-            document.addEventListener(name, stopEventPropagation, true);
-
-        // Don't tell InspectorFrontendAPI that loading is done, since it can
-        // clear some of the error boilerplate page by accident.
-
-        // Signal that loading is done even though we can't guarantee that
-        // evaluating code on the inspector page will do anything useful.
-        // Without this, the frontend host may never show the window.
-        if (InspectorFrontendHost) {
-            InspectorFrontendHost.loaded();
-            InspectorFrontendHost.inspectedURLChanged("Internal Error");
-        }
-    }
-
-    window.__earlyErrors.push({message, url, lineNumber, columnNumber});
-    let firstError = window.__earlyErrors[0];
-
-    let formattedErrorDetails = window.__earlyErrors.map((entry) => `${entry.message} (at ${entry.url}:${entry.lineNumber}:${entry.columnNumber})`);
-    let detailsForBugReport = formattedErrorDetails.map((line) => ` - ${line}`).join("\n");
-    let encodedBugDescription = encodeURIComponent(`Caught errors:\n${detailsForBugReport}`);
-    let encodedBugTitle = encodeURIComponent(`Uncaught Exception loading Web Inspector: ${firstError.message}`);
-    let prefilledBugReportLink = `https://bugs.webkit.org/enter_bug.cgi?alias=&assigned_to=webkit-unassigned%40lists.webkit.org&attach_text=&blocked=&bug_file_loc=http%3A%2F%2F&bug_severity=Normal&bug_status=NEW&comment=${encodedBugDescription}&component=Web%20Inspector&contenttypeentry=&contenttypemethod=autodetect&contenttypeselection=text%2Fplain&data=""
-    let detailsForHTML = formattedErrorDetails.map((line) => `<li>${line}</li>`).join("\n");
-    let errorPageHTML = `<h1>
-    <img src="" />
-    Web Inspector encountered an error while loading.
-    </h1>
-    <dl>
-        <dt>Why?</dt>
-        <dd>Usually, this is caused by a syntax error while modifying the Web Inspector
-        UI, or running an updated frontend with out-of-date WebKit build.</dt>
-        <dt>I didn't do anything...?</dt>
-        <dd>If you don't think you caused this error to happen,
-        <a href="" to file a pre-populated
-        bug with this information</a>. It's possible that someone else broke it by accident.</dd>
-        <dt>Oops, can I try again?</dt>
-        <dd><a href="" to reload the Inspector</a>
-        again after making local changes.</dd>
-    </dl>
-    <h2>
-    <img src="" />
-    These errors were caught while loading Inspector:
-    </h2>
-    <p><ul>${detailsForHTML}</ul></p>`;
-    document.body.classList.add("caught-early-error");
-    document.body.innerHTML = errorPageHTML;
-}

Copied: trunk/Source/WebInspectorUI/UserInterface/Debug/UncaughtExceptionReporter.css (from rev 193645, trunk/Source/WebInspectorUI/UserInterface/Debug/CatchEarlyErrors.css) (0 => 193646)


--- trunk/Source/WebInspectorUI/UserInterface/Debug/UncaughtExceptionReporter.css	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Debug/UncaughtExceptionReporter.css	2015-12-07 20:57:35 UTC (rev 193646)
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2015 Apple 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
+ */
+
+.sheet-container {
+    position: absolute;
+    left: 0;
+    right: 0;
+    top: 0;
+    bottom: 0;
+    z-index: 10000;
+    background-color: hsl(0, 0%, 96%);
+}
+
+.uncaught-exception-sheet {
+    padding: 50px 55px 50px 65px;
+    font-family: '-webkit-system-font';
+    font-size: 11pt;
+    overflow-y: auto;
+    min-width: 400px;
+    color: hsl(0, 0%, 40%);
+}
+
+.uncaught-exception-sheet a {
+    text-decoration: underline;
+    color: hsl(240, 55%, 30%);
+    cursor: pointer;
+    font-weight: 500;
+    font-size: 97%;
+}
+.uncaught-exception-sheet a:hover,
+.uncaught-exception-sheet a:active {
+    color: hsl(240, 55%, 25%);
+}
+
+.uncaught-exception-sheet h1,
+.uncaught-exception-sheet h2 {
+    font-size: 24px;
+    line-height: 28px;
+    margin-bottom: 0px;
+    margin-top: 10px;
+    font-weight: normal;
+}
+
+.uncaught-exception-sheet h2 {
+    margin-top: 40px;
+}
+
+.uncaught-exception-sheet h1 > img {
+    height: 35px;
+    position: relative;
+    margin-left: -50px;
+    margin-top: -5px;
+    float: left;
+}
+
+.uncaught-exception-sheet h2 > img {
+    height: 25px;
+    position: relative;
+    margin-left: -45px;
+    margin-top: 0px;
+    float: left;
+}
+
+.uncaught-exception-sheet dl {
+    max-width: 600px;
+}
+
+.uncaught-exception-sheet dt {
+    font-style: italic;
+    font-size: 17px;
+}
+
+.uncaught-exception-sheet dd {
+    margin: 10px 0 20px 10px;
+    font-size: 13px;
+    line-height: 18px;
+}
+
+.uncaught-exception-sheet ul {
+    font-family: Menlo, monospace;
+    font-size: 12px;
+    line-height: 18px;
+    margin: 0 0 0 2px;
+    padding: 0;
+}
+
+.uncaught-exception-sheet li {
+    margin-bottom: 20px;
+    word-break: break-word;
+}

Added: trunk/Source/WebInspectorUI/UserInterface/Debug/UncaughtExceptionReporter.js (0 => 193646)


--- trunk/Source/WebInspectorUI/UserInterface/Debug/UncaughtExceptionReporter.js	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Debug/UncaughtExceptionReporter.js	2015-12-07 20:57:35 UTC (rev 193646)
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2015 Apple 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
+ */
+
+(function() {
+
+const windowEvents = ["beforecopy", "copy", "click", "dragover", "focus"];
+const documentEvents = ["focus", "blur", "resize", "keydown", "keyup", "mousemove", "pagehide", "contextmenu"];
+
+function stopEventPropagation(event) {
+    if (event.target.classList && event.target.classList.contains("bypass-event-blocking"))
+        return;
+
+    event.stopPropagation();
+}
+
+function blockEventHandlers() {
+    // FIXME (151959): text selection on the sheet doesn't work for some reason.
+    for (let name of windowEvents)
+        window.addEventListener(name, stopEventPropagation, true);
+    for (let name of documentEvents)
+        document.addEventListener(name, stopEventPropagation, true);
+}
+
+function unblockEventHandlers() {
+    for (let name of windowEvents)
+        window.removeEventListener(name, stopEventPropagation, true);
+    for (let name of documentEvents)
+        document.removeEventListener(name, stopEventPropagation, true);
+}
+
+function handleUncaughtException(event) {
+    let exceptionRecord = {
+        message: event.message,
+        url: event.url,
+        lineNumber: event.lineno,
+        columnNumber: event.colno
+    };
+
+    if (!window.__uncaughtExceptions)
+        window.__uncaughtExceptions = [];
+
+    const loadCompleted = window.__frontendCompletedLoad;
+    const isFirstException = !window.__uncaughtExceptions.length;
+
+    // If an uncaught exception happens after loading is done, only show
+    // the first such exception. Many others may follow if internal
+    // state has been corrupted, but these are unhelpful to report.
+    if (!loadCompleted || isFirstException)
+        window.__uncaughtExceptions.push(exceptionRecord);
+
+    // If WebInspector.contentLoaded throws an uncaught exception, then these
+    // listeners will not work correctly because the UI is not fully loaded.
+    // Prevent any event handlers from running in an inconsistent state.
+    if (isFirstException)
+        blockEventHandlers();
+
+    if (isFirstException && !loadCompleted) {
+        // Signal that loading is done even though we can't guarantee that
+        // evaluating code on the inspector page will do anything useful.
+        // Without this, the frontend host may never show the window.
+        if (InspectorFrontendHost)
+            InspectorFrontendHost.loaded();
+
+        // Don't tell InspectorFrontendAPI that loading is done, since it can
+        // clear some of the error boilerplate page by accident.
+    }
+
+    createErrorSheet();
+}
+
+function dismissErrorSheet() {
+    unblockEventHandlers();
+
+    window.__sheetElement.remove();
+    window.__sheetElement = null;
+    window.__uncaughtExceptions = [];
+
+    // Do this last in case WebInspector's internal state is corrupted.
+    WebInspector.updateWindowTitle();
+
+    // FIXME (151959): tell the frontend host to hide a draggable title bar.
+}
+
+function createErrorSheet() {
+    // Early errors like parse errors may happen in the <head>, so attach
+    // a body if none exists yet. Code below expects document.body to exist.
+    if (!document.body)
+        document.write("<body></body></html>");
+
+    // FIXME (151959): tell the frontend host to show a draggable title bar.
+    if (InspectorFrontendHost)
+        InspectorFrontendHost.inspectedURLChanged("Internal Error");
+
+    // Only allow one sheet element at a time.
+    if (window.__sheetElement) {
+        window.__sheetElement.remove();
+        window.__sheetElement = null;
+    }
+
+    const loadCompleted = window.__frontendCompletedLoad;
+    let firstException = window.__uncaughtExceptions[0];
+
+    // Inlined from Utilities.js, because that file may not have loaded.
+    function insertWordBreakCharacters(text) {
+        return text.replace(/([\/;:\)\]\}&?])/g, "$1\u200b");
+    }
+
+    // This trampoline is necessary since none of our functions will be
+    // in scope of an href="" evaluation.
+    function handleLinkClick(event) {
+        if (event.target.tagName !== "A")
+            return;
+        if (event.target.id === "dismiss-error-sheet")
+            dismissErrorSheet();
+    }
+
+    let formattedErrorDetails = window.__uncaughtExceptions.map((entry) => `${entry.message} (at ${entry.url}:${entry.lineNumber}:${entry.columnNumber})`);
+    let detailsForBugReport = formattedErrorDetails.map((line) => ` - ${line}`).join("\n");
+    let encodedBugDescription = encodeURIComponent(`Loading completed: ${loadCompleted ? "true" : "false"}\nUncaught exceptions:\n${detailsForBugReport}`);
+    let encodedBugTitle = encodeURIComponent(`Uncaught Exception: ${firstException.message}`);
+    let prefilledBugReportLink = `https://bugs.webkit.org/enter_bug.cgi?alias=&assigned_to=webkit-unassigned%40lists.webkit.org&attach_text=&blocked=&bug_file_loc=http%3A%2F%2F&bug_severity=Normal&bug_status=NEW&comment=${encodedBugDescription}&component=Web%20Inspector&contenttypeentry=&contenttypemethod=autodetect&contenttypeselection=text%2Fplain&data=""
+    let detailsForHTML = formattedErrorDetails.map((line) => `<li>${insertWordBreakCharacters(line)}</li>`).join("\n");
+
+    let dismissOptionHTML = !loadCompleted ? "" : `<dt>A frivolous exception will not stop me!</dt>
+        <dd><a class="bypass-event-blocking" id="dismiss-error-sheet">Click to close this view</a> and return
+        to the Web Inspector without reloading. However, some things might not work without reloading if the error corrupted the Inspector's internal state.</dd>`;
+
+    let sheetElement = window.__sheetElement = document.createElement("div");
+    sheetElement.classList.add("sheet-container");
+    sheetElement.innerHTML = `<div class="uncaught-exception-sheet">
+    <h1>
+    <img src=""
+    Web Inspector encountered an internal error.
+    </h1>
+    <dl>
+        <dd>Usually, this is caused by a syntax error while modifying the Web Inspector
+        UI, or running an updated frontend with out-of-date WebKit build.</dt>
+        <dt>I didn't do anything...?</dt>
+        <dd>If you don't think you caused this error to happen,
+        <a href="" to file a pre-populated
+        bug with this information</a>. It is possible that someone else broke it by accident.</dd>
+        <dt>Oops, can I try again?</dt>
+        <dd><a href="" to reload the Inspector</a>
+        again after making local changes.</dd>
+        ${dismissOptionHTML}
+    </dl>
+    <h2>
+    <img src=""
+    These uncaught exceptions caused the problem:
+    </h2>
+    <p><ul>${detailsForHTML}</ul></p>
+    </div>`;
+
+    sheetElement.addEventListener("click", handleLinkClick, true);
+    document.body.appendChild(sheetElement);
+}
+
+window.addEventListener("error", handleUncaughtException);
+
+})();

Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (193645 => 193646)


--- trunk/Source/WebInspectorUI/UserInterface/Main.html	2015-12-07 20:37:03 UTC (rev 193645)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html	2015-12-07 20:57:35 UTC (rev 193646)
@@ -185,9 +185,9 @@
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
 
-    <link rel="stylesheet" href=""
+    <link rel="stylesheet" href=""
 
-    <script src=""
+    <script src=""
 
     <script src=""
 

Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/MessageDispatcher.js (193645 => 193646)


--- trunk/Source/WebInspectorUI/UserInterface/Protocol/MessageDispatcher.js	2015-12-07 20:37:03 UTC (rev 193645)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/MessageDispatcher.js	2015-12-07 20:57:35 UTC (rev 193646)
@@ -65,6 +65,12 @@
 
     this._messagesToDispatch.push(message);
 
+    // If something has gone wrong and the uncaught exception sheet is showing,
+    // then don't try to dispatch more messages. Dispatching causes spurious uncaught
+    // exceptions and cause the sheet to overflow with hundreds of logged exceptions.
+    if (window.__uncaughtExceptions && window.__uncaughtExceptions.length)
+        return;
+
     if (this._dispatchTimeout)
         return;
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to