2010-09-16 Andrey Kosyakov <caseq@chromium.org>
authorcaseq@chromium.org <caseq@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 Sep 2010 13:56:43 +0000 (13:56 +0000)
committercaseq@chromium.org <caseq@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 Sep 2010 13:56:43 +0000 (13:56 +0000)
        Reviewed by Pavel Feldman.

        Web Inspector: [Resources panel] [HAR] Need a way to save timing data.
        Added support to export HAR to file from Resources panel (conditional on Preferences)
        Added support for HARLog (a higher-level aggregate than HAREntry)
        https://bugs.webkit.org/show_bug.cgi?id=45663

        * English.lproj/localizedStrings.js:
        * inspector/front-end/HAREntry.js:
        (WebInspector.HAREntry.prototype.build):
        (WebInspector.HAREntry.prototype._buildTimings):
        (WebInspector.HAREntry._toMilliseconds):
        (WebInspector.HARLog):
        (WebInspector.HARLog.prototype.build):
        (WebInspector.HARLog.prototype._buildPages):
        (WebInspector.HARLog.prototype._buildMainResourceTimings):
        (WebInspector.HARLog.prototype._convertResource):
        * inspector/front-end/ResourcesPanel.js:
        (WebInspector.ResourcesPanel):
        (WebInspector.ResourcesPanel.prototype.hide):
        (WebInspector.ResourcesPanel.prototype._contextMenu):
        (WebInspector.ResourcesPanel.prototype._exportAll):
        (WebInspector.ResourcesPanel.prototype._exportResource):
        * inspector/front-end/Settings.js:
        * inspector/front-end/utilities.js:

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

WebCore/ChangeLog
WebCore/English.lproj/localizedStrings.js
WebCore/inspector/front-end/HAREntry.js
WebCore/inspector/front-end/ResourcesPanel.js
WebCore/inspector/front-end/Settings.js
WebCore/inspector/front-end/utilities.js

index d34cbac..c76f33a 100644 (file)
@@ -1,3 +1,32 @@
+2010-09-16  Andrey Kosyakov  <caseq@chromium.org>
+
+        Reviewed by Pavel Feldman.
+
+        Web Inspector: [Resources panel] [HAR] Need a way to save timing data.
+        Added support to export HAR to file from Resources panel (conditional on Preferences)
+        Added support for HARLog (a higher-level aggregate than HAREntry)
+        https://bugs.webkit.org/show_bug.cgi?id=45663
+
+        * English.lproj/localizedStrings.js:
+        * inspector/front-end/HAREntry.js:
+        (WebInspector.HAREntry.prototype.build):
+        (WebInspector.HAREntry.prototype._buildTimings):
+        (WebInspector.HAREntry._toMilliseconds):
+        (WebInspector.HARLog):
+        (WebInspector.HARLog.prototype.build):
+        (WebInspector.HARLog.prototype._buildPages):
+        (WebInspector.HARLog.prototype._buildMainResourceTimings):
+        (WebInspector.HARLog.prototype._convertResource):
+        * inspector/front-end/ResourcesPanel.js:
+        (WebInspector.ResourcesPanel):
+        (WebInspector.ResourcesPanel.prototype.hide):
+        (WebInspector.ResourcesPanel.prototype._contextMenu):
+        (WebInspector.ResourcesPanel.prototype._exportAll):
+        (WebInspector.ResourcesPanel.prototype._exportResource):
+        * inspector/front-end/Settings.js:
+        * inspector/front-end/utilities.js:
+        ():
+
 2010-09-16  Eric Uhrhane  <ericu@chromium.org>
 
         Reviewed by Jian Li.
index 38dba9b..eedf225 100644 (file)
Binary files a/WebCore/English.lproj/localizedStrings.js and b/WebCore/English.lproj/localizedStrings.js differ
index f7a5f58..85e4f59 100644 (file)
@@ -42,7 +42,7 @@ WebInspector.HAREntry.prototype = {
         return {
             pageref: this._resource.documentURL,
             startedDateTime: new Date(this._resource.startTime * 1000),
-            time: this._toMilliseconds(this._resource.duration),
+            time: WebInspector.HAREntry._toMilliseconds(this._resource.duration),
             request: this._buildRequest(),
             response: this._buildResponse(),
             // cache: {...}, -- Not supproted yet.
@@ -121,7 +121,7 @@ WebInspector.HAREntry.prototype = {
             connect: connect,
             send: send,
             wait: this._interval("sendEnd", "receiveHeadersEnd"),
-            receive: this._toMilliseconds(this._resource.receiveDuration),
+            receive: WebInspector.HAREntry._toMilliseconds(this._resource.receiveDuration),
             ssl: ssl
         };
     },
@@ -150,11 +150,6 @@ WebInspector.HAREntry.prototype = {
         return parameters.slice();
     },
 
-    _toMilliseconds: function(time)
-    {
-        return time === -1 ? -1 : Math.round(time * 1000);
-    },
-
     _interval: function(start, end)
     {
         var timing = this._resource.timing;
@@ -164,3 +159,56 @@ WebInspector.HAREntry.prototype = {
         return typeof startTime !== "number" || startTime === -1 ? -1 : Math.round(timing[end] - startTime);
     }
 };
+
+WebInspector.HAREntry._toMilliseconds = function(time)
+{
+    return time === -1 ? -1 : Math.round(time * 1000);
+}
+
+WebInspector.HARLog = function()
+{
+}
+
+WebInspector.HARLog.prototype = {
+    build: function()
+    {
+        var webKitVersion = /AppleWebKit\/([^ ]+)/.exec(window.navigator.userAgent);
+        
+        return {
+            version: "1.2",
+            creator: {
+                name: "WebInspector",
+                version: webKitVersion ? webKitVersion[1] : "n/a"
+            },
+            pages: this._buildPages(),
+            entries: Object.properties(WebInspector.resources).map(this._convertResource)
+        }
+    },
+
+    _buildPages: function()
+    {
+        return [
+            {
+                startedDateTime: new Date(WebInspector.mainResource.startTime * 1000),
+                id: WebInspector.mainResource.documentURL,
+                title: "",
+                pageTimings: this._buildMainResourceTimings()
+            }
+        ];
+    },
+
+    _buildMainResourceTimings: function()
+    {
+        var resourcesPanel = WebInspector.panels.resources;
+        var startTime = WebInspector.mainResource.startTime;
+        return {
+             onContentLoad: WebInspector.HAREntry._toMilliseconds(resourcesPanel.mainResourceDOMContentTime - startTime),
+             onLoad: WebInspector.HAREntry._toMilliseconds(resourcesPanel.mainResourceLoadTime - startTime),
+        }
+    },
+
+    _convertResource: function(id)
+    {
+        return (new WebInspector.HAREntry(WebInspector.resources[id])).build();
+    }
+};
index 27df5cf..afcc3e9 100644 (file)
@@ -47,6 +47,8 @@ WebInspector.ResourcesPanel = function()
     this.filter(this.filterAllElement, false);
     this.graphsTreeElement.children[0].select();
     this._resourceTrackingEnabled = false;
+
+    this.sidebarElement.addEventListener("contextmenu", this._contextMenu.bind(this), true);
 }
 
 WebInspector.ResourcesPanel.prototype = {
@@ -876,6 +878,36 @@ WebInspector.ResourcesPanel.prototype = {
     {
         WebInspector.Panel.prototype.hide.call(this);
         this._popoverHelper.hidePopup();
+    },
+
+    _contextMenu: function(event)
+    {
+        // createBlobURL is enabled conditionally, do not expose resource export if it's not available.
+        if (typeof window.createBlobURL !== "function" || !Preferences.resourceExportEnabled)
+            return;
+
+        var contextMenu = new WebInspector.ContextMenu();
+        var resourceTreeItem = event.target.enclosingNodeOrSelfWithClass("resource-sidebar-tree-item");
+        if (resourceTreeItem && resourceTreeItem.treeElement) {
+            var resource = resourceTreeItem.treeElement.representedObject;
+            contextMenu.appendItem(WebInspector.UIString("Export to HAR"), this._exportResource.bind(this, resource));
+        }
+        contextMenu.appendItem(WebInspector.UIString("Export all to HAR"), this._exportAll.bind(this));
+        contextMenu.show(event);
+    },
+
+    _exportAll: function()
+    {
+        var harArchive = {
+            log: (new WebInspector.HARLog()).build()
+        }
+        offerFileForDownload(JSON.stringify(harArchive));
+    },
+
+    _exportResource: function(resource)
+    {
+        var har = (new WebInspector.HAREntry(resource)).build();
+        offerFileForDownload(JSON.stringify(har));
     }
 }
 
index 1261cfd..05fd25e 100644 (file)
@@ -44,7 +44,8 @@ var Preferences = {
     profilerAlwaysEnabled: false,
     auditsPanelEnabled: true,
     onlineDetectionEnabled: true,
-    domBreakpointsEnabled: false
+    domBreakpointsEnabled: false,
+    resourceExportEnabled: false
 }
 
 WebInspector.Settings = function(sessionScope)
index e8adff6..5e41da6 100644 (file)
@@ -984,3 +984,12 @@ function createSearchRegex(query)
     }
     return new RegExp(regex, "i");
 }
+
+function offerFileForDownload(contents)
+{
+    var builder = new BlobBuilder();
+    builder.append(contents);
+    var blob = builder.getBlob("application/octet-stream");
+    var url = window.createBlobURL(blob);
+    window.open(url);
+}