<!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>[193870] trunk/Source/WebInspectorUI</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/193870">193870</a></dd>
<dt>Author</dt> <dd>bburg@apple.com</dd>
<dt>Date</dt> <dd>2015-12-09 14:45:21 -0800 (Wed, 09 Dec 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: control whether to collect and dump protocol messages using a WebInspector.Setting
https://bugs.webkit.org/show_bug.cgi?id=151635

Reviewed by Timothy Hatcher.

When closing and reopening the inspector, the setting for whether
to dump protocol messages should be persisted. Otherwise, enabling
dumping from the debug-only UI will miss the initial flood of
messages that are processed when the Inspector loads initial data.

To support a persistent setting, and build some infrastructure for
more advanced uses of collected protocol messages, this patch adds
a new object to trace protocol events. It gets callbacks for each
and implements the console-dumping functionality previously baked in
to InspectorBackend.

In follow-up patches, other protocol tracers will be added to save
protocol data to disk, marshall it to a higher inspection level,
or provide more fine-grained control over what is logged.

This change moves Setting.js into the Base/ directory,
since it is used by Views, Models, and now Protocol classes.

* UserInterface/Base/Setting.js: Renamed from Source/WebInspectorUI/UserInterface/Models/Setting.js.
(WebInspector.Setting):
(WebInspector.Setting.prototype.get name):
(WebInspector.Setting.prototype.get value):
(WebInspector.Setting.prototype.set value):
* UserInterface/Main.html:
* UserInterface/Protocol/InspectorBackend.js:
(InspectorBackendClass):
(InspectorBackendClass.prototype.set dumpInspectorProtocolMessages):
(InspectorBackendClass.prototype.get dumpInspectorProtocolMessages):

    We still want to support the legacy way to enable dumping:
    `InspectorBackend.dumpInspectorProtocolMessages = true`. This
    is because some tests always use it, and it's easier to set this
    flag in a custom Bootstrap.js file than to configure the Setting.

(InspectorBackendClass.prototype.set dumpInspectorTimeStats):
(InspectorBackendClass.prototype.get dumpInspectorTimeStats):

    We still want to support the legacy way to enable dumping:
    `InspectorBackend.dumpInspectorTimeStats = true`. This is
    because MessageDispatcher checks this flag for its logging.

(InspectorBackendClass.prototype.set activeTracer):
(InspectorBackendClass.prototype.get activeTracer):

    Set the active tracer, finalizing and removing any active tracer
    if one exists. If removing a custom tracer (setting to null), then
    re-sync activeTracer with the automatic tracing Setting.

(InspectorBackendClass.prototype.dispatch):
(InspectorBackendClass.prototype._startOrStopAutomaticTracing):

    Sync the Setting with activeTracer. If an custom tracer is active,
    don't replace it with the automatic logging tracer.

(InspectorBackendClass.prototype._sendCommandToBackendWithCallback):
(InspectorBackendClass.prototype._sendCommandToBackendExpectingPromise):
(InspectorBackendClass.prototype._sendMessageToBackend):
(InspectorBackendClass.prototype._dispatchResponse):
(InspectorBackendClass.prototype._dispatchEvent):
(InspectorBackendClass.prototype._flushPendingScripts):
* UserInterface/Protocol/LoggingProtocolTracer.js: Added.
(WebInspector.LoggingProtocolTracer):
(WebInspector.LoggingProtocolTracer.prototype.set dumpMessagesToConsole):
(WebInspector.LoggingProtocolTracer.prototype.get dumpMessagesToConsole):
(WebInspector.LoggingProtocolTracer.prototype.set dumpTimingDataToConsole):
(WebInspector.LoggingProtocolTracer.prototype.get dumpTimingDataToConsole):
(WebInspector.LoggingProtocolTracer.prototype.logFrontendException):
(WebInspector.LoggingProtocolTracer.prototype.logProtocolError):
(WebInspector.LoggingProtocolTracer.prototype.logFrontendRequest):
(WebInspector.LoggingProtocolTracer.prototype.logWillHandleResponse):
(WebInspector.LoggingProtocolTracer.prototype.logDidHandleResponse):
(WebInspector.LoggingProtocolTracer.prototype.logWillHandleEvent):
(WebInspector.LoggingProtocolTracer.prototype.logDidHandleEvent):
(WebInspector.LoggingProtocolTracer.prototype._processEntry):
* UserInterface/Protocol/ProtocolTracer.js: Added.
(WebInspector.ProtocolTracer.prototype.logStarted):
(WebInspector.ProtocolTracer.prototype.logFrontendException):
(WebInspector.ProtocolTracer.prototype.logProtocolError):
(WebInspector.ProtocolTracer.prototype.logFrontendRequest):
(WebInspector.ProtocolTracer.prototype.logWillHandleResponse):
(WebInspector.ProtocolTracer.prototype.logDidHandleResponse):
(WebInspector.ProtocolTracer.prototype.logWillHandleEvent):
(WebInspector.ProtocolTracer.prototype.logDidHandleEvent):        (WebInspector.ProtocolTracer.prototype.logFinished):
(WebInspector.ProtocolTracer):
* UserInterface/Test.html:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceMainhtml">trunk/Source/WebInspectorUI/UserInterface/Main.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceProtocolInspectorBackendjs">trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTesthtml">trunk/Source/WebInspectorUI/UserInterface/Test.html</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceBaseSettingjs">trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceProtocolLoggingProtocolTracerjs">trunk/Source/WebInspectorUI/UserInterface/Protocol/LoggingProtocolTracer.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceProtocolProtocolTracerjs">trunk/Source/WebInspectorUI/UserInterface/Protocol/ProtocolTracer.js</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsSettingjs">trunk/Source/WebInspectorUI/UserInterface/Models/Setting.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (193869 => 193870)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2015-12-09 22:39:46 UTC (rev 193869)
+++ trunk/Source/WebInspectorUI/ChangeLog        2015-12-09 22:45:21 UTC (rev 193870)
</span><span class="lines">@@ -1,5 +1,98 @@
</span><span class="cx"> 2015-12-09  Brian Burg  &lt;bburg@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Web Inspector: control whether to collect and dump protocol messages using a WebInspector.Setting
+        https://bugs.webkit.org/show_bug.cgi?id=151635
+
+        Reviewed by Timothy Hatcher.
+
+        When closing and reopening the inspector, the setting for whether
+        to dump protocol messages should be persisted. Otherwise, enabling
+        dumping from the debug-only UI will miss the initial flood of
+        messages that are processed when the Inspector loads initial data.
+
+        To support a persistent setting, and build some infrastructure for
+        more advanced uses of collected protocol messages, this patch adds
+        a new object to trace protocol events. It gets callbacks for each
+        and implements the console-dumping functionality previously baked in
+        to InspectorBackend.
+
+        In follow-up patches, other protocol tracers will be added to save
+        protocol data to disk, marshall it to a higher inspection level,
+        or provide more fine-grained control over what is logged.
+
+        This change moves Setting.js into the Base/ directory,
+        since it is used by Views, Models, and now Protocol classes.
+
+        * UserInterface/Base/Setting.js: Renamed from Source/WebInspectorUI/UserInterface/Models/Setting.js.
+        (WebInspector.Setting):
+        (WebInspector.Setting.prototype.get name):
+        (WebInspector.Setting.prototype.get value):
+        (WebInspector.Setting.prototype.set value):
+        * UserInterface/Main.html:
+        * UserInterface/Protocol/InspectorBackend.js:
+        (InspectorBackendClass):
+        (InspectorBackendClass.prototype.set dumpInspectorProtocolMessages):
+        (InspectorBackendClass.prototype.get dumpInspectorProtocolMessages):
+
+            We still want to support the legacy way to enable dumping:
+            `InspectorBackend.dumpInspectorProtocolMessages = true`. This
+            is because some tests always use it, and it's easier to set this
+            flag in a custom Bootstrap.js file than to configure the Setting.
+
+        (InspectorBackendClass.prototype.set dumpInspectorTimeStats):
+        (InspectorBackendClass.prototype.get dumpInspectorTimeStats):
+
+            We still want to support the legacy way to enable dumping:
+            `InspectorBackend.dumpInspectorTimeStats = true`. This is
+            because MessageDispatcher checks this flag for its logging.
+
+        (InspectorBackendClass.prototype.set activeTracer):
+        (InspectorBackendClass.prototype.get activeTracer):
+
+            Set the active tracer, finalizing and removing any active tracer
+            if one exists. If removing a custom tracer (setting to null), then
+            re-sync activeTracer with the automatic tracing Setting.
+
+        (InspectorBackendClass.prototype.dispatch):
+        (InspectorBackendClass.prototype._startOrStopAutomaticTracing):
+
+            Sync the Setting with activeTracer. If an custom tracer is active,
+            don't replace it with the automatic logging tracer.
+
+        (InspectorBackendClass.prototype._sendCommandToBackendWithCallback):
+        (InspectorBackendClass.prototype._sendCommandToBackendExpectingPromise):
+        (InspectorBackendClass.prototype._sendMessageToBackend):
+        (InspectorBackendClass.prototype._dispatchResponse):
+        (InspectorBackendClass.prototype._dispatchEvent):
+        (InspectorBackendClass.prototype._flushPendingScripts):
+        * UserInterface/Protocol/LoggingProtocolTracer.js: Added.
+        (WebInspector.LoggingProtocolTracer):
+        (WebInspector.LoggingProtocolTracer.prototype.set dumpMessagesToConsole):
+        (WebInspector.LoggingProtocolTracer.prototype.get dumpMessagesToConsole):
+        (WebInspector.LoggingProtocolTracer.prototype.set dumpTimingDataToConsole):
+        (WebInspector.LoggingProtocolTracer.prototype.get dumpTimingDataToConsole):
+        (WebInspector.LoggingProtocolTracer.prototype.logFrontendException):
+        (WebInspector.LoggingProtocolTracer.prototype.logProtocolError):
+        (WebInspector.LoggingProtocolTracer.prototype.logFrontendRequest):
+        (WebInspector.LoggingProtocolTracer.prototype.logWillHandleResponse):
+        (WebInspector.LoggingProtocolTracer.prototype.logDidHandleResponse):
+        (WebInspector.LoggingProtocolTracer.prototype.logWillHandleEvent):
+        (WebInspector.LoggingProtocolTracer.prototype.logDidHandleEvent):
+        (WebInspector.LoggingProtocolTracer.prototype._processEntry):
+        * UserInterface/Protocol/ProtocolTracer.js: Added.
+        (WebInspector.ProtocolTracer.prototype.logStarted):
+        (WebInspector.ProtocolTracer.prototype.logFrontendException):
+        (WebInspector.ProtocolTracer.prototype.logProtocolError):
+        (WebInspector.ProtocolTracer.prototype.logFrontendRequest):
+        (WebInspector.ProtocolTracer.prototype.logWillHandleResponse):
+        (WebInspector.ProtocolTracer.prototype.logDidHandleResponse):
+        (WebInspector.ProtocolTracer.prototype.logWillHandleEvent):
+        (WebInspector.ProtocolTracer.prototype.logDidHandleEvent):        (WebInspector.ProtocolTracer.prototype.logFinished):
+        (WebInspector.ProtocolTracer):
+        * UserInterface/Test.html:
+
+2015-12-09  Brian Burg  &lt;bburg@apple.com&gt;
+
</ins><span class="cx">         Web Inspector: zoom with Ctrl +/- doesn't work correctly when inspector is docked
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=152076
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceBaseSettingjsfromrev193867trunkSourceWebInspectorUIUserInterfaceModelsSettingjs"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js (from rev 193867, trunk/Source/WebInspectorUI/UserInterface/Models/Setting.js) (0 => 193870)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js        2015-12-09 22:45:21 UTC (rev 193870)
</span><span class="lines">@@ -0,0 +1,94 @@
</span><ins>+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2013 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:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.Setting = class Setting extends WebInspector.Object
+{
+    constructor(name, defaultValue)
+    {
+        super();
+
+        this._name = name;
+
+        let inspectionLevel = InspectorFrontendHost ? InspectorFrontendHost.inspectionLevel() : 1;
+        let levelString = inspectionLevel &gt; 1 ? &quot;-&quot; + inspectionLevel : &quot;&quot;;
+        this._localStorageKey = `com.apple.WebInspector${levelString}.${name}`;
+        this._defaultValue = defaultValue;
+    }
+
+    // Public
+
+    get name()
+    {
+        return this._name;
+    }
+
+    get value()
+    {
+        if (&quot;_value&quot; in this)
+            return this._value;
+
+        // Make a copy of the default value so changes to object values don't modify the default value.
+        this._value = JSON.parse(JSON.stringify(this._defaultValue));
+
+        if (!window.InspectorTest &amp;&amp; window.localStorage &amp;&amp; this._localStorageKey in window.localStorage) {
+            try {
+                this._value = JSON.parse(window.localStorage[this._localStorageKey]);
+            } catch(e) {
+                delete window.localStorage[this._localStorageKey];
+            }
+        }
+
+        return this._value;
+    }
+
+    set value(value)
+    {
+        this._value = value;
+
+        if (!window.InspectorTest &amp;&amp; window.localStorage) {
+            try {
+                // Use Object.shallowEqual to properly compare objects.
+                if (Object.shallowEqual(this._value, this._defaultValue))
+                    delete window.localStorage[this._localStorageKey];
+                else
+                    window.localStorage[this._localStorageKey] = JSON.stringify(this._value);
+            } catch(e) {
+                console.error(&quot;Error saving setting with name: &quot; + this._name);
+            }
+        }
+
+        this.dispatchEventToListeners(WebInspector.Setting.Event.Changed, this._value, {name: this._name});
+    }
+};
+
+WebInspector.Setting.Event = {
+    Changed: &quot;setting-changed&quot;
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceMainhtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (193869 => 193870)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Main.html        2015-12-09 22:39:46 UTC (rev 193869)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html        2015-12-09 22:45:21 UTC (rev 193870)
</span><span class="lines">@@ -224,7 +224,11 @@
</span><span class="cx">     &lt;script src=&quot;Base/MIMETypeUtilities.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Base/URLUtilities.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Base/Utilities.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Base/Setting.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx"> 
</span><ins>+    &lt;script src=&quot;Protocol/ProtocolTracer.js&quot;&gt;&lt;/script&gt;
+    &lt;script src=&quot;Protocol/LoggingProtocolTracer.js&quot;&gt;&lt;/script&gt;
+
</ins><span class="cx">     &lt;script src=&quot;Protocol/ApplicationCacheObserver.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Protocol/CSSObserver.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Protocol/ConsoleObserver.js&quot;&gt;&lt;/script&gt;
</span><span class="lines">@@ -328,7 +332,6 @@
</span><span class="cx">     &lt;script src=&quot;Models/ScriptInstrument.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/ScriptSyntaxTree.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/ScriptTimelineRecord.js&quot;&gt;&lt;/script&gt;
</span><del>-    &lt;script src=&quot;Models/Setting.js&quot;&gt;&lt;/script&gt;
</del><span class="cx">     &lt;script src=&quot;Models/SourceCodePosition.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/SourceCodeRevision.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/SourceCodeSearchMatchObject.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsSettingjs"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebInspectorUI/UserInterface/Models/Setting.js (193869 => 193870)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/Setting.js        2015-12-09 22:39:46 UTC (rev 193869)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Setting.js        2015-12-09 22:45:21 UTC (rev 193870)
</span><span class="lines">@@ -1,94 +0,0 @@
</span><del>-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- * Copyright (C) 2013 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:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-WebInspector.Setting = class Setting extends WebInspector.Object
-{
-    constructor(name, defaultValue)
-    {
-        super();
-
-        this._name = name;
-
-        let inspectionLevel = InspectorFrontendHost.inspectionLevel();
-        let levelString = inspectionLevel &gt; 1 ? &quot;-&quot; + inspectionLevel : &quot;&quot;;
-        this._localStorageKey = `com.apple.WebInspector${levelString}.${name}`;
-        this._defaultValue = defaultValue;
-    }
-
-    // Public
-
-    get name()
-    {
-        return this._name;
-    }
-
-    get value()
-    {
-        if (&quot;_value&quot; in this)
-            return this._value;
-
-        // Make a copy of the default value so changes to object values don't modify the default value.
-        this._value = JSON.parse(JSON.stringify(this._defaultValue));
-
-        if (!window.InspectorTest &amp;&amp; window.localStorage &amp;&amp; this._localStorageKey in window.localStorage) {
-            try {
-                this._value = JSON.parse(window.localStorage[this._localStorageKey]);
-            } catch(e) {
-                delete window.localStorage[this._localStorageKey];
-            }
-        }
-
-        return this._value;
-    }
-
-    set value(value)
-    {
-        this._value = value;
-
-        if (!window.InspectorTest &amp;&amp; window.localStorage) {
-            try {
-                // Use Object.shallowEqual to properly compare objects.
-                if (Object.shallowEqual(this._value, this._defaultValue))
-                    delete window.localStorage[this._localStorageKey];
-                else
-                    window.localStorage[this._localStorageKey] = JSON.stringify(this._value);
-            } catch(e) {
-                console.error(&quot;Error saving setting with name: &quot; + this._name);
-            }
-        }
-
-        this.dispatchEventToListeners(WebInspector.Setting.Event.Changed, this._value, {name: this._name});
-    }
-};
-
-WebInspector.Setting.Event = {
-    Changed: &quot;setting-changed&quot;
-};
</del></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceProtocolInspectorBackendjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js (193869 => 193870)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js        2015-12-09 22:39:46 UTC (rev 193869)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js        2015-12-09 22:45:21 UTC (rev 193870)
</span><span class="lines">@@ -38,17 +38,92 @@
</span><span class="cx">         this._pendingResponses = new Map;
</span><span class="cx">         this._agents = {};
</span><span class="cx">         this._deferredScripts = [];
</span><ins>+        this._activeTracer = null;
+        this._automaticTracer = null;
</ins><span class="cx"> 
</span><del>-        this.dumpInspectorTimeStats = false;
-        this.dumpInspectorProtocolMessages = false;
-        this.warnForLongMessageHandling = false;
-        this.longMessageHandlingThreshold = 10; // milliseconds.
</del><ins>+        this._dumpInspectorTimeStats = false;
</ins><span class="cx"> 
</span><del>-        this._log = window.InspectorTest ? InspectorFrontendHost.unbufferedLog.bind(InspectorFrontendHost) : console.log.bind(console);
</del><ins>+        let setting = WebInspector.autoLogProtocolMessagesSetting = new WebInspector.Setting(&quot;auto-collect-protocol-messages&quot;, false);
+        setting.addEventListener(WebInspector.Setting.Event.Changed, this._startOrStopAutomaticTracing.bind(this))
+        this._startOrStopAutomaticTracing();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Public
</span><span class="cx"> 
</span><ins>+    // It's still possible to set this flag on InspectorBackend to just
+    // dump protocol traffic as it happens. For more complex uses of
+    // protocol data, install a subclass of WebInspector.ProtocolTracer.
+    set dumpInspectorProtocolMessages(value)
+    {
+        // Implicitly cause automatic logging to start if it's allowed.
+        let setting = WebInspector.autoLogProtocolMessagesSetting;
+        setting.value = value;
+
+        if (this.activeTracer !== this._automaticTracer)
+            return;
+
+        if (this.activeTracer)
+            this.activeTracer.dumpMessagesToConsole = value;
+    }
+
+    get dumpInspectorProtocolMessages()
+    {
+        return !!this._automaticTracer;
+    }
+
+    set dumpInspectorTimeStats(value)
+    {
+        if (!this.dumpInspectorProtocolMessages)
+            this.dumpInspectorProtocolMessages = true;
+
+        if (this.activeTracer !== this._automaticTracer)
+            return;
+
+        if (this.activeTracer)
+            this.activeTracer.dumpTimingDataToConsole = value;
+    }
+
+    get dumpInspectorTimeStats()
+    {
+        return this._dumpInspectorTimeStats;
+    }
+
+    set activeTracer(tracer)
+    {
+        console.assert(!tracer || tracer instanceof WebInspector.ProtocolTracer);
+
+        // Bail early if no state change is to be made.
+        if (!tracer &amp;&amp; !this._activeTracer)
+            return;
+
+        if (tracer === this._activeTracer)
+            return;
+
+        // Don't allow an automatic tracer to dislodge a custom tracer.
+        if (this._activeTracer &amp;&amp; tracer === this._automaticTracer)
+            return;
+
+        if (this.activeTracer)
+            this.activeTracer.logFinished();
+
+        if (this._activeTracer === this._automaticTracer)
+            this._automaticTracer = null;
+
+        this._activeTracer = tracer;
+        if (this.activeTracer)
+            this.activeTracer.logStarted();
+        else {
+            // If the custom tracer was removed and automatic tracing is enabled,
+            // then create a new automatic tracer and install it in its place.
+            this._startOrStopAutomaticTracing();
+        }
+    }
+
+    get activeTracer()
+    {
+        return this._activeTracer || null;
+    }
+
</ins><span class="cx">     registerCommand(qualifiedName, callSignature, replySignature)
</span><span class="cx">     {
</span><span class="cx">         var [domainName, commandName] = qualifiedName.split(&quot;.&quot;);
</span><span class="lines">@@ -78,11 +153,8 @@
</span><span class="cx"> 
</span><span class="cx">     dispatch(message)
</span><span class="cx">     {
</span><del>-        if (this.dumpInspectorProtocolMessages)
-            this._log(&quot;backend: &quot; + ((typeof message === &quot;string&quot;) ? message : JSON.stringify(message)));
</del><ins>+        let messageObject = (typeof message === &quot;string&quot;) ? JSON.parse(message) : message;
</ins><span class="cx"> 
</span><del>-        var messageObject = (typeof message === &quot;string&quot;) ? JSON.parse(message) : message;
-
</del><span class="cx">         if (&quot;id&quot; in messageObject)
</span><span class="cx">             this._dispatchResponse(messageObject);
</span><span class="cx">         else
</span><span class="lines">@@ -113,6 +185,28 @@
</span><span class="cx"> 
</span><span class="cx">     // Private
</span><span class="cx"> 
</span><ins>+    _startOrStopAutomaticTracing()
+    {
+        let setting = WebInspector.autoLogProtocolMessagesSetting;
+
+        // Bail if there is no state transition to be made.
+        if (!(setting.value ^ !!this.activeTracer))
+            return;
+
+        if (!setting.value) {
+            if (this.activeTracer === this._automaticTracer)
+                this.activeTracer = null;
+
+            this._automaticTracer = null;
+        } else {
+            this._automaticTracer = new WebInspector.LoggingProtocolTracer;
+            this._automaticTracer.dumpMessagesToConsole = this.dumpInspectorProtocolMessages;
+            this._automaticTracer.dumpTimingDataToConsole = this.dumpTimingDataToConsole;
+            // This will be ignored if a custom tracer is installed.
+            this.activeTracer = this._automaticTracer;
+        }
+    }
+
</ins><span class="cx">     _agentForDomain(domainName)
</span><span class="cx">     {
</span><span class="cx">         if (this._agents[domainName])
</span><span class="lines">@@ -137,7 +231,7 @@
</span><span class="cx"> 
</span><span class="cx">         let responseData = {command, callback};
</span><span class="cx"> 
</span><del>-        if (this.dumpInspectorTimeStats)
</del><ins>+        if (this.activeTracer)
</ins><span class="cx">             responseData.sendRequestTimestamp = timestamp();
</span><span class="cx"> 
</span><span class="cx">         this._pendingResponses.set(sequenceId, responseData);
</span><span class="lines">@@ -158,7 +252,7 @@
</span><span class="cx"> 
</span><span class="cx">         let responseData = {command};
</span><span class="cx"> 
</span><del>-        if (this.dumpInspectorTimeStats)
</del><ins>+        if (this.activeTracer)
</ins><span class="cx">             responseData.sendRequestTimestamp = timestamp();
</span><span class="cx"> 
</span><span class="cx">         let responsePromise = new Promise(function(resolve, reject) {
</span><span class="lines">@@ -174,8 +268,8 @@
</span><span class="cx">     _sendMessageToBackend(messageObject)
</span><span class="cx">     {
</span><span class="cx">         let stringifiedMessage = JSON.stringify(messageObject);
</span><del>-        if (this.dumpInspectorProtocolMessages)
-            this._log(&quot;frontend: &quot; + stringifiedMessage);
</del><ins>+        if (this.activeTracer)
+            this.activeTracer.logFrontendRequest(stringifiedMessage);
</ins><span class="cx"> 
</span><span class="cx">         InspectorFrontendHost.sendMessageToBackend(stringifiedMessage);
</span><span class="cx">     }
</span><span class="lines">@@ -195,9 +289,11 @@
</span><span class="cx">         let responseData = this._pendingResponses.take(sequenceId);
</span><span class="cx">         let {command, callback, promise} = responseData;
</span><span class="cx"> 
</span><del>-        var processingStartTimestamp;
-        if (this.dumpInspectorTimeStats)
</del><ins>+        let processingStartTimestamp;
+        if (this.activeTracer) {
</ins><span class="cx">             processingStartTimestamp = timestamp();
</span><ins>+            this.activeTracer.logWillHandleResponse(JSON.stringify(messageObject));
+        }
</ins><span class="cx"> 
</span><span class="cx">         if (typeof callback === &quot;function&quot;)
</span><span class="cx">             this._dispatchResponseToCallback(command, messageObject, callback);
</span><span class="lines">@@ -206,13 +302,10 @@
</span><span class="cx">         else
</span><span class="cx">             console.error(&quot;Received a command response without a corresponding callback or promise.&quot;, messageObject, command);
</span><span class="cx"> 
</span><del>-        let processingDuration = (timestamp() - processingStartTimestamp).toFixed(3);
-        if (this.warnForLongMessageHandling &amp;&amp; processingDuration &gt; this.longMessageHandlingThreshold)
-            console.warn(`InspectorBackend: took ${processingDuration}ms to handle response for command: ${command.qualifiedName}`);
-
-        if (this.dumpInspectorTimeStats) {
-            let roundTripDuration = (processingStartTimestamp - responseData.sendRequestTimestamp).toFixed(3);
-            console.log(`time-stats: Handling: ${processingDuration}ms; RTT: ${roundTripDuration}ms; (command ${command.qualifiedName})`);
</del><ins>+        if (this.activeTracer) {
+            let processingTime = (timestamp() - processingStartTimestamp).toFixed(3);
+            let roundTripTime = (processingStartTimestamp - responseData.sendRequestTimestamp).toFixed(3);
+            this.activeTracer.logDidHandleResponse(JSON.stringify(messageObject), {rtt: roundTripTime, dispatch: processingTime});
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (this._deferredScripts.length &amp;&amp; !this._pendingResponses.size)
</span><span class="lines">@@ -247,48 +340,47 @@
</span><span class="cx"> 
</span><span class="cx">     _dispatchEvent(messageObject)
</span><span class="cx">     {
</span><del>-        var qualifiedName = messageObject[&quot;method&quot;];
-        var [domainName, eventName] = qualifiedName.split(&quot;.&quot;);
</del><ins>+        let qualifiedName = messageObject[&quot;method&quot;];
+        let [domainName, eventName] = qualifiedName.split(&quot;.&quot;);
</ins><span class="cx">         if (!(domainName in this._agents)) {
</span><span class="cx">             console.error(&quot;Protocol Error: Attempted to dispatch method '&quot; + eventName + &quot;' for non-existing domain '&quot; + domainName + &quot;'&quot;);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        var agent = this._agentForDomain(domainName);
</del><ins>+        let agent = this._agentForDomain(domainName);
</ins><span class="cx">         if (!agent.active) {
</span><span class="cx">             console.error(&quot;Protocol Error: Attempted to dispatch method for domain '&quot; + domainName + &quot;' which exists but is not active.&quot;);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        var event = agent.getEvent(eventName);
</del><ins>+        let event = agent.getEvent(eventName);
</ins><span class="cx">         if (!event) {
</span><span class="cx">             console.error(&quot;Protocol Error: Attempted to dispatch an unspecified method '&quot; + qualifiedName + &quot;'&quot;);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        var eventArguments = [];
-        if (messageObject[&quot;params&quot;]) {
-            var parameterNames = event.parameterNames;
-            for (var i = 0; i &lt; parameterNames.length; ++i)
-                eventArguments.push(messageObject[&quot;params&quot;][parameterNames[i]]);
-        }
</del><ins>+        let eventArguments = [];
+        if (messageObject[&quot;params&quot;])
+            eventArguments = event.parameterNames.map((name) =&gt; messageObject[&quot;params&quot;][name]);
</ins><span class="cx"> 
</span><del>-        var processingStartTimestamp;
-        if (this.dumpInspectorTimeStats)
</del><ins>+        let processingStartTimestamp;
+        if (this.activeTracer) {
</ins><span class="cx">             processingStartTimestamp = timestamp();
</span><ins>+            this.activeTracer.logWillHandleEvent(JSON.stringify(messageObject));
+        }
</ins><span class="cx"> 
</span><span class="cx">         try {
</span><span class="cx">             agent.dispatchEvent(eventName, eventArguments);
</span><span class="cx">         } catch (e) {
</span><span class="cx">             console.error(&quot;Uncaught exception in inspector page while handling event &quot; + qualifiedName, e);
</span><ins>+            if (this.activeTracer)
+                this.activeTracer.logFrontendException(JSON.stringify(messageObject), e);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        let processingDuration = (timestamp() - processingStartTimestamp).toFixed(3);
-        if (this.warnForLongMessageHandling &amp;&amp; processingDuration &gt; this.longMessageHandlingThreshold)
-            console.warn(`InspectorBackend: took ${processingDuration}ms to handle event: ${messageObject.method}`);
-
-        if (this.dumpInspectorTimeStats)
-            console.log(`time-stats: Handling: ${processingDuration}ms (event ${messageObject.method})`);
</del><ins>+        if (this.activeTracer) {
+            let processingTime = (timestamp() - processingStartTimestamp).toFixed(3);
+            this.activeTracer.logDidHandleEvent(JSON.stringify(messageObject), {dispatch: processingTime});
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     _reportProtocolError(messageObject)
</span><span class="lines">@@ -300,9 +392,9 @@
</span><span class="cx">     {
</span><span class="cx">         console.assert(this._pendingResponses.size === 0);
</span><span class="cx"> 
</span><del>-        var scriptsToRun = this._deferredScripts;
</del><ins>+        let scriptsToRun = this._deferredScripts;
</ins><span class="cx">         this._deferredScripts = [];
</span><del>-        for (var script of scriptsToRun)
</del><ins>+        for (let script of scriptsToRun)
</ins><span class="cx">             script.call(this);
</span><span class="cx">     }
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceProtocolLoggingProtocolTracerjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Protocol/LoggingProtocolTracer.js (0 => 193870)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Protocol/LoggingProtocolTracer.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/LoggingProtocolTracer.js        2015-12-09 22:45:21 UTC (rev 193870)
</span><span class="lines">@@ -0,0 +1,124 @@
</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.
+ */
+
+WebInspector.LoggingProtocolTracer = class LoggingProtocolTracer extends WebInspector.ProtocolTracer
+{
+    constructor()
+    {
+        super();
+
+        this._dumpMessagesToConsole = false;
+        this._dumpTimingDataToConsole = false;
+        this._logToConsole = window.InspectorTest ? InspectorFrontendHost.unbufferedLog.bind(InspectorFrontendHost) : console.log.bind(console);
+    }
+
+    // Public
+
+    set dumpMessagesToConsole(value)
+    {
+        this._dumpMessagesToConsole = !!value;
+    }
+
+    get dumpMessagesToConsole()
+    {
+        return this._dumpMessagesToConsole;
+    }
+
+    set dumpTimingDataToConsole(value)
+    {
+        this._dumpTimingDataToConsole = !!value;
+    }
+
+    get dumpTimingDataToConsole()
+    {
+        return this._dumpTimingDataToConsole;
+    }
+
+    logFrontendException(message, exception)
+    {
+        this._processEntry({type: &quot;exception&quot;, message, exception});
+    }
+
+    logProtocolError(message, error)
+    {
+        this._processEntry({type: &quot;error&quot;, message, error});
+    }
+
+    logFrontendRequest(message)
+    {
+        console.assert(typeof message === &quot;string&quot;, &quot;Must stringify messages to avoid leaking all JSON protocol messages.&quot;)
+
+        this._processEntry({type: &quot;request&quot;, message});
+    }
+
+    logWillHandleResponse(message)
+    {
+        console.assert(typeof message === &quot;string&quot;, &quot;Must stringify messages to avoid leaking all JSON protocol messages.&quot;)
+
+        let entry = {type: &quot;response&quot;, message};
+        this._processEntry(entry);
+    }
+
+    logDidHandleResponse(message, timings = null)
+    {
+        console.assert(typeof message === &quot;string&quot;, &quot;Must stringify messages to avoid leaking all JSON protocol messages.&quot;)
+
+        let entry = {type: &quot;response&quot;, message};
+        if (timings)
+            entry.timings = Object.shallowCopy(timings);
+
+        this._processEntry(entry);
+    }
+
+    logWillHandleEvent(message)
+    {
+        console.assert(typeof message === &quot;string&quot;, &quot;Must stringify messages to avoid leaking all JSON protocol messages.&quot;)
+
+        let entry = {type: &quot;event&quot;, message};
+        this._processEntry(entry);
+    }
+
+    logDidHandleEvent(message, timings = null)
+    {
+        console.assert(typeof message === &quot;string&quot;, &quot;Must stringify messages to avoid leaking all JSON protocol messages.&quot;)
+
+        let entry = {type: &quot;event&quot;, message};
+        if (timings)
+            entry.timings = Object.shallowCopy(timings);
+
+        this._processEntry(entry);
+    }
+
+    _processEntry(entry)
+    {
+        if (this._dumpTimingDataToConsole &amp;&amp; entry.timings) {
+            if (entry.timings.rtt &amp;&amp; entry.timings.dispatch)
+                this._logToConsole(`time-stats: Handling: ${entry.timings.dispatch || NaN}ms; RTT: ${entry.timings.rtt}ms`);
+            else if (entry.timings.dispatch)
+                this._logToConsole(`time-stats: Handling: ${entry.timings.dispatch || NaN}ms`);
+        } else if (this._dumpMessagesToConsole)
+            this._logToConsole(`${entry.type}: ${entry.message}`);
+    }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceProtocolProtocolTracerjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Protocol/ProtocolTracer.js (0 => 193870)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Protocol/ProtocolTracer.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/ProtocolTracer.js        2015-12-09 22:45:21 UTC (rev 193870)
</span><span class="lines">@@ -0,0 +1,88 @@
</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.
+ */
+
+WebInspector.ProtocolTracer = class ProtocolTracer extends WebInspector.Object
+{
+    // Public
+
+    logStarted()
+    {
+        // To be overridden by subclasses.
+    }
+
+    logFrontendException(message, exception)
+    {
+        console.assert(typeof message === &quot;string&quot;, &quot;Must stringify messages to avoid leaking all JSON protocol messages.&quot;)
+
+        // To be overridden by subclasses.
+    }
+
+    logProtocolError(message, error)
+    {
+        console.assert(typeof message === &quot;string&quot;, &quot;Must stringify messages to avoid leaking all JSON protocol messages.&quot;)
+
+        // To be overridden by subclasses.
+    }
+
+    logFrontendRequest(message)
+    {
+        console.assert(typeof message === &quot;string&quot;, &quot;Must stringify messages to avoid leaking all JSON protocol messages.&quot;)
+
+        // To be overridden by subclasses.
+    }
+
+    logWillHandleResponse(message)
+    {
+        console.assert(typeof message === &quot;string&quot;, &quot;Must stringify messages to avoid leaking all JSON protocol messages.&quot;)
+
+        // To be overridden by subclasses.
+    }
+
+    logDidHandleResponse(message, timings = null)
+    {
+        console.assert(typeof message === &quot;string&quot;, &quot;Must stringify messages to avoid leaking all JSON protocol messages.&quot;)
+
+        // To be overridden by subclasses.
+    }
+
+    logWillHandleEvent(message)
+    {
+        console.assert(typeof message === &quot;string&quot;, &quot;Must stringify messages to avoid leaking all JSON protocol messages.&quot;)
+
+        // To be overridden by subclasses.
+    }
+
+    logDidHandleEvent(message, timings = null)
+    {
+        console.assert(typeof message === &quot;string&quot;, &quot;Must stringify messages to avoid leaking all JSON protocol messages.&quot;)
+
+        // To be overridden by subclasses.
+    }
+
+    logFinished()
+    {
+        // To be overridden by subclasses.
+    }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTesthtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Test.html (193869 => 193870)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Test.html        2015-12-09 22:39:46 UTC (rev 193869)
+++ trunk/Source/WebInspectorUI/UserInterface/Test.html        2015-12-09 22:45:21 UTC (rev 193870)
</span><span class="lines">@@ -49,7 +49,11 @@
</span><span class="cx">     &lt;script src=&quot;Base/EventListenerSet.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Base/URLUtilities.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Base/Utilities.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Base/Setting.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx"> 
</span><ins>+    &lt;script src=&quot;Protocol/ProtocolTracer.js&quot;&gt;&lt;/script&gt;
+    &lt;script src=&quot;Protocol/LoggingProtocolTracer.js&quot;&gt;&lt;/script&gt;
+
</ins><span class="cx">     &lt;script src=&quot;Protocol/InspectorBackend.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Protocol/InspectorFrontendAPI.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Protocol/InspectorFrontendHostStub.js&quot;&gt;&lt;/script&gt;
</span><span class="lines">@@ -135,7 +139,6 @@
</span><span class="cx">     &lt;script src=&quot;Models/ScriptInstrument.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/ScriptSyntaxTree.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/ScriptTimelineRecord.js&quot;&gt;&lt;/script&gt;
</span><del>-    &lt;script src=&quot;Models/Setting.js&quot;&gt;&lt;/script&gt;
</del><span class="cx">     &lt;script src=&quot;Models/SourceCodeLocation.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/SourceCodeRevision.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/SourceCodeTimeline.js&quot;&gt;&lt;/script&gt;
</span></span></pre>
</div>
</div>

</body>
</html>