Web Inspector: [Console] Add console API message types for profile/profileEnd.
authoreustas@chromium.org <eustas@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Feb 2013 11:39:17 +0000 (11:39 +0000)
committereustas@chromium.org <eustas@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Feb 2013 11:39:17 +0000 (11:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=109790

Reviewed by Pavel Feldman.

With profile/profileEnd message types we will gain more control over
output messages.

* English.lproj/localizedStrings.js: Added corresponging strings.
* inspector/ConsoleAPITypes.h: Added enum members.
* inspector/Inspector.json: Ditto.
* inspector/front-end/ConsoleModel.js: Ditto.
* inspector/ConsoleMessage.cpp:
(WebCore::messageTypeValue): Added cases.
* inspector/InspectorProfilerAgent.cpp: Adopted changes.
* inspector/front-end/inspector.js: Ditto.
* inspector/front-end/ConsoleMessage.js:
Added message generators for introduced message types.
* inspector/front-end/ProfilesPanel.js:
Turned showProfileForURL(url) to showProfile(typeId, uid).
* inspector/front-end/ProfilesPanelDescriptor.js:
(WebInspector.ProfilesPanelDescriptor.resolveProfileTitle): Added.
* inspector/front-end/ResourceUtils.js: Removed linkifier plugins.

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

18 files changed:
LayoutTests/inspector/profiler/canvas2d/canvas-replay-log-grid.html
LayoutTests/inspector/profiler/heap-snapshot-inspect-dom-wrapper.html
LayoutTests/inspector/profiler/heap-snapshot-loader.html
LayoutTests/inspector/profiler/heap-snapshot-test.js
LayoutTests/inspector/profiler/profiler-test.js
PerformanceTests/inspector/heap-snapshot-performance-test.js
Source/WebCore/ChangeLog
Source/WebCore/English.lproj/localizedStrings.js
Source/WebCore/inspector/ConsoleAPITypes.h
Source/WebCore/inspector/ConsoleMessage.cpp
Source/WebCore/inspector/Inspector.json
Source/WebCore/inspector/InspectorProfilerAgent.cpp
Source/WebCore/inspector/front-end/ConsoleMessage.js
Source/WebCore/inspector/front-end/ConsoleModel.js
Source/WebCore/inspector/front-end/ProfilesPanel.js
Source/WebCore/inspector/front-end/ProfilesPanelDescriptor.js
Source/WebCore/inspector/front-end/ResourceUtils.js
Source/WebCore/inspector/front-end/inspector.js

index fb1611f..05a2765 100644 (file)
@@ -55,7 +55,7 @@ function test()
     function didStartCapturingFrame(profilesPanel, frameId, error, traceLogId)
     {
         profileHeader = profilesPanel.getProfiles(WebInspector.CanvasProfileType.TypeId)[0];
-        profilesPanel.showProfile(profileHeader);
+        profilesPanel._showProfile(profileHeader);
         InspectorTest.addSniffer(profileHeader, "_updateCapturingStatus", didReceiveFirstFrame);
         InspectorTest.evaluateInConsole("doSomeCanvasCalls(2)");
     }
index 035fc4c..924d5c5 100644 (file)
@@ -19,7 +19,7 @@ function test()
     function step0()
     {
         var profiles = WebInspector.panels.profiles.getProfiles("HEAP");
-        WebInspector.panels.profiles.showProfile(profiles[profiles.length - 1]);
+        WebInspector.panels.profiles._showProfile(profiles[profiles.length - 1]);
         InspectorTest.addSniffer(WebInspector.panels.profiles, "_finishHeapSnapshot", step1);
     }
 
index cd865be..0cdabdd 100644 (file)
@@ -45,7 +45,7 @@ function test()
         InspectorTest.addSniffer(profileHeader, "_snapshotReceived", snapshotLoaded);
 
         InspectorTest.override(HeapProfilerAgent, "getHeapSnapshot", getHeapSnapshotMock);
-        panel.showProfile(profileHeader);
+        panel._showProfile(profileHeader);
     }
 
     InspectorTest.runTestSuite([
index b581898..2e6bb1f 100644 (file)
@@ -738,7 +738,7 @@ InspectorTest.takeAndOpenSnapshot = function(generator, callback)
     InspectorTest.override(HeapProfilerAgent, "getHeapSnapshot", pushGeneratedSnapshot);
     InspectorTest._takeAndOpenSnapshotCallback = callback;
     WebInspector.panels.profiles.addProfileHeader(profile);
-    WebInspector.panels.profiles.showProfile(profile);
+    WebInspector.panels.profiles._showProfile(profile);
 };
 
 InspectorTest.viewColumns = function()
index cc7033c..2bcf30e 100644 (file)
@@ -66,7 +66,7 @@ InspectorTest.showProfileWhenAdded = function(title)
 InspectorTest._profileHeaderAdded = function(profile)
 {
     if (InspectorTest._showProfileWhenAdded === profile.title) {
-        WebInspector.panels.profiles.showProfile(profile);
+        WebInspector.panels.profiles._showProfile(profile);
     }
 };
 
index ad947b8..aa7ab35 100644 (file)
@@ -34,7 +34,7 @@ function test()
             timer.finish(backendTimerCookie);
             transferTimerCookie = timer.start("transfer-snapshot");
             var profiles = WebInspector.panels.profiles.getProfiles("HEAP");
-            WebInspector.panels.profiles.showProfile(profiles[profiles.length - 1]);
+            WebInspector.panels.profiles._showProfile(profiles[profiles.length - 1]);
             InspectorTest.addSniffer(WebInspector.panels.profiles, "_finishHeapSnapshot", step1);
         }
 
index 281a568..1b4d31d 100644 (file)
@@ -1,3 +1,29 @@
+2013-02-19  Eugene Klyuchnikov  <eustas@chromium.org>
+
+        Web Inspector: [Console] Add console API message types for profile/profileEnd.
+        https://bugs.webkit.org/show_bug.cgi?id=109790
+
+        Reviewed by Pavel Feldman.
+
+        With profile/profileEnd message types we will gain more control over
+        output messages.
+
+        * English.lproj/localizedStrings.js: Added corresponging strings.
+        * inspector/ConsoleAPITypes.h: Added enum members.
+        * inspector/Inspector.json: Ditto.
+        * inspector/front-end/ConsoleModel.js: Ditto.
+        * inspector/ConsoleMessage.cpp:
+        (WebCore::messageTypeValue): Added cases.
+        * inspector/InspectorProfilerAgent.cpp: Adopted changes.
+        * inspector/front-end/inspector.js: Ditto.
+        * inspector/front-end/ConsoleMessage.js:
+        Added message generators for introduced message types.
+        * inspector/front-end/ProfilesPanel.js:
+        Turned showProfileForURL(url) to showProfile(typeId, uid).
+        * inspector/front-end/ProfilesPanelDescriptor.js:
+        (WebInspector.ProfilesPanelDescriptor.resolveProfileTitle): Added.
+        * inspector/front-end/ResourceUtils.js: Removed linkifier plugins.
+
 2013-02-21  Tamas Czene  <tczene@inf.u-szeged.hu>
 
         OpenCL implementation of FEMerge filter.
index 119ab28..cfbd8fc 100644 (file)
@@ -311,6 +311,8 @@ localizedStrings["Paused"] = "Paused";
 localizedStrings["Paused on exception: '%s'."] = "Paused on exception: '%s'.";
 localizedStrings["Pausing"] = "Pausing";
 localizedStrings["Preview"] = "Preview";
+localizedStrings["Profile '%s' started."] = "Profile '%s' started.";
+localizedStrings["Profile '%s' finished."] = "Profile '%s' finished.";
 localizedStrings["Profiles"] = "Profiles";
 localizedStrings["Profiling disabled. Click to enable."] = "Profiling disabled. Click to enable.";
 localizedStrings["Profiling enabled. Click to disable."] = "Profiling enabled. Click to disable.";
index 31f03b2..11f65ec 100644 (file)
@@ -38,7 +38,9 @@ enum MessageType {
     EndGroupMessageType,
     ClearMessageType,
     AssertMessageType,
-    TimingMessageType
+    TimingMessageType,
+    ProfileMessageType,
+    ProfileEndMessageType
 };
 
 } // namespace WebCore
index 0a360de..de2ef04 100644 (file)
@@ -161,6 +161,8 @@ static TypeBuilder::Console::ConsoleMessage::Type::Enum messageTypeValue(Message
     case EndGroupMessageType: return TypeBuilder::Console::ConsoleMessage::Type::EndGroup;
     case AssertMessageType: return TypeBuilder::Console::ConsoleMessage::Type::Assert;
     case TimingMessageType: return TypeBuilder::Console::ConsoleMessage::Type::Timing;
+    case ProfileMessageType: return TypeBuilder::Console::ConsoleMessage::Type::Profile;
+    case ProfileEndMessageType: return TypeBuilder::Console::ConsoleMessage::Type::ProfileEnd;
     }
     return TypeBuilder::Console::ConsoleMessage::Type::Log;
 }
index 70ab7ee..489c1e6 100644 (file)
                     { "name": "source", "type": "string", "enum": ["html", "wml", "xml", "javascript", "network", "console-api", "other"], "description": "Message source." },
                     { "name": "level", "type": "string", "enum": ["tip", "log", "warning", "error", "debug"], "description": "Message severity." },
                     { "name": "text", "type": "string", "description": "Message text." },
-                    { "name": "type", "type": "string", "optional": true, "enum": ["log", "dir", "dirxml", "table", "trace", "clear", "startGroup", "startGroupCollapsed", "endGroup", "assert", "timing"], "description": "Console message type." },
+                    { "name": "type", "type": "string", "optional": true, "enum": ["log", "dir", "dirxml", "table", "trace", "clear", "startGroup", "startGroupCollapsed", "endGroup", "assert", "timing", "profile", "profileEnd"], "description": "Console message type." },
                     { "name": "url", "type": "string", "optional": true, "description": "URL of the message origin." },
                     { "name": "line", "type": "integer", "optional": true, "description": "Line number in the resource that generated this message." },
                     { "name": "repeatCount", "type": "integer", "optional": true, "description": "Repeat count for repeated messages." },
                     { "name": "arguments", "type": "array", "items": { "$ref": "CallArgument" }, "optional": true },
                     { "name": "result", "$ref": "CallArgument", "optional": true },
                     { "name": "isDrawingCall", "type": "boolean", "optional": true },
-                    { "name": "isFrameEndCall", "type": "boolean", "optional": true },
                     { "name": "property", "type": "string", "optional": true },
                     { "name": "value", "$ref": "CallArgument", "optional": true },
                     { "name": "sourceURL", "type": "string", "optional": true },
index 760fecf..39b35dc 100644 (file)
@@ -164,17 +164,15 @@ void InspectorProfilerAgent::addProfileFinishedMessageToConsole(PassRefPtr<Scrip
     if (!m_frontend)
         return;
     RefPtr<ScriptProfile> profile = prpProfile;
-    String title = profile->title();
-    String message = makeString("Profile \"webkit-profile://", CPUProfileType, '/', encodeWithURLEscapeSequences(title), '#', String::number(profile->uid()), "\" finished.");
-    m_consoleAgent->addMessageToConsole(ConsoleAPIMessageSource, LogMessageType, DebugMessageLevel, message, sourceURL, lineNumber);
+    String message = makeString(profile->title(), '#', String::number(profile->uid()));
+    m_consoleAgent->addMessageToConsole(ConsoleAPIMessageSource, ProfileEndMessageType, DebugMessageLevel, message, sourceURL, lineNumber);
 }
 
 void InspectorProfilerAgent::addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, const String& sourceURL)
 {
     if (!m_frontend)
         return;
-    String message = makeString("Profile \"webkit-profile://", CPUProfileType, '/', encodeWithURLEscapeSequences(title), "#0\" started.");
-    m_consoleAgent->addMessageToConsole(ConsoleAPIMessageSource, LogMessageType, DebugMessageLevel, message, sourceURL, lineNumber);
+    m_consoleAgent->addMessageToConsole(ConsoleAPIMessageSource, ProfileMessageType, DebugMessageLevel, title, sourceURL, lineNumber);
 }
 
 void InspectorProfilerAgent::collectGarbage(WebCore::ErrorString*)
index 0e582b2..fd852e8 100644 (file)
@@ -111,6 +111,19 @@ WebInspector.ConsoleMessageImpl.prototype = {
                     var args = ["%O", obj];
                     this._messageElement = this._format(args);
                     break;
+                case WebInspector.ConsoleMessage.MessageType.Profile:
+                    var title = WebInspector.ProfilesPanelDescriptor.resolveProfileTitle(this._messageText);
+                    this._messageElement = document.createTextNode(WebInspector.UIString("Profile '%s' started.", title));
+                    break;
+                case WebInspector.ConsoleMessage.MessageType.ProfileEnd:
+                    var hashIndex = this._messageText.lastIndexOf("#");
+                    var title = WebInspector.ProfilesPanelDescriptor.resolveProfileTitle(this._messageText.substring(0, hashIndex));
+                    var uid = this._messageText.substring(hashIndex + 1);
+                    var format = WebInspector.UIString("Profile '%s' finished.", "%_");
+                    var link = WebInspector.linkifyURLAsNode("webkit-profile://CPU/" + uid, title);
+                    this._messageElement = document.createElement("span");
+                    this._formatWithSubstitutionString(format, [link], this._messageElement);
+                    break;
                 default:
                     var args = this._parameters || [this._messageText];
                     this._messageElement = this._format(args);
@@ -247,7 +260,7 @@ WebInspector.ConsoleMessageImpl.prototype = {
         // Multiple parameters with the first being a format string. Save unused substitutions.
         if (shouldFormatMessage) {
             // Multiple parameters with the first being a format string. Save unused substitutions.
-            var result = this._formatWithSubstitutionString(parameters, formattedResult);
+            var result = this._formatWithSubstitutionString(parameters[0].description, parameters.slice(1), formattedResult);
             parameters = result.unusedSubstitutions;
             if (parameters.length)
                 formattedResult.appendChild(document.createTextNode(" "));
@@ -565,7 +578,7 @@ WebInspector.ConsoleMessageImpl.prototype = {
         return this._formatParameter(output, output.subtype && output.subtype === "array", false);
     },
 
-    _formatWithSubstitutionString: function(parameters, formattedResult)
+    _formatWithSubstitutionString: function(format, parameters, formattedResult)
     {
         var formatters = {};
 
@@ -593,6 +606,11 @@ WebInspector.ConsoleMessageImpl.prototype = {
             return Math.floor(obj.value);
         }
 
+        function bypassFormatter(obj)
+        {
+            return (obj instanceof Node) ? obj : "";
+        }
+
         var currentStyle = null;
         function styleFormatter(obj)
         {
@@ -630,6 +648,8 @@ WebInspector.ConsoleMessageImpl.prototype = {
         // Support %O to force object formatting, instead of the type-based %o formatting.
         formatters.O = parameterFormatter.bind(this, true);
 
+        formatters._ = bypassFormatter;
+
         function append(a, b)
         {
             if (b instanceof Node)
@@ -649,7 +669,7 @@ WebInspector.ConsoleMessageImpl.prototype = {
         }
 
         // String.format does treat formattedResult like a Builder, result is an object.
-        return String.format(parameters[0].description, parameters.slice(1), formatters, formattedResult, append);
+        return String.format(format, parameters, formatters, formattedResult, append);
     },
 
     clearHighlight: function()
@@ -820,6 +840,10 @@ WebInspector.ConsoleMessageImpl.prototype = {
             case WebInspector.ConsoleMessage.MessageType.Result:
                 typeString = "Result";
                 break;
+            case WebInspector.ConsoleMessage.MessageType.Profile:
+            case WebInspector.ConsoleMessage.MessageType.ProfileEnd:
+                typeString = "Profiling";
+                break;
         }
 
         var levelString;
index ad44314..7d983d7 100644 (file)
@@ -237,7 +237,9 @@ WebInspector.ConsoleMessage.MessageType = {
     StartGroupCollapsed: "startGroupCollapsed",
     EndGroup: "endGroup",
     Assert: "assert",
-    Result: "result"
+    Result: "result",
+    Profile: "profile",
+    ProfileEnd: "profileEnd"
 }
 
 WebInspector.ConsoleMessage.MessageLevel = {
index 090da46..9ac7511 100644 (file)
@@ -602,7 +602,7 @@ WebInspector.ProfilesPanel.prototype = {
         sidebarParent.appendChild(profileTreeElement);
         if (!profile.isTemporary) {
             if (!this.visibleView)
-                this.showProfile(profile);
+                this._showProfile(profile);
             this.dispatchEventToListeners("profile added", {
                 type: typeId
             });
@@ -650,7 +650,7 @@ WebInspector.ProfilesPanel.prototype = {
     /**
      * @param {WebInspector.ProfileHeader} profile
      */
-    showProfile: function(profile)
+    _showProfile: function(profile)
     {
         if (!profile || profile.isTemporary)
             return;
@@ -704,7 +704,7 @@ WebInspector.ProfilesPanel.prototype = {
             var profile = heapProfiles[i];
             // TODO: allow to choose snapshot if there are several options.
             if (profile.maxJSObjectId >= snapshotObjectId) {
-                this.showProfile(profile);
+                this._showProfile(profile);
                 profile.view().changeView(viewName, function() {
                     profile.view().dataGrid.highlightObjectByHeapSnapshotId(snapshotObjectId);
                 });
@@ -773,7 +773,7 @@ WebInspector.ProfilesPanel.prototype = {
      */
     showView: function(view)
     {
-        this.showProfile(view.profile);
+        this._showProfile(view.profile);
     },
 
     /**
@@ -785,14 +785,12 @@ WebInspector.ProfilesPanel.prototype = {
     },
 
     /**
-     * @param {string} url
+     * @param {string} typeId
+     * @param {string} uid
      */
-    showProfileForURL: function(url)
+    showProfile: function(typeId, uid)
     {
-        var match = url.match(WebInspector.ProfilesPanelDescriptor.ProfileURLRegExp);
-        if (!match)
-            return;
-        this.showProfile(this._profilesIdMap[this._makeKey(Number(match[3]), match[1])]);
+        this._showProfile(this._profilesIdMap[this._makeKey(Number(uid), typeId)]);
     },
 
     closeVisibleView: function()
@@ -803,31 +801,6 @@ WebInspector.ProfilesPanel.prototype = {
     },
 
     /**
-     * @param {string} title
-     * @param {string} typeId
-     */
-    displayTitleForProfileLink: function(title, typeId)
-    {
-        title = unescape(title);
-        if (title.startsWith(UserInitiatedProfileName)) {
-            title = WebInspector.UIString("Profile %d", title.substring(UserInitiatedProfileName.length + 1));
-        } else {
-            var titleKey = this._makeTitleKey(title, typeId);
-            if (!(titleKey in this._profileGroupsForLinks))
-                this._profileGroupsForLinks[titleKey] = 0;
-
-            var groupNumber = ++this._profileGroupsForLinks[titleKey];
-
-            if (groupNumber > 2)
-                // The title is used in the console message announcing that a profile has started so it gets
-                // incremented twice as often as it's displayed
-                title += " " + WebInspector.UIString("Run %d", (groupNumber + 1) / 2);
-        }
-
-        return title;
-    },
-
-    /**
      * @param {string} query
      */
     performSearch: function(query)
@@ -1407,7 +1380,7 @@ WebInspector.ProfileSidebarTreeElement.prototype = {
     onselect: function()
     {
         if (!this._suppressOnSelect)
-            this.treeOutline.panel.showProfile(this.profile);
+            this.treeOutline.panel._showProfile(this.profile);
     },
 
     ondelete: function()
@@ -1483,7 +1456,7 @@ WebInspector.ProfileGroupSidebarTreeElement.prototype = {
     onselect: function()
     {
         if (this.children.length > 0)
-            WebInspector.ProfilesPanel._instance.showProfile(this.children[this.children.length - 1].profile);
+            WebInspector.ProfilesPanel._instance._showProfile(this.children[this.children.length - 1].profile);
     },
 
     __proto__: WebInspector.SidebarTreeElement.prototype
index 24c06e1..d69c677 100644 (file)
@@ -64,3 +64,14 @@ WebInspector.ProfilesPanelDescriptor.userInitiatedProfileIndex = function(title)
     var suffix = title.substring(WebInspector.ProfilesPanelDescriptor.UserInitiatedProfileName.length + 1);
     return parseInt(suffix, 10);
 }
+
+/**
+ * @param {string} title
+ * @return {string}
+ */
+WebInspector.ProfilesPanelDescriptor.resolveProfileTitle = function(title)
+{
+    if (!WebInspector.ProfilesPanelDescriptor.isUserInitiatedProfile(title))
+        return title;
+    return WebInspector.UIString("Profile %d", WebInspector.ProfilesPanelDescriptor.userInitiatedProfileIndex(title));
+}
index dcc7891..362cf56 100644 (file)
@@ -123,16 +123,6 @@ WebInspector.linkifyStringAsFragmentWithCustomLinkifier = function(string, linki
     return container;
 }
 
-WebInspector._linkifierPlugins = [];
-
-/**
- * @param {function(string):string} plugin
- */
-WebInspector.registerLinkifierPlugin = function(plugin)
-{
-    WebInspector._linkifierPlugins.push(plugin);
-}
-
 /**
  * @param {string} string
  * @return {DocumentFragment}
@@ -147,9 +137,6 @@ WebInspector.linkifyStringAsFragment = function(string)
      */
     function linkifier(title, url, lineNumber)
     {
-        for (var i = 0; i < WebInspector._linkifierPlugins.length; ++i)
-            title = WebInspector._linkifierPlugins[i](title);
-
         var isExternal = !WebInspector.resourceForURL(url);
         var urlNode = WebInspector.linkifyURLAsNode(url, title, undefined, isExternal);
         if (typeof(lineNumber) !== "undefined") {
index 0a6991c..85150d5 100644 (file)
@@ -272,16 +272,6 @@ var WebInspector = {
         WebInspector.domAgent.setInspectModeEnabled(enabled, callback.bind(this));
     },
 
-    _profilesLinkifier: function(title)
-    {
-        var profileStringMatches = WebInspector.ProfilesPanelDescriptor.ProfileURLRegExp.exec(title);
-        if (profileStringMatches) {
-            var profilesPanel = /** @ type {WebInspector.ProfilesPanel} */ WebInspector.panel("profiles");
-            title = WebInspector.ProfilesPanel._instance.displayTitleForProfileLink(profileStringMatches[2], profileStringMatches[1]);
-        }
-        return title;
-    },
-
     _debuggerPaused: function()
     {
         // Create scripts panel upon demand.
@@ -468,7 +458,6 @@ WebInspector._doLoadedDoneWithCapabilities = function()
     WebInspector.endBatchUpdate();
 
     this.addMainEventListeners(document);
-    WebInspector.registerLinkifierPlugin(this._profilesLinkifier.bind(this));
 
     window.addEventListener("resize", this.windowResize.bind(this), true);
 
@@ -583,7 +572,7 @@ WebInspector.close = function(event)
 WebInspector.documentClick = function(event)
 {
     var anchor = event.target.enclosingNodeOrSelfWithNodeName("a");
-    if (!anchor || (anchor.target === "_blank" && !WebInspector.ProfilesPanelDescriptor.ProfileURLRegExp.exec(anchor.href)))
+    if (!anchor || (anchor.target === "_blank"))
         return;
 
     // Prevent the link from navigating, since we don't do any navigation by following links normally.
@@ -596,7 +585,7 @@ WebInspector.documentClick = function(event)
 
         const profileMatch = WebInspector.ProfilesPanelDescriptor.ProfileURLRegExp.exec(anchor.href);
         if (profileMatch) {
-            WebInspector.showProfileForURL(anchor.href);
+            WebInspector.showPanel("profiles").showProfile(profileMatch[1], profileMatch[2]);
             return;
         }
 
@@ -984,11 +973,6 @@ WebInspector._showAnchorLocationInPanel = function(anchor, panel)
     return true;
 }
 
-WebInspector.showProfileForURL = function(url)
-{
-    WebInspector.showPanel("profiles").showProfileForURL(url);
-}
-
 WebInspector.evaluateInConsole = function(expression, showResultOnly)
 {
     this.showConsole();