<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[189338] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/189338">189338</a></dd>
<dt>Author</dt> <dd>bburg@apple.com</dd>
<dt>Date</dt> <dd>2015-09-03 20:58:43 -0700 (Thu, 03 Sep 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: InspectorController should support multiple frontend channels
https://bugs.webkit.org/show_bug.cgi?id=148538

Reviewed by Joseph Pecoraro.

Source/JavaScriptCore:

Instead of a singleton, it should be possible to have multiple channels open
at the same time and to individually close channels as frontends come and go.

The FrontendRouter class keeps a list of open FrontendChannels and sends messages
to the appropriate frontends based on whether the message is a response or event.
Each InspectorController owns a single FrontendRouter and BackendDispatcher instance.
Inspector backend code that sends messages to the frontend should switch over to
using the router rather than directly using a FrontendChannel.

* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* inspector/InspectorBackendDispatcher.cpp: Move constructors/destructors out of the header
to avoid including InspectorFrontendRouter everywhere. Use the router instead of a
specific frontend channel. Remove guards that are no longer necessary since the router
is guaranteed to outlive the backend dispatcher.

(Inspector::SupplementalBackendDispatcher::SupplementalBackendDispatcher):
(Inspector::SupplementalBackendDispatcher::~SupplementalBackendDispatcher):
(Inspector::BackendDispatcher::BackendDispatcher):
(Inspector::BackendDispatcher::create):
(Inspector::BackendDispatcher::isActive):
(Inspector::BackendDispatcher::registerDispatcherForDomain):
(Inspector::BackendDispatcher::sendResponse):
(Inspector::BackendDispatcher::sendPendingErrors):
* inspector/InspectorBackendDispatcher.h:
(Inspector::SupplementalBackendDispatcher::SupplementalBackendDispatcher): Deleted.
(Inspector::SupplementalBackendDispatcher::~SupplementalBackendDispatcher): Deleted.
(Inspector::BackendDispatcher::clearFrontend): Deleted, no longer necessary.
(Inspector::BackendDispatcher::isActive): Moved to implementation file.
(Inspector::BackendDispatcher::BackendDispatcher): Moved to implementation file.
* inspector/InspectorFrontendRouter.cpp: Added.
(Inspector::FrontendRouter::create):
(Inspector::FrontendRouter::connectFrontend):
(Inspector::FrontendRouter::disconnectFrontend):
(Inspector::FrontendRouter::disconnectAllFrontends):
(Inspector::FrontendRouter::leakChannel):
(Inspector::FrontendRouter::hasLocalFrontend):
(Inspector::FrontendRouter::hasRemoteFrontend):
(Inspector::FrontendRouter::sendEvent):
(Inspector::FrontendRouter::sendResponse):
* inspector/InspectorFrontendRouter.h: Added.
* inspector/JSGlobalObjectInspectorController.cpp: Remove guards that are no longer necessary.
The frontend router and backend dispatcher now have the same lifetime as the controller.
Explicitly connect/disconnect the frontend channel.

(Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
(Inspector::JSGlobalObjectInspectorController::globalObjectDestroyed):
(Inspector::JSGlobalObjectInspectorController::connectFrontend):
(Inspector::JSGlobalObjectInspectorController::disconnectFrontend):
(Inspector::JSGlobalObjectInspectorController::disconnectAllFrontends):
(Inspector::JSGlobalObjectInspectorController::dispatchMessageFromFrontend):
(Inspector::JSGlobalObjectInspectorController::appendExtraAgent):
(Inspector::JSGlobalObjectInspectorController::pause): Deleted.
* inspector/JSGlobalObjectInspectorController.h:
* inspector/agents/InspectorAgent.cpp:
* inspector/agents/InspectorConsoleAgent.cpp:
* inspector/agents/InspectorDebuggerAgent.cpp:
* inspector/agents/InspectorRuntimeAgent.cpp:
* inspector/augmentable/AugmentableInspectorController.h:
(Inspector::AugmentableInspectorController::connected):
* inspector/remote/RemoteInspectorDebuggable.h:
* inspector/remote/RemoteInspectorDebuggableConnection.mm:
(Inspector::RemoteInspectorDebuggableConnection::close):
* inspector/scripts/codegen/generate_cpp_alternate_backend_dispatcher_header.py:
(CppAlternateBackendDispatcherHeaderGenerator.generate_output):
* inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py:
(ObjCFrontendDispatcherImplementationGenerator._generate_event): Use the router.
* runtime/JSGlobalObjectDebuggable.cpp:
(JSC::JSGlobalObjectDebuggable::disconnect):
* runtime/JSGlobalObjectDebuggable.h:

Source/WebCore:

No new tests, no behavior change from this patch. Teardown scenarios are
covered by existing protocol and inspector tests running under DRT and WKTR.

* ForwardingHeaders/inspector/InspectorFrontendRouter.h: Added.
* WebCore.vcxproj/WebCore.vcxproj:
* inspector/InspectorClient.h: Stop using forwarded types.
* inspector/InspectorController.cpp:
(WebCore::InspectorController::InspectorController):
(WebCore::InspectorController::inspectedPageDestroyed):
(WebCore::InspectorController::hasLocalFrontend):
(WebCore::InspectorController::hasRemoteFrontend):
(WebCore::InspectorController::connectFrontend):
(WebCore::InspectorController::disconnectFrontend):
(WebCore::InspectorController::disconnectAllFrontends): Added. Disconnects all
frontends and signals DisconnectReason::InspectedTargetDestroyed.

(WebCore::InspectorController::show):
(WebCore::InspectorController::close):
(WebCore::InspectorController::dispatchMessageFromFrontend):
* inspector/InspectorController.h: Add default value for isAutomaticInspection.
* inspector/InspectorDatabaseAgent.cpp:
* inspector/InspectorIndexedDBAgent.cpp:
* inspector/InspectorResourceAgent.cpp:
* inspector/WorkerInspectorController.cpp: Use a router with a singleton channel
that forwards messages over to the main page.

(WebCore::WorkerInspectorController::WorkerInspectorController):
(WebCore::WorkerInspectorController::connectFrontend):
(WebCore::WorkerInspectorController::disconnectFrontend):
(WebCore::WorkerInspectorController::dispatchMessageFromFrontend):
* inspector/WorkerInspectorController.h:
* page/PageDebuggable.cpp:
(WebCore::PageDebuggable::disconnect):
* page/PageDebuggable.h:
* testing/Internals.cpp: Clear the frontend client before disconnecting frontend channel.
(WebCore::Internals::openDummyInspectorFrontend):
(WebCore::Internals::closeDummyInspectorFrontend):

Source/WebKit/mac:

Remove the notifyInspectorController flag from closeWindow. Since InspectorClients
must now manually disconnect their FrontendChannel(s), we should always
perform the teardown that was guarded by this flag.

* WebCoreSupport/WebInspectorClient.h:
* WebCoreSupport/WebInspectorClient.mm:
(WebInspectorClient::bringFrontendToFront): Add a missing assertion.
(WebInspectorFrontendClient::closeWindow):
(WebInspectorFrontendClient::disconnectFromBackend):
(-[WebInspectorWindowController windowShouldClose:]):
(-[WebInspectorWindowController destroyInspectorView]): Always clear the frontend client.
(-[WebInspectorWindowController destroyInspectorView:]): Renamed to above.

Source/WebKit/win:

Remove the notifyInspectorController flag from closeWindow. Since InspectorClients
must now manually disconnect their FrontendChannel(s), we should always
perform the teardown that was guarded by this flag.

* WebCoreSupport/WebInspectorClient.cpp:
(WebInspectorClient::closeInspectorFrontend):
(WebInspectorFrontendClient::~WebInspectorFrontendClient):
(WebInspectorFrontendClient::closeWindow):
(WebInspectorFrontendClient::destroyInspectorView):
* WebCoreSupport/WebInspectorClient.h:

Source/WebKit2:

Explicitly disconnect the frontend channel when closing the frontend.

Rename createInspectorPage/closeFrontend to the symmetric and unambiguous
{open,close}FrontendConnection in the WebInspector class.

* WebProcess/WebCoreSupport/WebInspectorClient.cpp:
(WebKit::WebInspectorClient::openInspectorFrontend):
(WebKit::WebInspectorClient::closeInspectorFrontend):
* WebProcess/WebCoreSupport/WebInspectorClient.h: Stop using a forwarded type.
* WebProcess/WebPage/WebInspector.cpp:
(WebKit::WebInspector::openFrontendConnection):
(WebKit::WebInspector::closeFrontendConnection):
(WebKit::WebInspector::remoteFrontendConnected):
(WebKit::WebInspector::remoteFrontendDisconnected):
(WebKit::WebInspector::createInspectorPage): Deleted.
(WebKit::WebInspector::closeFrontend): Deleted.
* WebProcess/WebPage/WebInspector.h:

Tools:

InspectorClients must explicitly disconnect their frontend channel(s) from the
inspected page's InspectorController.

To make this possible, DumpRenderTree should not destroy non-primary views until
it has tried to close any abandoned Web Inspector instances. Performing teardown
in the reverse order prevents disconnection of the frontend channel because that
prematurely destroys the inspector frontend client.

* DumpRenderTree/mac/DumpRenderTree.mm:
(runTest):
* DumpRenderTree/win/DumpRenderTree.cpp:
(runTest):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorInspectorBackendDispatchercpp">trunk/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorInspectorBackendDispatcherh">trunk/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorJSGlobalObjectInspectorControllercpp">trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorJSGlobalObjectInspectorControllerh">trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorAgentcpp">trunk/Source/JavaScriptCore/inspector/agents/InspectorAgent.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorConsoleAgentcpp">trunk/Source/JavaScriptCore/inspector/agents/InspectorConsoleAgent.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorDebuggerAgentcpp">trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorRuntimeAgentcpp">trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoraugmentableAugmentableInspectorControllerh">trunk/Source/JavaScriptCore/inspector/augmentable/AugmentableInspectorController.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorremoteRemoteInspectorDebuggableh">trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggable.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorremoteRemoteInspectorDebuggableConnectionmm">trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggableConnection.mm</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorscriptscodegengenerate_cpp_alternate_backend_dispatcher_headerpy">trunk/Source/JavaScriptCore/inspector/scripts/codegen/generate_cpp_alternate_backend_dispatcher_header.py</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorscriptscodegengenerate_cpp_backend_dispatcher_implementationpy">trunk/Source/JavaScriptCore/inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorscriptscodegengenerate_objc_frontend_dispatcher_implementationpy">trunk/Source/JavaScriptCore/inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectDebuggablecpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectDebuggableh">trunk/Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxproj">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorClienth">trunk/Source/WebCore/inspector/InspectorClient.h</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorControllercpp">trunk/Source/WebCore/inspector/InspectorController.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorControllerh">trunk/Source/WebCore/inspector/InspectorController.h</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorDatabaseAgentcpp">trunk/Source/WebCore/inspector/InspectorDatabaseAgent.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorIndexedDBAgentcpp">trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorResourceAgentcpp">trunk/Source/WebCore/inspector/InspectorResourceAgent.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorWorkerInspectorControllercpp">trunk/Source/WebCore/inspector/WorkerInspectorController.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorWorkerInspectorControllerh">trunk/Source/WebCore/inspector/WorkerInspectorController.h</a></li>
<li><a href="#trunkSourceWebCorepagePageDebuggablecpp">trunk/Source/WebCore/page/PageDebuggable.cpp</a></li>
<li><a href="#trunkSourceWebCorepagePageDebuggableh">trunk/Source/WebCore/page/PageDebuggable.h</a></li>
<li><a href="#trunkSourceWebCoretestingInternalscpp">trunk/Source/WebCore/testing/Internals.cpp</a></li>
<li><a href="#trunkSourceWebKitmacChangeLog">trunk/Source/WebKit/mac/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitmacWebCoreSupportWebInspectorClienth">trunk/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.h</a></li>
<li><a href="#trunkSourceWebKitmacWebCoreSupportWebInspectorClientmm">trunk/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.mm</a></li>
<li><a href="#trunkSourceWebKitwinChangeLog">trunk/Source/WebKit/win/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitwinWebCoreSupportWebInspectorClientcpp">trunk/Source/WebKit/win/WebCoreSupport/WebInspectorClient.cpp</a></li>
<li><a href="#trunkSourceWebKitwinWebCoreSupportWebInspectorClienth">trunk/Source/WebKit/win/WebCoreSupport/WebInspectorClient.h</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebCoreSupportWebInspectorClientcpp">trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebCoreSupportWebInspectorClienth">trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebInspectorcpp">trunk/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebInspectorh">trunk/Source/WebKit2/WebProcess/WebPage/WebInspector.h</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsDumpRenderTreemacDumpRenderTreemm">trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm</a></li>
<li><a href="#trunkToolsDumpRenderTreewinDumpRenderTreecpp">trunk/Tools/DumpRenderTree/win/DumpRenderTree.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreinspectorInspectorFrontendRoutercpp">trunk/Source/JavaScriptCore/inspector/InspectorFrontendRouter.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorInspectorFrontendRouterh">trunk/Source/JavaScriptCore/inspector/InspectorFrontendRouter.h</a></li>
<li><a href="#trunkSourceWebCoreForwardingHeadersinspectorInspectorFrontendRouterh">trunk/Source/WebCore/ForwardingHeaders/inspector/InspectorFrontendRouter.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -323,6 +323,7 @@
</span><span class="cx">     inspector/InjectedScriptManager.cpp
</span><span class="cx">     inspector/InjectedScriptModule.cpp
</span><span class="cx">     inspector/InspectorAgentRegistry.cpp
</span><ins>+    inspector/InspectorFrontendRouter.cpp
</ins><span class="cx">     inspector/InspectorBackendDispatcher.cpp
</span><span class="cx">     inspector/InspectorValues.cpp
</span><span class="cx">     inspector/JSGlobalObjectConsoleClient.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -1,3 +1,82 @@
</span><ins>+2015-09-03  Brian Burg  &lt;bburg@apple.com&gt;
+
+        Web Inspector: InspectorController should support multiple frontend channels
+        https://bugs.webkit.org/show_bug.cgi?id=148538
+
+        Reviewed by Joseph Pecoraro.
+
+        Instead of a singleton, it should be possible to have multiple channels open
+        at the same time and to individually close channels as frontends come and go.
+
+        The FrontendRouter class keeps a list of open FrontendChannels and sends messages
+        to the appropriate frontends based on whether the message is a response or event.
+        Each InspectorController owns a single FrontendRouter and BackendDispatcher instance.
+        Inspector backend code that sends messages to the frontend should switch over to
+        using the router rather than directly using a FrontendChannel.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * inspector/InspectorBackendDispatcher.cpp: Move constructors/destructors out of the header
+        to avoid including InspectorFrontendRouter everywhere. Use the router instead of a
+        specific frontend channel. Remove guards that are no longer necessary since the router
+        is guaranteed to outlive the backend dispatcher.
+
+        (Inspector::SupplementalBackendDispatcher::SupplementalBackendDispatcher):
+        (Inspector::SupplementalBackendDispatcher::~SupplementalBackendDispatcher):
+        (Inspector::BackendDispatcher::BackendDispatcher):
+        (Inspector::BackendDispatcher::create):
+        (Inspector::BackendDispatcher::isActive):
+        (Inspector::BackendDispatcher::registerDispatcherForDomain):
+        (Inspector::BackendDispatcher::sendResponse):
+        (Inspector::BackendDispatcher::sendPendingErrors):
+        * inspector/InspectorBackendDispatcher.h:
+        (Inspector::SupplementalBackendDispatcher::SupplementalBackendDispatcher): Deleted.
+        (Inspector::SupplementalBackendDispatcher::~SupplementalBackendDispatcher): Deleted.
+        (Inspector::BackendDispatcher::clearFrontend): Deleted, no longer necessary.
+        (Inspector::BackendDispatcher::isActive): Moved to implementation file.
+        (Inspector::BackendDispatcher::BackendDispatcher): Moved to implementation file.
+        * inspector/InspectorFrontendRouter.cpp: Added.
+        (Inspector::FrontendRouter::create):
+        (Inspector::FrontendRouter::connectFrontend):
+        (Inspector::FrontendRouter::disconnectFrontend):
+        (Inspector::FrontendRouter::disconnectAllFrontends):
+        (Inspector::FrontendRouter::leakChannel):
+        (Inspector::FrontendRouter::hasLocalFrontend):
+        (Inspector::FrontendRouter::hasRemoteFrontend):
+        (Inspector::FrontendRouter::sendEvent):
+        (Inspector::FrontendRouter::sendResponse):
+        * inspector/InspectorFrontendRouter.h: Added.
+        * inspector/JSGlobalObjectInspectorController.cpp: Remove guards that are no longer necessary.
+        The frontend router and backend dispatcher now have the same lifetime as the controller.
+        Explicitly connect/disconnect the frontend channel.
+
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::globalObjectDestroyed):
+        (Inspector::JSGlobalObjectInspectorController::connectFrontend):
+        (Inspector::JSGlobalObjectInspectorController::disconnectFrontend):
+        (Inspector::JSGlobalObjectInspectorController::disconnectAllFrontends):
+        (Inspector::JSGlobalObjectInspectorController::dispatchMessageFromFrontend):
+        (Inspector::JSGlobalObjectInspectorController::appendExtraAgent):
+        (Inspector::JSGlobalObjectInspectorController::pause): Deleted.
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/agents/InspectorAgent.cpp:
+        * inspector/agents/InspectorConsoleAgent.cpp:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        * inspector/augmentable/AugmentableInspectorController.h:
+        (Inspector::AugmentableInspectorController::connected):
+        * inspector/remote/RemoteInspectorDebuggable.h:
+        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
+        (Inspector::RemoteInspectorDebuggableConnection::close):
+        * inspector/scripts/codegen/generate_cpp_alternate_backend_dispatcher_header.py:
+        (CppAlternateBackendDispatcherHeaderGenerator.generate_output):
+        * inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py:
+        (ObjCFrontendDispatcherImplementationGenerator._generate_event): Use the router.
+        * runtime/JSGlobalObjectDebuggable.cpp:
+        (JSC::JSGlobalObjectDebuggable::disconnect):
+        * runtime/JSGlobalObjectDebuggable.h:
+
</ins><span class="cx"> 2015-09-03  Basile Clement  &lt;basile_clement@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [ES6] Recognize calls in tail position
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -595,6 +595,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\inspector\InjectedScriptModule.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\inspector\InspectorAgentRegistry.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\inspector\InspectorBackendDispatcher.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\inspector\InspectorFrontendRouter.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\inspector\InspectorValues.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\inspector\JSInjectedScriptHost.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\inspector\JSInjectedScriptHostPrototype.cpp&quot; /&gt;
</span><span class="lines">@@ -1384,6 +1385,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\inspector\InspectorBackendDispatcher.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\inspector\InspectorEnvironment.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\inspector\InspectorFrontendChannel.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\inspector\InspectorFrontendRouter.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\inspector\InspectorValues.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\inspector\JSInjectedScriptHost.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\inspector\JSInjectedScriptHostPrototype.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -1195,6 +1195,8 @@
</span><span class="cx">                 99E45A2618A1B2590026D88F /* EncodedValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A2118A1B2590026D88F /* EncodedValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 99E45A2718A1B2590026D88F /* InputCursor.h in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A2218A1B2590026D88F /* InputCursor.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 99E45A2818A1B2590026D88F /* NondeterministicInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A2318A1B2590026D88F /* NondeterministicInput.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                99F1A6FE1B8E6D9400463B26 /* InspectorFrontendRouter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99F1A6FC1B8E6D9400463B26 /* InspectorFrontendRouter.cpp */; };
+                99F1A7011B98FBEC00463B26 /* InspectorFrontendRouter.h in Headers */ = {isa = PBXBuildFile; fileRef = 99F1A7001B98FBEC00463B26 /* InspectorFrontendRouter.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 9E729407190F01A5001A91B5 /* InitializeThreading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */; };
</span><span class="cx">                 9E729408190F021E001A91B5 /* InitializeLLVMPOSIX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCEFAC51805E75500472CE4 /* InitializeLLVMPOSIX.cpp */; };
</span><span class="cx">                 9E72940B190F0514001A91B5 /* BundlePath.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E72940A190F0514001A91B5 /* BundlePath.h */; };
</span><span class="lines">@@ -3061,6 +3063,8 @@
</span><span class="cx">                 99E45A2118A1B2590026D88F /* EncodedValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EncodedValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 99E45A2218A1B2590026D88F /* InputCursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputCursor.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 99E45A2318A1B2590026D88F /* NondeterministicInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NondeterministicInput.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                99F1A6FC1B8E6D9400463B26 /* InspectorFrontendRouter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorFrontendRouter.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                99F1A7001B98FBEC00463B26 /* InspectorFrontendRouter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorFrontendRouter.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 9B4954E81A6640DB002815A6 /* ParserFunctionInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ParserFunctionInfo.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9E729409190F0306001A91B5 /* BundlePath.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BundlePath.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9E72940A190F0514001A91B5 /* BundlePath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BundlePath.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -5707,6 +5711,7 @@
</span><span class="cx">                 A5BA15DF1823409200A82E69 /* inspector */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                99F1A7001B98FBEC00463B26 /* InspectorFrontendRouter.h */,
</ins><span class="cx">                                 A513E5CC185FB992007E95AD /* agents */,
</span><span class="cx">                                 A5EA70E319F5B0E20098F5EC /* augmentable */,
</span><span class="cx">                                 A532438D185696CA002ED692 /* protocol */,
</span><span class="lines">@@ -5738,6 +5743,7 @@
</span><span class="cx">                                 A593CF7B1840360300BFCE27 /* InspectorBackendDispatcher.h */,
</span><span class="cx">                                 A5D0A1BA1862301B00C7B496 /* InspectorEnvironment.h */,
</span><span class="cx">                                 A5945594182479EB00CC3843 /* InspectorFrontendChannel.h */,
</span><ins>+                                99F1A6FC1B8E6D9400463B26 /* InspectorFrontendRouter.cpp */,
</ins><span class="cx">                                 A55D93AB18514F7900400DED /* InspectorProtocolTypes.h */,
</span><span class="cx">                                 A593CF801840377100BFCE27 /* InspectorValues.cpp */,
</span><span class="cx">                                 A593CF811840377100BFCE27 /* InspectorValues.h */,
</span><span class="lines">@@ -5901,6 +5907,7 @@
</span><span class="cx">                                 A1A009C11831A26E00CF8711 /* ARM64Assembler.h in Headers */,
</span><span class="cx">                                 0F898F321B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.h in Headers */,
</span><span class="cx">                                 86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */,
</span><ins>+                                99F1A7011B98FBEC00463B26 /* InspectorFrontendRouter.h in Headers */,
</ins><span class="cx">                                 7964656A1B952FF0003059EE /* GetPutInfo.h in Headers */,
</span><span class="cx">                                 797E07AA1B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h in Headers */,
</span><span class="cx">                                 0FE050281AA9095600D33B33 /* ScopedArguments.h in Headers */,
</span><span class="lines">@@ -7933,6 +7940,7 @@
</span><span class="cx">                                 C225494315F7DBAA0065E898 /* SlotVisitor.cpp in Sources */,
</span><span class="cx">                                 9330402C0E6A764000786E6A /* SmallStrings.cpp in Sources */,
</span><span class="cx">                                 E3EF88741B66DF23003F26CB /* JSPropertyNameIterator.cpp in Sources */,
</span><ins>+                                99F1A6FE1B8E6D9400463B26 /* InspectorFrontendRouter.cpp in Sources */,
</ins><span class="cx">                                 0F8F2B9E17306C8D007DBDA5 /* SourceCode.cpp in Sources */,
</span><span class="cx">                                 0F493AFA16D0CAD30084508B /* SourceProvider.cpp in Sources */,
</span><span class="cx">                                 E33E8D1C1B9013C300346B52 /* JSNativeStdFunction.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorInspectorBackendDispatchercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> #include &quot;InspectorBackendDispatcher.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;InspectorFrontendChannel.h&quot;
</span><ins>+#include &quot;InspectorFrontendRouter.h&quot;
</ins><span class="cx"> #include &quot;InspectorValues.h&quot;
</span><span class="cx"> #include &lt;wtf/TemporaryChange.h&gt;
</span><span class="cx"> #include &lt;wtf/text/CString.h&gt;
</span><span class="lines">@@ -35,6 +36,15 @@
</span><span class="cx"> 
</span><span class="cx"> namespace Inspector {
</span><span class="cx"> 
</span><ins>+SupplementalBackendDispatcher::SupplementalBackendDispatcher(BackendDispatcher&amp; backendDispatcher)
+    : m_backendDispatcher(backendDispatcher)
+{
+}
+
+SupplementalBackendDispatcher::~SupplementalBackendDispatcher()
+{
+}
+
</ins><span class="cx"> BackendDispatcher::CallbackBase::CallbackBase(Ref&lt;BackendDispatcher&gt;&amp;&amp; backendDispatcher, long requestId)
</span><span class="cx">     : m_backendDispatcher(WTF::move(backendDispatcher))
</span><span class="cx">     , m_requestId(requestId)
</span><span class="lines">@@ -69,15 +79,28 @@
</span><span class="cx">     m_backendDispatcher-&gt;sendResponse(m_requestId, WTF::move(partialMessage));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Ref&lt;BackendDispatcher&gt; BackendDispatcher::create(FrontendChannel* frontendChannel)
</del><ins>+BackendDispatcher::BackendDispatcher(Ref&lt;FrontendRouter&gt;&amp;&amp; router)
+    : m_frontendRouter(WTF::move(router))
</ins><span class="cx"> {
</span><del>-    return adoptRef(*new BackendDispatcher(frontendChannel));
</del><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Ref&lt;BackendDispatcher&gt; BackendDispatcher::create(Ref&lt;FrontendRouter&gt;&amp;&amp; router)
+{
+    return adoptRef(*new BackendDispatcher(WTF::move(router)));
+}
+
+bool BackendDispatcher::isActive() const
+{
+    return m_frontendRouter-&gt;hasFrontends();
+}
+
</ins><span class="cx"> void BackendDispatcher::registerDispatcherForDomain(const String&amp; domain, SupplementalBackendDispatcher* dispatcher)
</span><span class="cx"> {
</span><del>-    auto result = m_dispatchers.add(domain, dispatcher);
-    ASSERT_UNUSED(result, result.isNewEntry);
</del><ins>+    ASSERT_ARG(dispatcher, dispatcher);
+
+    // FIXME: &lt;https://webkit.org/b/148492&gt; Agents should only register with the backend once,
+    // and we should re-add the assertion that only one dispatcher is registered per domain.
+    m_dispatchers.set(domain, dispatcher);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void BackendDispatcher::dispatch(const String&amp; message)
</span><span class="lines">@@ -165,9 +188,6 @@
</span><span class="cx"> 
</span><span class="cx"> void BackendDispatcher::sendResponse(long requestId, RefPtr&lt;InspectorObject&gt;&amp;&amp; result)
</span><span class="cx"> {
</span><del>-    if (!m_frontendChannel)
-        return;
-
</del><span class="cx">     ASSERT(!m_protocolErrors.size());
</span><span class="cx"> 
</span><span class="cx">     // The JSON-RPC 2.0 specification requires that the &quot;error&quot; member have the value 'null'
</span><span class="lines">@@ -175,7 +195,7 @@
</span><span class="cx">     Ref&lt;InspectorObject&gt; responseMessage = InspectorObject::create();
</span><span class="cx">     responseMessage-&gt;setObject(ASCIILiteral(&quot;result&quot;), result);
</span><span class="cx">     responseMessage-&gt;setInteger(ASCIILiteral(&quot;id&quot;), requestId);
</span><del>-    m_frontendChannel-&gt;sendMessageToFrontend(responseMessage-&gt;toJSONString());
</del><ins>+    m_frontendRouter-&gt;sendResponse(responseMessage-&gt;toJSONString());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void BackendDispatcher::sendPendingErrors()
</span><span class="lines">@@ -190,9 +210,6 @@
</span><span class="cx">         -32000, // ServerError
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    if (!m_frontendChannel)
-        return;
-    
</del><span class="cx">     // To construct the error object, only use the last error's code and message.
</span><span class="cx">     // Per JSON-RPC 2.0, Section 5.1, the 'data' member may contain nested errors,
</span><span class="cx">     // but only one top-level Error object should be sent per request.
</span><span class="lines">@@ -227,7 +244,7 @@
</span><span class="cx">         message-&gt;setValue(ASCIILiteral(&quot;id&quot;), InspectorValue::null());
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_frontendChannel-&gt;sendMessageToFrontend(message-&gt;toJSONString());
</del><ins>+    m_frontendRouter-&gt;sendResponse(message-&gt;toJSONString());
</ins><span class="cx"> 
</span><span class="cx">     m_protocolErrors.clear();
</span><span class="cx">     m_currentRequestId = Nullopt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorInspectorBackendDispatcherh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -35,15 +35,14 @@
</span><span class="cx"> namespace Inspector {
</span><span class="cx"> 
</span><span class="cx"> class BackendDispatcher;
</span><del>-class FrontendChannel;
</del><ins>+class FrontendRouter;
</ins><span class="cx"> 
</span><span class="cx"> typedef String ErrorString;
</span><span class="cx"> 
</span><span class="cx"> class SupplementalBackendDispatcher : public RefCounted&lt;SupplementalBackendDispatcher&gt; {
</span><span class="cx"> public:
</span><del>-    SupplementalBackendDispatcher(BackendDispatcher&amp; backendDispatcher)
-        : m_backendDispatcher(backendDispatcher) { }
-    virtual ~SupplementalBackendDispatcher() { }
</del><ins>+    SupplementalBackendDispatcher(BackendDispatcher&amp;);
+    virtual ~SupplementalBackendDispatcher();
</ins><span class="cx">     virtual void dispatch(long requestId, const String&amp; method, Ref&lt;InspectorObject&gt;&amp;&amp; message) = 0;
</span><span class="cx"> protected:
</span><span class="cx">     Ref&lt;BackendDispatcher&gt; m_backendDispatcher;
</span><span class="lines">@@ -51,7 +50,7 @@
</span><span class="cx"> 
</span><span class="cx"> class BackendDispatcher : public RefCounted&lt;BackendDispatcher&gt; {
</span><span class="cx"> public:
</span><del>-    JS_EXPORT_PRIVATE static Ref&lt;BackendDispatcher&gt; create(FrontendChannel*);
</del><ins>+    JS_EXPORT_PRIVATE static Ref&lt;BackendDispatcher&gt; create(Ref&lt;FrontendRouter&gt;&amp;&amp;);
</ins><span class="cx"> 
</span><span class="cx">     class JS_EXPORT_PRIVATE CallbackBase : public RefCounted&lt;CallbackBase&gt; {
</span><span class="cx">     public:
</span><span class="lines">@@ -69,8 +68,7 @@
</span><span class="cx">         bool m_alreadySent { false };
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    void clearFrontend() { m_frontendChannel = nullptr; }
-    bool isActive() const { return !!m_frontendChannel; }
</del><ins>+    bool isActive() const;
</ins><span class="cx"> 
</span><span class="cx">     bool hasProtocolErrors() const { return m_protocolErrors.size() &gt; 0; }
</span><span class="cx"> 
</span><span class="lines">@@ -104,12 +102,9 @@
</span><span class="cx">     RefPtr&lt;InspectorArray&gt; getArray(InspectorObject*, const String&amp; name, bool* valueFound);
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    BackendDispatcher(FrontendChannel* channel)
-        : m_frontendChannel(channel)
-    {
-    }
</del><ins>+    BackendDispatcher(Ref&lt;FrontendRouter&gt;&amp;&amp;);
</ins><span class="cx"> 
</span><del>-    FrontendChannel* m_frontendChannel;
</del><ins>+    Ref&lt;FrontendRouter&gt; m_frontendRouter;
</ins><span class="cx">     HashMap&lt;String, SupplementalBackendDispatcher*&gt; m_dispatchers;
</span><span class="cx"> 
</span><span class="cx">     // Protocol errors reported for the top-level request being processed.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorInspectorFrontendRoutercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/inspector/InspectorFrontendRouter.cpp (0 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/InspectorFrontendRouter.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/inspector/InspectorFrontendRouter.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -0,0 +1,110 @@
</span><ins>+/*
+ * 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.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;InspectorFrontendRouter.h&quot;
+
+#include &quot;InspectorFrontendChannel.h&quot;
+#include &lt;wtf/Assertions.h&gt;
+
+namespace Inspector {
+
+Ref&lt;FrontendRouter&gt; FrontendRouter::create()
+{
+    return adoptRef(*new FrontendRouter);
+}
+
+void FrontendRouter::connectFrontend(FrontendChannel* connection)
+{
+    ASSERT_ARG(connection, connection);
+
+    if (m_connections.contains(connection)) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+
+    m_connections.append(connection);
+}
+
+void FrontendRouter::disconnectFrontend(FrontendChannel* connection)
+{
+    ASSERT_ARG(connection, connection);
+
+    if (!m_connections.contains(connection)) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+
+    m_connections.removeFirst(connection);
+}
+
+void FrontendRouter::disconnectAllFrontends()
+{
+    m_connections.clear();
+}
+
+// FIXME: &lt;https://webkit.org/b/148492&gt; remove this method once agents move to using FrontendRouter directly.
+FrontendChannel* FrontendRouter::leakChannel() const
+{
+    if (m_connections.size())
+        return m_connections.at(0);
+
+    return nullptr;
+}
+
+bool FrontendRouter::hasLocalFrontend() const
+{
+    for (auto* connection : m_connections) {
+        if (connection-&gt;connectionType() == FrontendChannel::ConnectionType::Local)
+            return true;
+    }
+
+    return false;
+}
+
+bool FrontendRouter::hasRemoteFrontend() const
+{
+    for (auto* connection : m_connections) {
+        if (connection-&gt;connectionType() == FrontendChannel::ConnectionType::Remote)
+            return true;
+    }
+
+    return false;
+}
+
+void FrontendRouter::sendEvent(const String&amp; message) const
+{
+    for (auto* connection : m_connections)
+        connection-&gt;sendMessageToFrontend(message);
+}
+
+void FrontendRouter::sendResponse(const String&amp; message) const
+{
+    // FIXME: send responses to the appropriate frontend.
+    for (auto* connection : m_connections)
+        connection-&gt;sendMessageToFrontend(message);
+}
+
+} // namespace Inspector
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorInspectorFrontendRouterh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/inspector/InspectorFrontendRouter.h (0 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/InspectorFrontendRouter.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/inspector/InspectorFrontendRouter.h        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -0,0 +1,60 @@
</span><ins>+/*
+ * 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.
+ */
+
+#ifndef InspectorFrontendRouter_h
+#define InspectorFrontendRouter_h
+
+#include &lt;wtf/Vector.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
+namespace Inspector {
+
+class FrontendChannel;
+
+class JS_EXPORT_PRIVATE FrontendRouter : public RefCounted&lt;FrontendRouter&gt; {
+public:
+    static Ref&lt;FrontendRouter&gt; create();
+
+    bool hasFrontends() const { return !m_connections.isEmpty(); }
+    bool hasLocalFrontend() const;
+    bool hasRemoteFrontend() const;
+
+    void connectFrontend(FrontendChannel*);
+    void disconnectFrontend(FrontendChannel*);
+    void disconnectAllFrontends();
+
+    // FIXME: &lt;https://webkit.org/b/148492&gt; remove this method once agents move to using FrontendRouter directly.
+    FrontendChannel* leakChannel() const;
+
+    void sendEvent(const String&amp; message) const;
+    void sendResponse(const String&amp; message) const;
+
+private:
+    Vector&lt;FrontendChannel*, 2&gt; m_connections;
+};
+
+} // namespace Inspector
+
+#endif // !defined(InspectorFrontendRouter_h)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorJSGlobalObjectInspectorControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx"> #include &quot;InspectorAgent.h&quot;
</span><span class="cx"> #include &quot;InspectorBackendDispatcher.h&quot;
</span><span class="cx"> #include &quot;InspectorFrontendChannel.h&quot;
</span><ins>+#include &quot;InspectorFrontendRouter.h&quot;
</ins><span class="cx"> #include &quot;JSGlobalObject.h&quot;
</span><span class="cx"> #include &quot;JSGlobalObjectConsoleAgent.h&quot;
</span><span class="cx"> #include &quot;JSGlobalObjectConsoleClient.h&quot;
</span><span class="lines">@@ -63,7 +64,8 @@
</span><span class="cx"> JSGlobalObjectInspectorController::JSGlobalObjectInspectorController(JSGlobalObject&amp; globalObject)
</span><span class="cx">     : m_globalObject(globalObject)
</span><span class="cx">     , m_injectedScriptManager(std::make_unique&lt;InjectedScriptManager&gt;(*this, InjectedScriptHost::create()))
</span><del>-    , m_frontendChannel(nullptr)
</del><ins>+    , m_frontendRouter(FrontendRouter::create())
+    , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
</ins><span class="cx">     , m_executionStopwatch(Stopwatch::create())
</span><span class="cx">     , m_includeNativeCallStackWithExceptions(true)
</span><span class="cx">     , m_isAutomaticInspection(false)
</span><span class="lines">@@ -98,23 +100,25 @@
</span><span class="cx"> 
</span><span class="cx"> void JSGlobalObjectInspectorController::globalObjectDestroyed()
</span><span class="cx"> {
</span><del>-    disconnectFrontend(DisconnectReason::InspectedTargetDestroyed);
</del><ins>+    disconnectAllFrontends();
</ins><span class="cx"> 
</span><span class="cx">     m_injectedScriptManager-&gt;disconnect();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JSGlobalObjectInspectorController::connectFrontend(FrontendChannel* frontendChannel, bool isAutomaticInspection)
</span><span class="cx"> {
</span><del>-    ASSERT(!m_frontendChannel);
-    ASSERT(!m_backendDispatcher);
</del><ins>+    ASSERT_ARG(frontendChannel, frontendChannel);
</ins><span class="cx"> 
</span><span class="cx">     m_isAutomaticInspection = isAutomaticInspection;
</span><span class="cx"> 
</span><del>-    m_frontendChannel = frontendChannel;
-    m_backendDispatcher = BackendDispatcher::create(frontendChannel);
</del><ins>+    bool connectedFirstFrontend = !m_frontendRouter-&gt;hasFrontends();
+    m_frontendRouter-&gt;connectFrontend(frontendChannel);
</ins><span class="cx"> 
</span><del>-    m_agents.didCreateFrontendAndBackend(frontendChannel, m_backendDispatcher.get());
</del><ins>+    if (!connectedFirstFrontend)
+        return;
</ins><span class="cx"> 
</span><ins>+    m_agents.didCreateFrontendAndBackend(frontendChannel, &amp;m_backendDispatcher.get());
+
</ins><span class="cx"> #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
</span><span class="cx">     m_inspectorAgent-&gt;activateExtraDomains(m_agents.extraDomains());
</span><span class="cx"> 
</span><span class="lines">@@ -123,17 +127,32 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JSGlobalObjectInspectorController::disconnectFrontend(DisconnectReason reason)
</del><ins>+void JSGlobalObjectInspectorController::disconnectFrontend(FrontendChannel* frontendChannel)
</ins><span class="cx"> {
</span><del>-    if (!m_frontendChannel)
</del><ins>+    ASSERT_ARG(frontendChannel, frontendChannel);
+
+    m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectorDestroyed);
+
+    m_frontendRouter-&gt;disconnectFrontend(frontendChannel);
+
+    m_isAutomaticInspection = false;
+
+    bool disconnectedLastFrontend = !m_frontendRouter-&gt;hasFrontends();
+    if (!disconnectedLastFrontend)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    m_agents.willDestroyFrontendAndBackend(reason);
</del><ins>+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_augmentingClient)
+        m_augmentingClient-&gt;inspectorDisconnected();
+#endif
+}
</ins><span class="cx"> 
</span><del>-    m_backendDispatcher-&gt;clearFrontend();
-    m_backendDispatcher = nullptr;
-    m_frontendChannel = nullptr;
</del><ins>+void JSGlobalObjectInspectorController::disconnectAllFrontends()
+{
+    m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectedTargetDestroyed);
</ins><span class="cx"> 
</span><ins>+    m_frontendRouter-&gt;disconnectAllFrontends();
+
</ins><span class="cx">     m_isAutomaticInspection = false;
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
</span><span class="lines">@@ -144,15 +163,11 @@
</span><span class="cx"> 
</span><span class="cx"> void JSGlobalObjectInspectorController::dispatchMessageFromFrontend(const String&amp; message)
</span><span class="cx"> {
</span><del>-    if (m_backendDispatcher)
-        m_backendDispatcher-&gt;dispatch(message);
</del><ins>+    m_backendDispatcher-&gt;dispatch(message);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JSGlobalObjectInspectorController::pause()
</span><span class="cx"> {
</span><del>-    if (!m_frontendChannel)
-        return;
-
</del><span class="cx">     ErrorString dummyError;
</span><span class="cx">     m_debuggerAgent-&gt;enable(dummyError);
</span><span class="cx">     m_debuggerAgent-&gt;pause(dummyError);
</span><span class="lines">@@ -262,13 +277,11 @@
</span><span class="cx"> {
</span><span class="cx">     String domainName = agent-&gt;domainName();
</span><span class="cx"> 
</span><del>-    if (m_frontendChannel)
-        agent-&gt;didCreateFrontendAndBackend(m_frontendChannel, m_backendDispatcher.get());
</del><ins>+    agent-&gt;didCreateFrontendAndBackend(m_frontendRouter-&gt;leakChannel(), &amp;m_backendDispatcher.get());
</ins><span class="cx"> 
</span><span class="cx">     m_agents.appendExtraAgent(WTF::move(agent));
</span><span class="cx"> 
</span><del>-    if (m_frontendChannel)
-        m_inspectorAgent-&gt;activateExtraDomain(domainName);
</del><ins>+    m_inspectorAgent-&gt;activateExtraDomain(domainName);
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorJSGlobalObjectInspectorControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.h (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.h        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.h        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -53,6 +53,7 @@
</span><span class="cx"> 
</span><span class="cx"> class BackendDispatcher;
</span><span class="cx"> class FrontendChannel;
</span><ins>+class FrontendRouter;
</ins><span class="cx"> class InjectedScriptManager;
</span><span class="cx"> class InspectorAgent;
</span><span class="cx"> class InspectorConsoleAgent;
</span><span class="lines">@@ -73,7 +74,9 @@
</span><span class="cx">     ~JSGlobalObjectInspectorController();
</span><span class="cx"> 
</span><span class="cx">     void connectFrontend(FrontendChannel*, bool isAutomaticInspection);
</span><del>-    void disconnectFrontend(DisconnectReason);
</del><ins>+    void disconnectFrontend(FrontendChannel*);
+    void disconnectAllFrontends();
+
</ins><span class="cx">     void dispatchMessageFromFrontend(const String&amp;);
</span><span class="cx"> 
</span><span class="cx">     void globalObjectDestroyed();
</span><span class="lines">@@ -99,7 +102,7 @@
</span><span class="cx">     virtual AugmentableInspectorControllerClient* augmentableInspectorControllerClient() const override { return m_augmentingClient; } 
</span><span class="cx">     virtual void setAugmentableInspectorControllerClient(AugmentableInspectorControllerClient* client) override { m_augmentingClient = client; }
</span><span class="cx"> 
</span><del>-    virtual FrontendChannel* frontendChannel() const override { return m_frontendChannel; }
</del><ins>+    virtual const FrontendRouter&amp; frontendRouter() const override { return m_frontendRouter.get(); }
</ins><span class="cx">     virtual void appendExtraAgent(std::unique_ptr&lt;InspectorAgentBase&gt;) override;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -113,8 +116,8 @@
</span><span class="cx">     InspectorConsoleAgent* m_consoleAgent;
</span><span class="cx">     InspectorDebuggerAgent* m_debuggerAgent;
</span><span class="cx">     AgentRegistry m_agents;
</span><del>-    FrontendChannel* m_frontendChannel;
-    RefPtr&lt;BackendDispatcher&gt; m_backendDispatcher;
</del><ins>+    Ref&lt;FrontendRouter&gt; m_frontendRouter;
+    Ref&lt;BackendDispatcher&gt; m_backendDispatcher;
</ins><span class="cx">     Ref&lt;WTF::Stopwatch&gt; m_executionStopwatch;
</span><span class="cx">     bool m_includeNativeCallStackWithExceptions;
</span><span class="cx">     bool m_isAutomaticInspection;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorAgent.cpp (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorAgent.cpp        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorAgent.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;InspectorAgent.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;InspectorEnvironment.h&quot;
</span><ins>+#include &quot;InspectorFrontendRouter.h&quot;
</ins><span class="cx"> #include &quot;InspectorValues.h&quot;
</span><span class="cx"> #include &quot;ScriptValue.h&quot;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorConsoleAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorConsoleAgent.cpp (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorConsoleAgent.cpp        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorConsoleAgent.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ConsoleMessage.h&quot;
</span><span class="cx"> #include &quot;InjectedScriptManager.h&quot;
</span><ins>+#include &quot;InspectorFrontendRouter.h&quot;
</ins><span class="cx"> #include &quot;ScriptArguments.h&quot;
</span><span class="cx"> #include &quot;ScriptCallFrame.h&quot;
</span><span class="cx"> #include &quot;ScriptCallStack.h&quot;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorDebuggerAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;ContentSearchUtilities.h&quot;
</span><span class="cx"> #include &quot;InjectedScript.h&quot;
</span><span class="cx"> #include &quot;InjectedScriptManager.h&quot;
</span><ins>+#include &quot;InspectorFrontendRouter.h&quot;
</ins><span class="cx"> #include &quot;InspectorValues.h&quot;
</span><span class="cx"> #include &quot;RegularExpression.h&quot;
</span><span class="cx"> #include &quot;ScriptDebugServer.h&quot;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorRuntimeAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> #include &quot;HeapIterationScope.h&quot;
</span><span class="cx"> #include &quot;InjectedScript.h&quot;
</span><span class="cx"> #include &quot;InjectedScriptManager.h&quot;
</span><ins>+#include &quot;InspectorFrontendRouter.h&quot;
</ins><span class="cx"> #include &quot;InspectorValues.h&quot;
</span><span class="cx"> #include &quot;JSLock.h&quot;
</span><span class="cx"> #include &quot;ParserError.h&quot;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoraugmentableAugmentableInspectorControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/augmentable/AugmentableInspectorController.h (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/augmentable/AugmentableInspectorController.h        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/inspector/augmentable/AugmentableInspectorController.h        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -29,7 +29,7 @@
</span><span class="cx"> #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
</span><span class="cx"> 
</span><span class="cx"> #include &lt;JavaScriptCore/AugmentableInspectorControllerClient.h&gt;
</span><del>-#include &lt;JavaScriptCore/InspectorFrontendChannel.h&gt;
</del><ins>+#include &lt;JavaScriptCore/InspectorFrontendRouter.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace Inspector {
</span><span class="cx"> 
</span><span class="lines">@@ -42,10 +42,10 @@
</span><span class="cx">     virtual AugmentableInspectorControllerClient* augmentableInspectorControllerClient() const = 0;
</span><span class="cx">     virtual void setAugmentableInspectorControllerClient(AugmentableInspectorControllerClient*) = 0;
</span><span class="cx"> 
</span><del>-    virtual FrontendChannel* frontendChannel() const = 0;
</del><ins>+    virtual const FrontendRouter&amp; frontendRouter() const = 0;
</ins><span class="cx">     virtual void appendExtraAgent(std::unique_ptr&lt;InspectorAgentBase&gt;) = 0;
</span><span class="cx"> 
</span><del>-    bool connected() const { return !!frontendChannel(); }
</del><ins>+    bool connected() const { return frontendRouter().hasFrontends(); }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace Inspector
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorremoteRemoteInspectorDebuggableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggable.h (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggable.h        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggable.h        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -64,7 +64,7 @@
</span><span class="cx">     virtual bool hasLocalDebugger() const = 0;
</span><span class="cx"> 
</span><span class="cx">     virtual void connect(FrontendChannel*, bool isAutomaticInspection) = 0;
</span><del>-    virtual void disconnect() = 0;
</del><ins>+    virtual void disconnect(FrontendChannel*) = 0;
</ins><span class="cx">     virtual void dispatchMessageFromRemoteFrontend(const String&amp; message) = 0;
</span><span class="cx">     virtual void setIndicating(bool) { } // Default is to do nothing.
</span><span class="cx">     virtual void pause() { };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorremoteRemoteInspectorDebuggableConnectionmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggableConnection.mm (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggableConnection.mm        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggableConnection.mm        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -191,7 +191,7 @@
</span><span class="cx"> 
</span><span class="cx">             if (m_debuggable) {
</span><span class="cx">                 if (m_connected)
</span><del>-                    m_debuggable-&gt;disconnect();
</del><ins>+                    m_debuggable-&gt;disconnect(this);
</ins><span class="cx"> 
</span><span class="cx">                 m_debuggable = nullptr;
</span><span class="cx">             }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorscriptscodegengenerate_cpp_alternate_backend_dispatcher_headerpy"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/scripts/codegen/generate_cpp_alternate_backend_dispatcher_header.py (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/scripts/codegen/generate_cpp_alternate_backend_dispatcher_header.py        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/inspector/scripts/codegen/generate_cpp_alternate_backend_dispatcher_header.py        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -47,6 +47,7 @@
</span><span class="cx">     def generate_output(self):
</span><span class="cx">         headers = [
</span><span class="cx">             '&quot;InspectorProtocolTypes.h&quot;',
</span><ins>+            '&lt;inspector/InspectorFrontendRouter.h&gt;',
</ins><span class="cx">             '&lt;JavaScriptCore/InspectorBackendDispatcher.h&gt;',
</span><span class="cx">         ]
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorscriptscodegengenerate_cpp_backend_dispatcher_implementationpy"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx">     def generate_output(self):
</span><span class="cx">         secondary_headers = [
</span><span class="cx">             '&lt;inspector/InspectorFrontendChannel.h&gt;',
</span><ins>+            '&lt;inspector/InspectorFrontendRouter.h&gt;',
</ins><span class="cx">             '&lt;inspector/InspectorValues.h&gt;',
</span><span class="cx">             '&lt;wtf/NeverDestroyed.h&gt;',
</span><span class="cx">             '&lt;wtf/text/CString.h&gt;']
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorscriptscodegengenerate_objc_frontend_dispatcher_implementationpy"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -98,9 +98,7 @@
</span><span class="cx">         lines = []
</span><span class="cx">         lines.append(self._generate_event_signature(domain, event))
</span><span class="cx">         lines.append('{')
</span><del>-        lines.append('    FrontendChannel* frontendChannel = _controller-&gt;frontendChannel();')
-        lines.append('    if (!frontendChannel)')
-        lines.append('        return;')
</del><ins>+        lines.append('    const FrontendRouter&amp; router = _controller-&gt;frontendRouter();')
</ins><span class="cx">         lines.append('')
</span><span class="cx"> 
</span><span class="cx">         required_pointer_parameters = filter(lambda parameter: not parameter.is_optional and ObjCGenerator.is_type_objc_pointer_type(parameter.type), event.event_parameters)
</span><span class="lines">@@ -126,7 +124,7 @@
</span><span class="cx">         lines.append('    jsonMessage-&gt;setString(ASCIILiteral(&quot;method&quot;), ASCIILiteral(&quot;%s.%s&quot;));' % (domain.domain_name, event.event_name))
</span><span class="cx">         if event.event_parameters:
</span><span class="cx">             lines.extend(self._generate_event_out_parameters(domain, event))
</span><del>-        lines.append('    frontendChannel-&gt;sendMessageToFrontend(jsonMessage-&gt;toJSONString());')
</del><ins>+        lines.append('    router.sendEvent(jsonMessage-&gt;toJSONString());')
</ins><span class="cx">         lines.append('}')
</span><span class="cx">         return '\n'.join(lines)
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectDebuggablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.cpp (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.cpp        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -56,11 +56,11 @@
</span><span class="cx">     m_globalObject.inspectorController().connectFrontend(frontendChannel, automaticInspection);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JSGlobalObjectDebuggable::disconnect()
</del><ins>+void JSGlobalObjectDebuggable::disconnect(FrontendChannel* frontendChannel)
</ins><span class="cx"> {
</span><span class="cx">     JSLockHolder locker(&amp;m_globalObject.vm());
</span><span class="cx"> 
</span><del>-    m_globalObject.inspectorController().disconnectFrontend(DisconnectReason::InspectorDestroyed);
</del><ins>+    m_globalObject.inspectorController().disconnectFrontend(frontendChannel);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JSGlobalObjectDebuggable::pause()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectDebuggableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.h (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.h        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.h        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -54,7 +54,7 @@
</span><span class="cx">     virtual bool hasLocalDebugger() const override { return false; }
</span><span class="cx"> 
</span><span class="cx">     virtual void connect(Inspector::FrontendChannel*, bool automaticInspection) override;
</span><del>-    virtual void disconnect() override;
</del><ins>+    virtual void disconnect(Inspector::FrontendChannel*) override;
</ins><span class="cx">     virtual void dispatchMessageFromRemoteFrontend(const String&amp; message) override;
</span><span class="cx">     virtual void pause() override;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/ChangeLog        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -1,3 +1,48 @@
</span><ins>+2015-09-03  Brian Burg  &lt;bburg@apple.com&gt;
+
+        Web Inspector: InspectorController should support multiple frontend channels
+        https://bugs.webkit.org/show_bug.cgi?id=148538
+
+        Reviewed by Joseph Pecoraro.
+
+        No new tests, no behavior change from this patch. Teardown scenarios are
+        covered by existing protocol and inspector tests running under DRT and WKTR.
+
+        * ForwardingHeaders/inspector/InspectorFrontendRouter.h: Added.
+        * WebCore.vcxproj/WebCore.vcxproj:
+        * inspector/InspectorClient.h: Stop using forwarded types.
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::InspectorController):
+        (WebCore::InspectorController::inspectedPageDestroyed):
+        (WebCore::InspectorController::hasLocalFrontend):
+        (WebCore::InspectorController::hasRemoteFrontend):
+        (WebCore::InspectorController::connectFrontend):
+        (WebCore::InspectorController::disconnectFrontend):
+        (WebCore::InspectorController::disconnectAllFrontends): Added. Disconnects all
+        frontends and signals DisconnectReason::InspectedTargetDestroyed.
+
+        (WebCore::InspectorController::show):
+        (WebCore::InspectorController::close):
+        (WebCore::InspectorController::dispatchMessageFromFrontend):
+        * inspector/InspectorController.h: Add default value for isAutomaticInspection.
+        * inspector/InspectorDatabaseAgent.cpp:
+        * inspector/InspectorIndexedDBAgent.cpp:
+        * inspector/InspectorResourceAgent.cpp:
+        * inspector/WorkerInspectorController.cpp: Use a router with a singleton channel
+        that forwards messages over to the main page.
+
+        (WebCore::WorkerInspectorController::WorkerInspectorController):
+        (WebCore::WorkerInspectorController::connectFrontend):
+        (WebCore::WorkerInspectorController::disconnectFrontend):
+        (WebCore::WorkerInspectorController::dispatchMessageFromFrontend):
+        * inspector/WorkerInspectorController.h:
+        * page/PageDebuggable.cpp:
+        (WebCore::PageDebuggable::disconnect):
+        * page/PageDebuggable.h:
+        * testing/Internals.cpp: Clear the frontend client before disconnecting frontend channel.
+        (WebCore::Internals::openDummyInspectorFrontend):
+        (WebCore::Internals::closeDummyInspectorFrontend):
+
</ins><span class="cx"> 2015-09-03  Jinyoung Hur  &lt;hur.ims@navercorp.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Texmap] highp precision should be used conditionally for fragment shaders on OpenGL ES
</span></span></pre></div>
<a id="trunkSourceWebCoreForwardingHeadersinspectorInspectorFrontendRouterh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/ForwardingHeaders/inspector/InspectorFrontendRouter.h (0 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ForwardingHeaders/inspector/InspectorFrontendRouter.h                                (rev 0)
+++ trunk/Source/WebCore/ForwardingHeaders/inspector/InspectorFrontendRouter.h        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+#ifndef WebCore_FWD_InspectorFrontendRouter_h
+#define WebCore_FWD_InspectorFrontendRouter_h
+#include &lt;JavaScriptCore/InspectorFrontendRouter.h&gt;
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -20336,6 +20336,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ForwardingHeaders\inspector\InspectorBackendDispatcher.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ForwardingHeaders\inspector\InspectorEnvironment.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ForwardingHeaders\inspector\InspectorFrontendChannel.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\ForwardingHeaders\inspector\InspectorFrontendRouter.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\ForwardingHeaders\inspector\InspectorBackendDispatchers.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ForwardingHeaders\inspector\InspectorFrontendDispatchers.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ForwardingHeaders\inspector\InspectorProtocolObjects.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorClient.h (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorClient.h        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/inspector/InspectorClient.h        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -27,11 +27,14 @@
</span><span class="cx"> #ifndef InspectorClient_h
</span><span class="cx"> #define InspectorClient_h
</span><span class="cx"> 
</span><del>-#include &quot;InspectorForwarding.h&quot;
</del><span class="cx"> #include &lt;wtf/Forward.h&gt;
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> #include &lt;wtf/HashSet.h&gt;
</span><span class="cx"> 
</span><ins>+namespace Inspector {
+class FrontendChannel;
+}
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class FloatRect;
</span><span class="lines">@@ -45,7 +48,7 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void inspectorDestroyed() = 0;
</span><span class="cx"> 
</span><del>-    virtual InspectorFrontendChannel* openInspectorFrontend(InspectorController*) = 0;
</del><ins>+    virtual Inspector::FrontendChannel* openInspectorFrontend(InspectorController*) = 0;
</ins><span class="cx">     virtual void closeInspectorFrontend() = 0;
</span><span class="cx">     virtual void bringFrontendToFront() = 0;
</span><span class="cx">     virtual void didResizeMainFrame(Frame*) { }
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorController.cpp (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorController.cpp        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/inspector/InspectorController.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -68,6 +68,7 @@
</span><span class="cx"> #include &lt;inspector/InspectorBackendDispatcher.h&gt;
</span><span class="cx"> #include &lt;inspector/InspectorBackendDispatchers.h&gt;
</span><span class="cx"> #include &lt;inspector/InspectorFrontendDispatchers.h&gt;
</span><ins>+#include &lt;inspector/InspectorFrontendRouter.h&gt;
</ins><span class="cx"> #include &lt;inspector/agents/InspectorAgent.h&gt;
</span><span class="cx"> #include &lt;profiler/LegacyProfiler.h&gt;
</span><span class="cx"> #include &lt;runtime/JSLock.h&gt;
</span><span class="lines">@@ -85,6 +86,8 @@
</span><span class="cx"> InspectorController::InspectorController(Page&amp; page, InspectorClient* inspectorClient)
</span><span class="cx">     : m_instrumentingAgents(InstrumentingAgents::create(*this))
</span><span class="cx">     , m_injectedScriptManager(std::make_unique&lt;WebInjectedScriptManager&gt;(*this, WebInjectedScriptHost::create()))
</span><ins>+    , m_frontendRouter(FrontendRouter::create())
+    , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
</ins><span class="cx">     , m_overlay(std::make_unique&lt;InspectorOverlay&gt;(page, inspectorClient))
</span><span class="cx">     , m_executionStopwatch(Stopwatch::create())
</span><span class="cx">     , m_page(page)
</span><span class="lines">@@ -177,7 +180,8 @@
</span><span class="cx"> 
</span><span class="cx"> void InspectorController::inspectedPageDestroyed()
</span><span class="cx"> {
</span><del>-    disconnectFrontend(DisconnectReason::InspectedTargetDestroyed);
</del><ins>+    disconnectAllFrontends();
+
</ins><span class="cx">     m_injectedScriptManager-&gt;disconnect();
</span><span class="cx">     m_inspectorClient-&gt;inspectorDestroyed();
</span><span class="cx">     m_inspectorClient = nullptr;
</span><span class="lines">@@ -190,12 +194,12 @@
</span><span class="cx"> 
</span><span class="cx"> bool InspectorController::hasLocalFrontend() const
</span><span class="cx"> {
</span><del>-    return m_frontendChannel &amp;&amp; m_frontendChannel-&gt;connectionType() == FrontendChannel::ConnectionType::Local;
</del><ins>+    return m_frontendRouter-&gt;hasLocalFrontend();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool InspectorController::hasRemoteFrontend() const
</span><span class="cx"> {
</span><del>-    return m_frontendChannel &amp;&amp; m_frontendChannel-&gt;connectionType() == FrontendChannel::ConnectionType::Remote;
</del><ins>+    return m_frontendRouter-&gt;hasRemoteFrontend();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool InspectorController::hasInspectorFrontendClient() const
</span><span class="lines">@@ -219,74 +223,96 @@
</span><span class="cx"> 
</span><span class="cx"> void InspectorController::connectFrontend(Inspector::FrontendChannel* frontendChannel, bool isAutomaticInspection)
</span><span class="cx"> {
</span><del>-    ASSERT(frontendChannel);
</del><ins>+    ASSERT_ARG(frontendChannel, frontendChannel);
</ins><span class="cx">     ASSERT(m_inspectorClient);
</span><del>-    ASSERT(!m_frontendChannel);
-    ASSERT(!m_backendDispatcher);
</del><span class="cx"> 
</span><ins>+    bool connectedFirstFrontend = !m_frontendRouter-&gt;hasFrontends();
</ins><span class="cx">     m_isAutomaticInspection = isAutomaticInspection;
</span><span class="cx"> 
</span><del>-    m_frontendChannel = frontendChannel;
-    m_backendDispatcher = BackendDispatcher::create(frontendChannel);
</del><ins>+    m_frontendRouter-&gt;connectFrontend(frontendChannel);
</ins><span class="cx"> 
</span><del>-    m_agents.didCreateFrontendAndBackend(frontendChannel, m_backendDispatcher.get());
-
-    InspectorInstrumentation::registerInstrumentingAgents(m_instrumentingAgents.get());
</del><span class="cx">     InspectorInstrumentation::frontendCreated();
</span><span class="cx"> 
</span><ins>+    if (connectedFirstFrontend) {
+        InspectorInstrumentation::registerInstrumentingAgents(m_instrumentingAgents.get());
+        m_agents.didCreateFrontendAndBackend(frontendChannel, &amp;m_backendDispatcher.get());
+    }
+
</ins><span class="cx"> #if ENABLE(REMOTE_INSPECTOR)
</span><del>-    if (!hasRemoteFrontend())
</del><ins>+    if (!m_frontendRouter-&gt;hasRemoteFrontend())
</ins><span class="cx">         m_page.remoteInspectorInformationDidChange();
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void InspectorController::disconnectFrontend(DisconnectReason reason)
</del><ins>+void InspectorController::disconnectFrontend(FrontendChannel* frontendChannel)
</ins><span class="cx"> {
</span><del>-    if (!m_frontendChannel)
-        return;
</del><ins>+    // The local frontend client should be disconnected first so it stops sending messages.
+    ASSERT(!m_frontendRouter-&gt;hasLocalFrontend() || !m_inspectorFrontendClient);
</ins><span class="cx"> 
</span><ins>+    m_frontendRouter-&gt;disconnectFrontend(frontendChannel);
+    m_isAutomaticInspection = false;
+
+    InspectorInstrumentation::frontendDeleted();
+
+    bool disconnectedLastFrontend = !m_frontendRouter-&gt;hasFrontends();
+    if (disconnectedLastFrontend) {
+        // Release overlay page resources.
+        m_overlay-&gt;freePage();
+        m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectorDestroyed);
+        InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get());
+    }
+
</ins><span class="cx"> #if ENABLE(REMOTE_INSPECTOR)
</span><del>-    if (!hasRemoteFrontend())
</del><ins>+    if (!m_frontendRouter-&gt;hasFrontends())
</ins><span class="cx">         m_page.remoteInspectorInformationDidChange();
</span><span class="cx"> #endif
</span><ins>+}
</ins><span class="cx"> 
</span><del>-    m_agents.willDestroyFrontendAndBackend(reason);
</del><ins>+void InspectorController::disconnectAllFrontends()
+{
+    // The local frontend client should be disconnected first so it stops sending messages.
+    ASSERT(!m_frontendRouter-&gt;hasLocalFrontend() || !m_inspectorFrontendClient);
</ins><span class="cx"> 
</span><del>-    m_backendDispatcher-&gt;clearFrontend();
-    m_backendDispatcher = nullptr;
-    m_frontendChannel = nullptr;
</del><ins>+    m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectedTargetDestroyed);
</ins><span class="cx"> 
</span><ins>+    m_frontendRouter-&gt;disconnectAllFrontends();
</ins><span class="cx">     m_isAutomaticInspection = false;
</span><span class="cx"> 
</span><span class="cx">     // Release overlay page resources.
</span><span class="cx">     m_overlay-&gt;freePage();
</span><del>-    InspectorInstrumentation::frontendDeleted();
</del><ins>+
+    while (InspectorInstrumentation::hasFrontends())
+        InspectorInstrumentation::frontendDeleted();
+
</ins><span class="cx">     InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get());
</span><ins>+    
+#if ENABLE(REMOTE_INSPECTOR)
+    m_page.remoteInspectorInformationDidChange();
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorController::show()
</span><span class="cx"> {
</span><del>-    ASSERT(!hasRemoteFrontend());
</del><ins>+    ASSERT(!m_frontendRouter-&gt;hasRemoteFrontend());
</ins><span class="cx"> 
</span><ins>+    // The local frontend client should be disconnected if there's no local frontend.
+    ASSERT(m_frontendRouter-&gt;hasLocalFrontend() || !m_inspectorFrontendClient);
+
</ins><span class="cx">     if (!enabled())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    if (m_frontendChannel)
</del><ins>+    if (m_frontendRouter-&gt;hasLocalFrontend())
</ins><span class="cx">         m_inspectorClient-&gt;bringFrontendToFront();
</span><del>-    else {
-        if (Inspector::FrontendChannel* frontendChannel = m_inspectorClient-&gt;openInspectorFrontend(this)) {
-            bool isAutomaticInspection = false;
-            connectFrontend(frontendChannel, isAutomaticInspection);
-        }
-    }
</del><ins>+    else if (Inspector::FrontendChannel* frontendChannel = m_inspectorClient-&gt;openInspectorFrontend(this))
+        connectFrontend(frontendChannel);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorController::close()
</span><span class="cx"> {
</span><del>-    if (!m_frontendChannel)
-        return;
-    disconnectFrontend(DisconnectReason::InspectorDestroyed);
-    m_inspectorClient-&gt;closeInspectorFrontend();
</del><ins>+    if (m_frontendRouter-&gt;hasLocalFrontend())
+        m_inspectorClient-&gt;closeInspectorFrontend();
+
+    ASSERT(!m_frontendRouter-&gt;hasLocalFrontend());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorController::setProcessId(long processId)
</span><span class="lines">@@ -337,8 +363,7 @@
</span><span class="cx"> 
</span><span class="cx"> void InspectorController::dispatchMessageFromFrontend(const String&amp; message)
</span><span class="cx"> {
</span><del>-    if (m_backendDispatcher)
-        m_backendDispatcher-&gt;dispatch(message);
</del><ins>+    m_backendDispatcher-&gt;dispatch(message);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorController::hideHighlight()
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorController.h (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorController.h        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/inspector/InspectorController.h        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -45,6 +45,7 @@
</span><span class="cx"> namespace Inspector {
</span><span class="cx"> class BackendDispatcher;
</span><span class="cx"> class FrontendChannel;
</span><ins>+class FrontendRouter;
</ins><span class="cx"> class InspectorAgent;
</span><span class="cx"> class InspectorObject;
</span><span class="cx"> 
</span><span class="lines">@@ -98,8 +99,9 @@
</span><span class="cx">     bool hasLocalFrontend() const;
</span><span class="cx">     bool hasRemoteFrontend() const;
</span><span class="cx"> 
</span><del>-    WEBCORE_EXPORT void connectFrontend(Inspector::FrontendChannel*, bool isAutomaticInspection);
-    WEBCORE_EXPORT void disconnectFrontend(Inspector::DisconnectReason);
</del><ins>+    WEBCORE_EXPORT void connectFrontend(Inspector::FrontendChannel*, bool isAutomaticInspection = false);
+    WEBCORE_EXPORT void disconnectFrontend(Inspector::FrontendChannel*);
+    WEBCORE_EXPORT void disconnectAllFrontends();
</ins><span class="cx">     void setProcessId(long);
</span><span class="cx"> 
</span><span class="cx">     void inspect(Node*);
</span><span class="lines">@@ -140,8 +142,8 @@
</span><span class="cx"> 
</span><span class="cx">     Ref&lt;InstrumentingAgents&gt; m_instrumentingAgents;
</span><span class="cx">     std::unique_ptr&lt;WebInjectedScriptManager&gt; m_injectedScriptManager;
</span><del>-    RefPtr&lt;Inspector::BackendDispatcher&gt; m_backendDispatcher;
-    Inspector::FrontendChannel* m_frontendChannel { nullptr };
</del><ins>+    Ref&lt;Inspector::FrontendRouter&gt; m_frontendRouter;
+    Ref&lt;Inspector::BackendDispatcher&gt; m_backendDispatcher;
</ins><span class="cx">     std::unique_ptr&lt;InspectorOverlay&gt; m_overlay;
</span><span class="cx">     Ref&lt;WTF::Stopwatch&gt; m_executionStopwatch;
</span><span class="cx">     Inspector::AgentRegistry m_agents;
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorDatabaseAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorDatabaseAgent.cpp (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorDatabaseAgent.cpp        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/inspector/InspectorDatabaseAgent.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -44,6 +44,7 @@
</span><span class="cx"> #include &quot;SQLTransactionErrorCallback.h&quot;
</span><span class="cx"> #include &quot;SQLValue.h&quot;
</span><span class="cx"> #include &quot;VoidCallback.h&quot;
</span><ins>+#include &lt;inspector/InspectorFrontendRouter.h&gt;
</ins><span class="cx"> #include &lt;inspector/InspectorValues.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorIndexedDBAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -64,6 +64,7 @@
</span><span class="cx"> #include &lt;inspector/InjectedScript.h&gt;
</span><span class="cx"> #include &lt;inspector/InjectedScriptManager.h&gt;
</span><span class="cx"> #include &lt;inspector/InspectorFrontendDispatchers.h&gt;
</span><ins>+#include &lt;inspector/InspectorFrontendRouter.h&gt;
</ins><span class="cx"> #include &lt;inspector/InspectorValues.h&gt;
</span><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorResourceAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorResourceAgent.cpp (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorResourceAgent.cpp        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/inspector/InspectorResourceAgent.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -62,6 +62,7 @@
</span><span class="cx"> #include &quot;URL.h&quot;
</span><span class="cx"> #include &quot;WebSocketFrame.h&quot;
</span><span class="cx"> #include &lt;inspector/IdentifiersFactory.h&gt;
</span><ins>+#include &lt;inspector/InspectorFrontendRouter.h&gt;
</ins><span class="cx"> #include &lt;inspector/InspectorValues.h&gt;
</span><span class="cx"> #include &lt;inspector/ScriptCallStack.h&gt;
</span><span class="cx"> #include &lt;inspector/ScriptCallStackFactory.h&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorWorkerInspectorControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/WorkerInspectorController.cpp (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/WorkerInspectorController.cpp        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/inspector/WorkerInspectorController.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -48,6 +48,7 @@
</span><span class="cx"> #include &quot;WorkerThread.h&quot;
</span><span class="cx"> #include &lt;inspector/InspectorBackendDispatcher.h&gt;
</span><span class="cx"> #include &lt;inspector/InspectorFrontendDispatchers.h&gt;
</span><ins>+#include &lt;inspector/InspectorFrontendRouter.h&gt;
</ins><span class="cx"> #include &lt;wtf/Stopwatch.h&gt;
</span><span class="cx"> 
</span><span class="cx"> using namespace Inspector;
</span><span class="lines">@@ -80,6 +81,8 @@
</span><span class="cx">     , m_instrumentingAgents(InstrumentingAgents::create(*this))
</span><span class="cx">     , m_injectedScriptManager(std::make_unique&lt;WebInjectedScriptManager&gt;(*this, WebInjectedScriptHost::create()))
</span><span class="cx">     , m_executionStopwatch(Stopwatch::create())
</span><ins>+    , m_frontendRouter(FrontendRouter::create())
+    , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
</ins><span class="cx"> {
</span><span class="cx">     auto runtimeAgent = std::make_unique&lt;WorkerRuntimeAgent&gt;(*m_injectedScriptManager, &amp;workerGlobalScope);
</span><span class="cx">     m_runtimeAgent = runtimeAgent.get();
</span><span class="lines">@@ -114,27 +117,27 @@
</span><span class="cx"> 
</span><span class="cx"> void WorkerInspectorController::connectFrontend()
</span><span class="cx"> {
</span><del>-    ASSERT(!m_frontendChannel);
-    m_frontendChannel = std::make_unique&lt;PageInspectorProxy&gt;(m_workerGlobalScope);
-    m_backendDispatcher = BackendDispatcher::create(m_frontendChannel.get());
-    m_agents.didCreateFrontendAndBackend(m_frontendChannel.get(), m_backendDispatcher.get());
</del><ins>+    ASSERT(!m_frontendRouter-&gt;hasFrontends());
+    ASSERT(!m_forwardingChannel);
+
+    m_forwardingChannel = std::make_unique&lt;PageInspectorProxy&gt;(m_workerGlobalScope);
+    m_frontendRouter-&gt;connectFrontend(m_forwardingChannel.get());
+    m_agents.didCreateFrontendAndBackend(m_forwardingChannel.get(), &amp;m_backendDispatcher.get());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WorkerInspectorController::disconnectFrontend(Inspector::DisconnectReason reason)
</span><span class="cx"> {
</span><del>-    if (!m_frontendChannel)
-        return;
</del><ins>+    ASSERT(m_frontendRouter-&gt;hasFrontends());
+    ASSERT(m_forwardingChannel);
</ins><span class="cx"> 
</span><span class="cx">     m_agents.willDestroyFrontendAndBackend(reason);
</span><del>-    m_backendDispatcher-&gt;clearFrontend();
-    m_backendDispatcher = nullptr;
-    m_frontendChannel = nullptr;
</del><ins>+    m_frontendRouter-&gt;disconnectFrontend(m_forwardingChannel.get());
+    m_forwardingChannel = nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WorkerInspectorController::dispatchMessageFromFrontend(const String&amp; message)
</span><span class="cx"> {
</span><del>-    if (m_backendDispatcher)
-        m_backendDispatcher-&gt;dispatch(message);
</del><ins>+    m_backendDispatcher-&gt;dispatch(message);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WorkerInspectorController::resume()
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorWorkerInspectorControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/WorkerInspectorController.h (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/WorkerInspectorController.h        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/inspector/WorkerInspectorController.h        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -41,6 +41,10 @@
</span><span class="cx"> #include &lt;wtf/RefPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> 
</span><ins>+namespace Inspector {
+class FrontendRouter;
+};
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class InspectorInstrumentation;
</span><span class="lines">@@ -78,9 +82,10 @@
</span><span class="cx">     std::unique_ptr&lt;WebInjectedScriptManager&gt; m_injectedScriptManager;
</span><span class="cx">     WorkerRuntimeAgent* m_runtimeAgent { nullptr };
</span><span class="cx">     Inspector::AgentRegistry m_agents;
</span><del>-    std::unique_ptr&lt;Inspector::FrontendChannel&gt; m_frontendChannel;
</del><ins>+    std::unique_ptr&lt;Inspector::FrontendChannel&gt; m_forwardingChannel;
</ins><span class="cx">     Ref&lt;WTF::Stopwatch&gt; m_executionStopwatch;
</span><del>-    RefPtr&lt;Inspector::BackendDispatcher&gt; m_backendDispatcher;
</del><ins>+    Ref&lt;Inspector::FrontendRouter&gt; m_frontendRouter;
+    Ref&lt;Inspector::BackendDispatcher&gt; m_backendDispatcher;
</ins><span class="cx">     Vector&lt;InspectorInstrumentationCookie, 2&gt; m_injectedScriptInstrumentationCookies;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorepagePageDebuggablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/PageDebuggable.cpp (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/PageDebuggable.cpp        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/page/PageDebuggable.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -80,10 +80,10 @@
</span><span class="cx">     inspectorController.connectFrontend(channel, isAutomaticInspection);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void PageDebuggable::disconnect()
</del><ins>+void PageDebuggable::disconnect(Inspector::FrontendChannel* channel)
</ins><span class="cx"> {
</span><span class="cx">     InspectorController&amp; inspectorController = m_page.inspectorController();
</span><del>-    inspectorController.disconnectFrontend(Inspector::DisconnectReason::InspectorDestroyed);
</del><ins>+    inspectorController.disconnectFrontend(channel);
</ins><span class="cx"> 
</span><span class="cx">     if (m_forcedDeveloperExtrasEnabled) {
</span><span class="cx">         m_forcedDeveloperExtrasEnabled = false;
</span></span></pre></div>
<a id="trunkSourceWebCorepagePageDebuggableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/PageDebuggable.h (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/PageDebuggable.h        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/page/PageDebuggable.h        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -49,7 +49,7 @@
</span><span class="cx">     virtual bool hasLocalDebugger() const override;
</span><span class="cx"> 
</span><span class="cx">     virtual void connect(Inspector::FrontendChannel*, bool isAutomaticInspection) override;
</span><del>-    virtual void disconnect() override;
</del><ins>+    virtual void disconnect(Inspector::FrontendChannel*) override;
</ins><span class="cx">     virtual void dispatchMessageFromRemoteFrontend(const String&amp; message) override;
</span><span class="cx">     virtual void setIndicating(bool) override;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.cpp (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.cpp        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/testing/Internals.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -1734,9 +1734,8 @@
</span><span class="cx">     m_frontendClient = std::make_unique&lt;InspectorFrontendClientDummy&gt;(&amp;page-&gt;inspectorController(), frontendPage);
</span><span class="cx">     frontendPage-&gt;inspectorController().setInspectorFrontendClient(m_frontendClient.get());
</span><span class="cx"> 
</span><del>-    bool isAutomaticInspection = false;
</del><span class="cx">     m_frontendChannel = std::make_unique&lt;InspectorFrontendChannelDummy&gt;(frontendPage);
</span><del>-    page-&gt;inspectorController().connectFrontend(m_frontendChannel.get(), isAutomaticInspection);
</del><ins>+    page-&gt;inspectorController().connectFrontend(m_frontendChannel.get());
</ins><span class="cx"> 
</span><span class="cx">     return m_frontendWindow;
</span><span class="cx"> }
</span><span class="lines">@@ -1747,9 +1746,13 @@
</span><span class="cx">     ASSERT(page);
</span><span class="cx">     ASSERT(m_frontendWindow);
</span><span class="cx"> 
</span><del>-    page-&gt;inspectorController().disconnectFrontend(Inspector::DisconnectReason::InspectorDestroyed);
</del><ins>+    Page* frontendPage = m_frontendWindow-&gt;document()-&gt;page();
+    ASSERT(frontendPage);
</ins><span class="cx"> 
</span><ins>+    frontendPage-&gt;inspectorController().setInspectorFrontendClient(nullptr);
</ins><span class="cx">     m_frontendClient = nullptr;
</span><ins>+
+    page-&gt;inspectorController().disconnectFrontend(m_frontendChannel.get());
</ins><span class="cx">     m_frontendChannel = nullptr;
</span><span class="cx"> 
</span><span class="cx">     m_frontendWindow-&gt;close(m_frontendWindow-&gt;scriptExecutionContext());
</span></span></pre></div>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/ChangeLog        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit/mac/ChangeLog        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2015-09-03  Brian Burg  &lt;bburg@apple.com&gt;
+
+        Web Inspector: InspectorController should support multiple frontend channels
+        https://bugs.webkit.org/show_bug.cgi?id=148538
+
+        Reviewed by Joseph Pecoraro.
+
+        Remove the notifyInspectorController flag from closeWindow. Since InspectorClients
+        must now manually disconnect their FrontendChannel(s), we should always
+        perform the teardown that was guarded by this flag.
+
+        * WebCoreSupport/WebInspectorClient.h:
+        * WebCoreSupport/WebInspectorClient.mm:
+        (WebInspectorClient::bringFrontendToFront): Add a missing assertion.
+        (WebInspectorFrontendClient::closeWindow):
+        (WebInspectorFrontendClient::disconnectFromBackend):
+        (-[WebInspectorWindowController windowShouldClose:]):
+        (-[WebInspectorWindowController destroyInspectorView]): Always clear the frontend client.
+        (-[WebInspectorWindowController destroyInspectorView:]): Renamed to above.
+
</ins><span class="cx"> 2015-08-26  Andy Estes  &lt;aestes@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Content Filtering] Determine navigation and content policy before continuing to filter a load
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebCoreSupportWebInspectorClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.h (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.h        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.h        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -124,7 +124,7 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void bringToFront() override;
</span><span class="cx">     virtual void closeWindow() override;
</span><del>-    virtual void disconnectFromBackend();
</del><ins>+    void disconnectFromBackend();
</ins><span class="cx"> 
</span><span class="cx">     virtual void attachWindow(DockSide) override;
</span><span class="cx">     virtual void detachWindow() override;
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebCoreSupportWebInspectorClientmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.mm (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.mm        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.mm        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -87,7 +87,7 @@
</span><span class="cx"> - (WebInspectorClient*)inspectorClient;
</span><span class="cx"> - (void)setAttachedWindowHeight:(unsigned)height;
</span><span class="cx"> - (void)setDockingUnavailable:(BOOL)unavailable;
</span><del>-- (void)destroyInspectorView:(bool)notifyInspectorController;
</del><ins>+- (void)destroyInspectorView;
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -130,6 +130,7 @@
</span><span class="cx"> 
</span><span class="cx"> void WebInspectorClient::bringFrontendToFront()
</span><span class="cx"> {
</span><ins>+    ASSERT(m_frontendClient);
</ins><span class="cx">     m_frontendClient-&gt;bringToFront();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -252,12 +253,12 @@
</span><span class="cx"> 
</span><span class="cx"> void WebInspectorFrontendClient::closeWindow()
</span><span class="cx"> {
</span><del>-    [m_windowController.get() destroyInspectorView:true];
</del><ins>+    [m_windowController.get() destroyInspectorView];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebInspectorFrontendClient::disconnectFromBackend()
</span><span class="cx"> {
</span><del>-    [m_windowController.get() destroyInspectorView:false];
</del><ins>+    [m_windowController.get() destroyInspectorView];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebInspectorFrontendClient::attachWindow(DockSide)
</span><span class="lines">@@ -522,7 +523,7 @@
</span><span class="cx"> 
</span><span class="cx"> - (BOOL)windowShouldClose:(id)sender
</span><span class="cx"> {
</span><del>-    [self destroyInspectorView:true];
</del><ins>+    [self destroyInspectorView];
</ins><span class="cx"> 
</span><span class="cx">     return YES;
</span><span class="cx"> }
</span><span class="lines">@@ -676,7 +677,7 @@
</span><span class="cx">     // Do nothing.
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (void)destroyInspectorView:(bool)notifyInspectorController
</del><ins>+- (void)destroyInspectorView
</ins><span class="cx"> {
</span><span class="cx">     RetainPtr&lt;WebInspectorWindowController&gt; protect(self);
</span><span class="cx"> 
</span><span class="lines">@@ -692,9 +693,9 @@
</span><span class="cx"> 
</span><span class="cx">     _visible = NO;
</span><span class="cx"> 
</span><del>-    if (notifyInspectorController) {
-        if (Page* inspectedPage = [_inspectedWebView.get() page])
-            inspectedPage-&gt;inspectorController().disconnectFrontend(Inspector::DisconnectReason::InspectorDestroyed);
</del><ins>+    if (Page* inspectedPage = [_inspectedWebView.get() page]) {
+        inspectedPage-&gt;inspectorController().setInspectorFrontendClient(nullptr);
+        inspectedPage-&gt;inspectorController().disconnectFrontend(_inspectorClient);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     [_webView close];
</span></span></pre></div>
<a id="trunkSourceWebKitwinChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/ChangeLog (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/win/ChangeLog        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit/win/ChangeLog        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2015-09-03  Brian Burg  &lt;bburg@apple.com&gt;
+
+        Web Inspector: InspectorController should support multiple frontend channels
+        https://bugs.webkit.org/show_bug.cgi?id=148538
+
+        Reviewed by Joseph Pecoraro.
+
+        Remove the notifyInspectorController flag from closeWindow. Since InspectorClients
+        must now manually disconnect their FrontendChannel(s), we should always
+        perform the teardown that was guarded by this flag.
+
+        * WebCoreSupport/WebInspectorClient.cpp:
+        (WebInspectorClient::closeInspectorFrontend):
+        (WebInspectorFrontendClient::~WebInspectorFrontendClient):
+        (WebInspectorFrontendClient::closeWindow):
+        (WebInspectorFrontendClient::destroyInspectorView):
+        * WebCoreSupport/WebInspectorClient.h:
+
</ins><span class="cx"> 2015-09-02  Andreas Kling  &lt;akling@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         ScrollbarThemes should be returned by reference.
</span></span></pre></div>
<a id="trunkSourceWebKitwinWebCoreSupportWebInspectorClientcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/WebCoreSupport/WebInspectorClient.cpp (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/win/WebCoreSupport/WebInspectorClient.cpp        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit/win/WebCoreSupport/WebInspectorClient.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -174,7 +174,7 @@
</span><span class="cx"> void WebInspectorClient::closeInspectorFrontend()
</span><span class="cx"> {
</span><span class="cx">     if (m_frontendClient)
</span><del>-        m_frontendClient-&gt;destroyInspectorView(false);
</del><ins>+        m_frontendClient-&gt;destroyInspectorView();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebInspectorClient::bringFrontendToFront()
</span><span class="lines">@@ -237,7 +237,7 @@
</span><span class="cx"> 
</span><span class="cx"> WebInspectorFrontendClient::~WebInspectorFrontendClient()
</span><span class="cx"> {
</span><del>-    destroyInspectorView(true);
</del><ins>+    destroyInspectorView();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebInspectorFrontendClient::frontendLoaded()
</span><span class="lines">@@ -269,7 +269,7 @@
</span><span class="cx"> 
</span><span class="cx"> void WebInspectorFrontendClient::closeWindow()
</span><span class="cx"> {
</span><del>-    destroyInspectorView(true);
</del><ins>+    destroyInspectorView();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebInspectorFrontendClient::attachWindow(DockSide)
</span><span class="lines">@@ -421,7 +421,7 @@
</span><span class="cx">     m_inspectorClient-&gt;updateHighlight();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebInspectorFrontendClient::destroyInspectorView(bool notifyInspectorController)
</del><ins>+void WebInspectorFrontendClient::destroyInspectorView()
</ins><span class="cx"> {
</span><span class="cx">     m_inspectorClient-&gt;releaseFrontend();
</span><span class="cx"> 
</span><span class="lines">@@ -431,10 +431,10 @@
</span><span class="cx"> 
</span><span class="cx">     closeWindowWithoutNotifications();
</span><span class="cx"> 
</span><del>-    if (notifyInspectorController) {
-        m_inspectedWebView-&gt;page()-&gt;inspectorController().disconnectFrontend(Inspector::DisconnectReason::InspectorDestroyed);
-        m_inspectorClient-&gt;updateHighlight();
-    }
</del><ins>+    m_inspectedWebView-&gt;page()-&gt;inspectorController().setInspectorFrontendClient(nullptr);
+    m_inspectedWebView-&gt;page()-&gt;inspectorController().disconnectFrontend(m_inspectorClient);
+    m_inspectorClient-&gt;updateHighlight();
+
</ins><span class="cx">     ::DestroyWindow(m_frontendHwnd);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitwinWebCoreSupportWebInspectorClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/WebCoreSupport/WebInspectorClient.h (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/win/WebCoreSupport/WebInspectorClient.h        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit/win/WebCoreSupport/WebInspectorClient.h        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -113,7 +113,7 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void inspectedURLChanged(const WTF::String&amp; newURL);
</span><span class="cx"> 
</span><del>-    void destroyInspectorView(bool notifyInspectorController);
</del><ins>+    void destroyInspectorView();
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     void closeWindowWithoutNotifications();
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit2/ChangeLog        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2015-09-03  Brian Burg  &lt;bburg@apple.com&gt;
+
+        Web Inspector: InspectorController should support multiple frontend channels
+        https://bugs.webkit.org/show_bug.cgi?id=148538
+
+        Reviewed by Joseph Pecoraro.
+
+        Explicitly disconnect the frontend channel when closing the frontend.
+
+        Rename createInspectorPage/closeFrontend to the symmetric and unambiguous
+        {open,close}FrontendConnection in the WebInspector class.
+
+        * WebProcess/WebCoreSupport/WebInspectorClient.cpp:
+        (WebKit::WebInspectorClient::openInspectorFrontend):
+        (WebKit::WebInspectorClient::closeInspectorFrontend):
+        * WebProcess/WebCoreSupport/WebInspectorClient.h: Stop using a forwarded type.
+        * WebProcess/WebPage/WebInspector.cpp:
+        (WebKit::WebInspector::openFrontendConnection):
+        (WebKit::WebInspector::closeFrontendConnection):
+        (WebKit::WebInspector::remoteFrontendConnected):
+        (WebKit::WebInspector::remoteFrontendDisconnected):
+        (WebKit::WebInspector::createInspectorPage): Deleted.
+        (WebKit::WebInspector::closeFrontend): Deleted.
+        * WebProcess/WebPage/WebInspector.h:
+
</ins><span class="cx"> 2015-09-03  Timothy Hatcher  &lt;timothy@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Closing the Safari window when the Web Inspector is one of the other windows in split screen mode can cause the entire screen to go black
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportWebInspectorClientcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.cpp (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.cpp        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -82,17 +82,19 @@
</span><span class="cx">     delete this;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-WebCore::InspectorFrontendChannel* WebInspectorClient::openInspectorFrontend(InspectorController* controller)
</del><ins>+Inspector::FrontendChannel* WebInspectorClient::openInspectorFrontend(InspectorController* controller)
</ins><span class="cx"> {
</span><del>-    m_page-&gt;inspector()-&gt;createInspectorPage(controller-&gt;isUnderTest());
</del><ins>+    m_page-&gt;inspector()-&gt;openFrontendConnection(controller-&gt;isUnderTest());
</ins><span class="cx"> 
</span><span class="cx">     return m_page-&gt;inspector();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebInspectorClient::closeInspectorFrontend()
</span><span class="cx"> {
</span><del>-    if (m_page-&gt;inspector())
-        m_page-&gt;inspector()-&gt;closeFrontend();
</del><ins>+    if (m_page-&gt;inspector()) {
+        m_page-&gt;corePage()-&gt;inspectorController().disconnectFrontend(m_page-&gt;inspector());
+        m_page-&gt;inspector()-&gt;closeFrontendConnection();
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebInspectorClient::bringFrontendToFront()
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportWebInspectorClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.h (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.h        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.h        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -27,7 +27,6 @@
</span><span class="cx"> #define WebInspectorClient_h
</span><span class="cx"> 
</span><span class="cx"> #include &lt;WebCore/InspectorClient.h&gt;
</span><del>-#include &lt;WebCore/InspectorForwarding.h&gt;
</del><span class="cx"> #include &lt;WebCore/PageOverlay.h&gt;
</span><span class="cx"> #include &lt;wtf/HashSet.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -53,7 +52,7 @@
</span><span class="cx">     // WebCore::InspectorClient
</span><span class="cx">     void inspectorDestroyed() override;
</span><span class="cx"> 
</span><del>-    WebCore::InspectorFrontendChannel* openInspectorFrontend(WebCore::InspectorController*) override;
</del><ins>+    Inspector::FrontendChannel* openInspectorFrontend(WebCore::InspectorController*) override;
</ins><span class="cx">     void closeInspectorFrontend() override;
</span><span class="cx">     void bringFrontendToFront() override;
</span><span class="cx">     void didResizeMainFrame(WebCore::Frame*) override;
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebInspectorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -70,7 +70,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // Called from WebInspectorClient
</span><del>-void WebInspector::createInspectorPage(bool underTest)
</del><ins>+void WebInspector::openFrontendConnection(bool underTest)
</ins><span class="cx"> {
</span><span class="cx"> #if OS(DARWIN)
</span><span class="cx">     mach_port_t listeningPort;
</span><span class="lines">@@ -93,7 +93,7 @@
</span><span class="cx">     WebProcess::singleton().parentProcessConnection()-&gt;send(Messages::WebInspectorProxy::CreateInspectorPage(connectionClientPort, canAttachWindow(), underTest), m_page-&gt;pageID());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebInspector::closeFrontend()
</del><ins>+void WebInspector::closeFrontendConnection()
</ins><span class="cx"> {
</span><span class="cx">     WebProcess::singleton().parentProcessConnection()-&gt;send(Messages::WebInspectorProxy::DidClose(), m_page-&gt;pageID());
</span><span class="cx"> 
</span><span class="lines">@@ -262,8 +262,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (m_page-&gt;corePage()) {
</span><span class="cx">         m_remoteFrontendConnected = true;
</span><del>-        bool isAutomaticInspection = false;
-        m_page-&gt;corePage()-&gt;inspectorController().connectFrontend(this, isAutomaticInspection);
</del><ins>+        m_page-&gt;corePage()-&gt;inspectorController().connectFrontend(this);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -272,7 +271,7 @@
</span><span class="cx">     m_remoteFrontendConnected = false;
</span><span class="cx"> 
</span><span class="cx">     if (m_page-&gt;corePage())
</span><del>-        m_page-&gt;corePage()-&gt;inspectorController().disconnectFrontend(Inspector::DisconnectReason::InspectorDestroyed);
</del><ins>+        m_page-&gt;corePage()-&gt;inspectorController().disconnectFrontend(this);
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebInspectorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebInspector.h (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebInspector.h        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebInspector.h        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -97,9 +97,9 @@
</span><span class="cx">     bool canAttachWindow();
</span><span class="cx"> 
</span><span class="cx">     // Called from WebInspectorClient
</span><del>-    void createInspectorPage(bool underTest);
</del><ins>+    void openFrontendConnection(bool underTest);
+    void closeFrontendConnection();
</ins><span class="cx"> 
</span><del>-    void closeFrontend();
</del><span class="cx">     void bringToFront();
</span><span class="cx"> 
</span><span class="cx">     WebPage* m_page;
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Tools/ChangeLog        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2015-09-03  Brian Burg  &lt;bburg@apple.com&gt;
+
+        Web Inspector: InspectorController should support multiple frontend channels
+        https://bugs.webkit.org/show_bug.cgi?id=148538
+
+        Reviewed by Joseph Pecoraro.
+
+        InspectorClients must explicitly disconnect their frontend channel(s) from the
+        inspected page's InspectorController.
+
+        To make this possible, DumpRenderTree should not destroy non-primary views until
+        it has tried to close any abandoned Web Inspector instances. Performing teardown
+        in the reverse order prevents disconnection of the frontend channel because that
+        prematurely destroys the inspector frontend client.
+
+        * DumpRenderTree/mac/DumpRenderTree.mm:
+        (runTest):
+        * DumpRenderTree/win/DumpRenderTree.cpp:
+        (runTest):
+
</ins><span class="cx"> 2015-09-03  Timothy Hatcher  &lt;timothy@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Update WebKit nightly icon to be more like Safari
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreemacDumpRenderTreemm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -2039,6 +2039,13 @@
</span><span class="cx"> 
</span><span class="cx">     workQueue.clear();
</span><span class="cx"> 
</span><ins>+    // If the test page could have possibly opened the Web Inspector frontend,
+    // then try to close it in case it was accidentally left open.
+    if (shouldEnableDeveloperExtras(pathOrURL.c_str())) {
+        gTestRunner-&gt;closeWebInspector();
+        gTestRunner-&gt;setDeveloperExtrasEnabled(false);
+    }
+
</ins><span class="cx">     if (gTestRunner-&gt;closeRemainingWindowsWhenComplete()) {
</span><span class="cx">         NSArray* array = [DumpRenderTreeWindow openWindows];
</span><span class="cx"> 
</span><span class="lines">@@ -2062,12 +2069,6 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // If developer extras enabled Web Inspector may have been open by the test.
-    if (shouldEnableDeveloperExtras(pathOrURL.c_str())) {
-        gTestRunner-&gt;closeWebInspector();
-        gTestRunner-&gt;setDeveloperExtrasEnabled(false);
-    }
-
</del><span class="cx">     resetWebViewToConsistentStateBeforeTesting();
</span><span class="cx"> 
</span><span class="cx">     // Loading an empty request synchronously replaces the document with a blank one, which is necessary
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreewinDumpRenderTreecpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/win/DumpRenderTree.cpp (189337 => 189338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/win/DumpRenderTree.cpp        2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Tools/DumpRenderTree/win/DumpRenderTree.cpp        2015-09-04 03:58:43 UTC (rev 189338)
</span><span class="lines">@@ -1147,6 +1147,13 @@
</span><span class="cx">     // EventSendingController clearSavedEvents
</span><span class="cx">     workQueue.clear();
</span><span class="cx"> 
</span><ins>+    // If the test page could have possibly opened the Web Inspector frontend,
+    // then try to close it in case it was accidentally left open.
+    if (shouldEnableDeveloperExtras(pathOrURL.c_str())) {
+        ::gTestRunner-&gt;closeWebInspector();
+        ::gTestRunner-&gt;setDeveloperExtrasEnabled(false);
+    }
+
</ins><span class="cx">     if (::gTestRunner-&gt;closeRemainingWindowsWhenComplete()) {
</span><span class="cx">         Vector&lt;HWND&gt; windows = openWindows();
</span><span class="cx">         unsigned size = windows.size();
</span><span class="lines">@@ -1161,11 +1168,6 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (shouldEnableDeveloperExtras(pathOrURL.c_str())) {
-        ::gTestRunner-&gt;closeWebInspector();
-        ::gTestRunner-&gt;setDeveloperExtrasEnabled(false);
-    }
-
</del><span class="cx">     resetWebViewToConsistentStateBeforeTesting();
</span><span class="cx"> 
</span><span class="cx">     // Loading an empty request synchronously replaces the document with a blank one, which is necessary
</span></span></pre>
</div>
</div>

</body>
</html>