Title: [224851] trunk/Source/WebInspectorUI
Revision
224851
Author
commit-qu...@webkit.org
Date
2017-11-14 15:22:45 -0800 (Tue, 14 Nov 2017)

Log Message

Web Inspector: Network Detail Views - Split Metrics into Sizes and Timing
https://bugs.webkit.org/show_bug.cgi?id=179569
<rdar://problem/35484914>

Patch by Joseph Pecoraro <pecor...@apple.com> on 2017-11-14
Reviewed by Brian Burg.

* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Main.html:
New resources and strings.

* UserInterface/Views/NetworkResourceDetailView.js:
(WI.NetworkResourceDetailView):
(WI.NetworkResourceDetailView.prototype.initialLayout):
(WI.NetworkResourceDetailView.prototype._showPreferredContentView):
(WI.NetworkResourceDetailView.prototype._showContentViewForNavigationItem):
(WI.NetworkResourceDetailView.prototype.sizesContentViewGoToHeaders): Renamed.
(WI.NetworkResourceDetailView.prototype.sizesContentViewGoToRequestBody): Renamed.
(WI.NetworkResourceDetailView.prototype.sizesContentViewGoToResponseBody): Renamed.
Split into two navigation items and views.

* UserInterface/Views/ResourceMetricsContentView.css: Removed.
* UserInterface/Views/ResourceMetricsContentView.js: Removed.
* UserInterface/Views/ResourceSizesContentView.css: Added.
* UserInterface/Views/ResourceSizesContentView.js: Added.
* UserInterface/Views/ResourceTimingContentView.css: Added.
* UserInterface/Views/ResourceTimingContentView.js: Added.
Split Metrics into two views.

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WebInspectorUI/ChangeLog (224850 => 224851)


--- trunk/Source/WebInspectorUI/ChangeLog	2017-11-14 22:59:42 UTC (rev 224850)
+++ trunk/Source/WebInspectorUI/ChangeLog	2017-11-14 23:22:45 UTC (rev 224851)
@@ -1,3 +1,33 @@
+2017-11-14  Joseph Pecoraro  <pecor...@apple.com>
+
+        Web Inspector: Network Detail Views - Split Metrics into Sizes and Timing
+        https://bugs.webkit.org/show_bug.cgi?id=179569
+        <rdar://problem/35484914>
+
+        Reviewed by Brian Burg.
+
+        * Localizations/en.lproj/localizedStrings.js:
+        * UserInterface/Main.html:
+        New resources and strings.
+
+        * UserInterface/Views/NetworkResourceDetailView.js:
+        (WI.NetworkResourceDetailView):
+        (WI.NetworkResourceDetailView.prototype.initialLayout):
+        (WI.NetworkResourceDetailView.prototype._showPreferredContentView):
+        (WI.NetworkResourceDetailView.prototype._showContentViewForNavigationItem):
+        (WI.NetworkResourceDetailView.prototype.sizesContentViewGoToHeaders): Renamed.
+        (WI.NetworkResourceDetailView.prototype.sizesContentViewGoToRequestBody): Renamed.
+        (WI.NetworkResourceDetailView.prototype.sizesContentViewGoToResponseBody): Renamed.
+        Split into two navigation items and views.
+
+        * UserInterface/Views/ResourceMetricsContentView.css: Removed.
+        * UserInterface/Views/ResourceMetricsContentView.js: Removed.
+        * UserInterface/Views/ResourceSizesContentView.css: Added.
+        * UserInterface/Views/ResourceSizesContentView.js: Added.
+        * UserInterface/Views/ResourceTimingContentView.css: Added.
+        * UserInterface/Views/ResourceTimingContentView.js: Added.
+        Split Metrics into two views.
+
 2017-11-14  Matt Baker  <mattba...@apple.com>
 
         Web Inspector: Cleanup navigation bar dividers and separators

Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (224850 => 224851)


--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2017-11-14 22:59:42 UTC (rev 224850)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2017-11-14 23:22:45 UTC (rev 224851)
@@ -590,7 +590,6 @@
 localizedStrings["Memory: %s"] = "Memory: %s";
 localizedStrings["Message"] = "Message";
 localizedStrings["Method"] = "Method";
-localizedStrings["Metrics"] = "Metrics";
 localizedStrings["Microtask Dispatched"] = "Microtask Dispatched";
 localizedStrings["Min"] = "Min";
 localizedStrings["Missing Dependencies:%s"] = "Missing Dependencies:%s";
@@ -869,6 +868,7 @@
 localizedStrings["Shrink"] = "Shrink";
 localizedStrings["Size"] = "Size";
 localizedStrings["Size of current object plus all objects it keeps alive"] = "Size of current object plus all objects it keeps alive";
+localizedStrings["Sizes"] = "Sizes";
 localizedStrings["Sizing"] = "Sizing";
 localizedStrings["Slice"] = "Slice";
 localizedStrings["Snapshot %d"] = "Snapshot %d";

Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (224850 => 224851)


--- trunk/Source/WebInspectorUI/UserInterface/Main.html	2017-11-14 22:59:42 UTC (rev 224850)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html	2017-11-14 23:22:45 UTC (rev 224851)
@@ -148,11 +148,12 @@
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
-    <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
+    <link rel="stylesheet" href=""
+    <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
@@ -692,13 +693,14 @@
     <script src=""
     <script src=""
     <script src=""
-    <script src=""
     <script src=""
     <script src=""
     <script src=""
     <script src=""
+    <script src=""
     <script src=""
     <script src=""
+    <script src=""
     <script src=""
     <script src=""
     <script src=""

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkResourceDetailView.js (224850 => 224851)


--- trunk/Source/WebInspectorUI/UserInterface/Views/NetworkResourceDetailView.js	2017-11-14 22:59:42 UTC (rev 224850)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NetworkResourceDetailView.js	2017-11-14 23:22:45 UTC (rev 224851)
@@ -40,7 +40,8 @@
         this._resourceContentView = null;
         this._headersContentView = null;
         this._cookiesContentView = null;
-        this._metricsContentView = null;
+        this._sizesContentView = null;
+        this._timingContentView = null;
     }
 
     // Public
@@ -77,14 +78,14 @@
         this._resourceContentView.showRequest();
     }
 
-    // ResourceMetricsContentView delegate
+    // ResourceSizesContentView delegate
 
-    metricsContentViewGoToHeaders(metricsContentView)
+    sizesContentViewGoToHeaders(metricsContentView)
     {
         this._contentBrowser.navigationBar.selectedNavigationItem = this._headersNavigationItem;
     }
 
-    metricsContentViewGoToRequestBody(metricsContentView)
+    sizesContentViewGoToRequestBody(metricsContentView)
     {
         this._contentBrowser.navigationBar.selectedNavigationItem = this._previewNavigationItem;
 
@@ -91,7 +92,7 @@
         this._resourceContentView.showRequest();
     }
 
-    metricsContentViewGoToResponseBody(metricsContentView)
+    sizesContentViewGoToResponseBody(metricsContentView)
     {
         this._contentBrowser.navigationBar.selectedNavigationItem = this._previewNavigationItem;
 
@@ -117,7 +118,8 @@
         this._previewNavigationItem = new WI.RadioButtonNavigationItem("preview", WI.UIString("Preview"));
         this._headersNavigationItem = new WI.RadioButtonNavigationItem("headers", WI.UIString("Headers"));
         this._cookiesNavigationItem = new WI.RadioButtonNavigationItem("cookies", WI.UIString("Cookies"));
-        this._metricsNavigationItem = new WI.RadioButtonNavigationItem("metrics", WI.UIString("Metrics"));
+        this._sizesNavigationItem = new WI.RadioButtonNavigationItem("sizes", WI.UIString("Sizes"));
+        this._timingNavigationItem = new WI.RadioButtonNavigationItem("timing", WI.UIString("Timing"));
 
         // Insert all of our custom navigation items at the start of the ContentBrowser's NavigationBar.
         let index = 0;
@@ -126,7 +128,8 @@
         this._contentBrowser.navigationBar.insertNavigationItem(this._previewNavigationItem, index++);
         this._contentBrowser.navigationBar.insertNavigationItem(this._headersNavigationItem, index++);
         this._contentBrowser.navigationBar.insertNavigationItem(this._cookiesNavigationItem, index++);
-        this._contentBrowser.navigationBar.insertNavigationItem(this._metricsNavigationItem, index++);
+        this._contentBrowser.navigationBar.insertNavigationItem(this._sizesNavigationItem, index++);
+        this._contentBrowser.navigationBar.insertNavigationItem(this._timingNavigationItem, index++);
         this._contentBrowser.navigationBar.addEventListener(WI.NavigationBar.Event.NavigationItemSelected, this._navigationItemSelected, this);
 
         this.addSubview(this._contentBrowser);
@@ -148,7 +151,8 @@
             if (navigationItem !== this._previewNavigationItem
                 && navigationItem !== this._headersNavigationItem
                 && navigationItem !== this._cookiesNavigationItem
-                && navigationItem !== this._metricsNavigationItem)
+                && navigationItem !== this._sizesNavigationItem
+                && navigationItem !== this._timingNavigationItem)
                 continue;
 
             if (!firstNavigationItem)
@@ -182,11 +186,16 @@
                 this._cookiesContentView = new WI.ResourceCookiesContentView(this._resource);
             this._contentBrowser.showContentView(this._cookiesContentView);
             break;
-        case "metrics":
-            if (!this._metricsContentView)
-                this._metricsContentView = new WI.ResourceMetricsContentView(this._resource, this);
-            this._contentBrowser.showContentView(this._metricsContentView);
+        case "sizes":
+            if (!this._sizesContentView)
+                this._sizesContentView = new WI.ResourceSizesContentView(this._resource, this);
+            this._contentBrowser.showContentView(this._sizesContentView);
             break;
+        case "timing":
+            if (!this._timingContentView)
+                this._timingContentView = new WI.ResourceTimingContentView(this._resource);
+            this._contentBrowser.showContentView(this._timingContentView);
+            break;
         }
     }
 

Deleted: trunk/Source/WebInspectorUI/UserInterface/Views/ResourceMetricsContentView.css (224850 => 224851)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ResourceMetricsContentView.css	2017-11-14 22:59:42 UTC (rev 224850)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ResourceMetricsContentView.css	2017-11-14 23:22:45 UTC (rev 224851)
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-.resource-metrics {
-    font-family: '-webkit-system-font';
-}
-
-.resource-metrics > .content {
-    width: 550px;
-    margin: 0 auto;
-}
-
-.resource-metrics > .content .label {
-    color: gray;
-}
-
-.resource-metrics > .content > section {
-    position: relative;
-    padding: 10px 0;
-}
-
-.resource-metrics > .content > section .subtitle {
-    margin-bottom: 10px;
-    font-size: 14px;
-    text-align: center;
-    letter-spacing: 0.04em;
-}
-
-.resource-metrics > .content > section:not(:last-of-type) {
-    border-bottom: 1px solid var(--border-color);
-}
-
-.resource-metrics > .content > section.split {
-    display: flex;
-    justify-content: center;
-}
-
-.resource-metrics > .content > section.split > .subsection {
-    width: 160px;
-    margin: 10px 0px;
-}
-
-.resource-metrics > .content > section.split > .subsection.large .icon {
-    width: 32px;
-    height: 32px;
-}
-
-.resource-metrics > .content > section.split > .subsection > table {
-    margin: 0 auto;
-}
-
-.resource-metrics > .content > section.split > .divider {
-    margin: 0 10px;
-    border-right: 1px solid var(--border-color);
-}
-
-.resource-metrics > .content > section.network > .subsection > .container {
-    display: flex;
-    justify-content: center;
-    margin-bottom: 8px;
-}
-
-.resource-metrics > .content > section.network .bytes-group {
-    text-align: start;
-}
-
-.resource-metrics > .content > section.network .bytes {
-    margin-top: 2px;
-    font-size: 28px;
-    display: inline-block;
-}
-
-.resource-metrics > .content > section.network table > tr > td.label {
-    text-align: end;
-}
-
-.resource-metrics > .content > section.network .suffix {
-    display: inline-block;
-    margin: 13px 1px 0 1px;
-    font-size: 15px;
-}
-
-.resource-metrics > .content > section.network img {
-    width: 32px;
-    height: 32px;
-    margin: 3px;
-}
-
-.resource-metrics > .content > section.network .go-to-arrow {
-    bottom: -1px;
-    height: 12px;
-    vertical-align: top;
-}
-
-.resource-metrics > .content > section.network .warning {
-    display: inline-block;
-    width: 10px;
-    height: 10px;
-    -webkit-margin-start: 3px;
-}
-
-.resource-metrics > .content > section.timing {
-    padding: 20px 0;
-}
-
-.resource-metrics > .content > section.timing .subtitle {
-    letter-spacing: 0.06em;
-}
-
-.resource-metrics > .content > section.timing > ul {
-    margin: 0;
-    padding: 0;
-    list-style-type: none;
-}
-
-.resource-metrics > .content > section.timing > ul > li {
-    position: relative;
-    height: 20px;
-    padding: 1px 0;
-    line-height: 18px;
-}
-
-.resource-metrics > .content > section.timing > .waterfall {
-    width: 500px;
-    margin: auto;
-}
-
-.resource-metrics > .content > section.timing > .waterfall .block {
-    top: 4px;
-    min-width: 1px;
-    height: 12px;
-}
-
-.resource-metrics > .content > section.timing > ul > li > .row-label {
-    display: inline-block;
-    min-width: 70px;
-    color: black;
-}
-
-.resource-metrics > .content > section.timing > ul > li > .row-label {
-    text-align: end;
-}
-
-.resource-metrics > .content > section.timing > ul > li > .time-label {
-    position: absolute;
-    top: 1px;
-    color: gray;
-}
-
-.resource-metrics > .content > section.timing > ul > li.total .block {
-    display: none;
-}
-
-.resource-metrics > .content > section.timing > ul > li.total .time-label {
-    color: black;
-}
-
-.resource-metrics > .content > section.timing .indeterminate-progress-spinner {
-    margin: 0 auto;
-}
-
-.resource-metrics > .content > section.timing .empty {
-    text-align: center;
-    color: gray;
-}

Deleted: trunk/Source/WebInspectorUI/UserInterface/Views/ResourceMetricsContentView.js (224850 => 224851)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ResourceMetricsContentView.js	2017-11-14 22:59:42 UTC (rev 224850)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ResourceMetricsContentView.js	2017-11-14 23:22:45 UTC (rev 224851)
@@ -1,379 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-WI.ResourceMetricsContentView = class ResourceMetricsContentView extends WI.ContentView
-{
-    constructor(resource, delegate)
-    {
-        super(null);
-
-        console.assert(resource instanceof WI.Resource);
-        console.assert(delegate);
-
-        this._resource = resource;
-        this._resource.addEventListener(WI.Resource.Event.SizeDidChange, this._resourceSizeDidChange, this);
-        this._resource.addEventListener(WI.Resource.Event.TransferSizeDidChange, this._resourceTransferSizeDidChange, this);
-        this._resource.addEventListener(WI.Resource.Event.MetricsDidChange, this._resourceMetricsDidChange, this);
-        this._resource.addEventListener(WI.Resource.Event.TimestampsDidChange, this._resourceTimestampsDidChange, this);
-
-        this._delegate = delegate;
-
-        this.element.classList.add("resource-details", "resource-metrics");
-
-        this._needsTransferSizesRefresh = false;
-        this._needsResourceSizeRefresh = false;
-        this._needsTimingRefresh = false;
-    }
-
-    // Protected
-
-    initialLayout()
-    {
-        super.initialLayout();
-
-        let contentElement = this.element.appendChild(document.createElement("div"));
-        contentElement.className = "content";
-
-        // Network.
-
-        let networkSection = contentElement.appendChild(document.createElement("section"));
-        networkSection.className = "network split";
-
-        function createSizeComponents(parentElement, subtitle, imageSource, label1, label2) {
-            let subtitleElement = parentElement.appendChild(document.createElement("div"));
-            subtitleElement.className = "subtitle";
-            subtitleElement.textContent = subtitle;
-
-            let container = parentElement.appendChild(document.createElement("div"));
-            container.className = "container";
-
-            let imageElement = container.appendChild(document.createElement("img"));
-            if (imageSource)
-                imageElement.src = ""
-
-            let groupElement = container.appendChild(document.createElement("div"));
-            groupElement.className = "bytes-group";
-
-            let bytesElement = groupElement.appendChild(document.createElement("div"));
-            bytesElement.className = "bytes";
-
-            let suffixElement = groupElement.appendChild(document.createElement("div"));
-            suffixElement.className = "suffix";
-
-            let table = parentElement.appendChild(document.createElement("table"));
-            let headerRow = table.appendChild(document.createElement("tr"));
-            let label1Element = headerRow.appendChild(document.createElement("td"));
-            let value1Element = headerRow.appendChild(document.createElement("td"));
-            let bodyRow = table.appendChild(document.createElement("tr"));
-            let label2Element = bodyRow.appendChild(document.createElement("td"));
-            let value2Element = bodyRow.appendChild(document.createElement("td"));
-
-            label1Element.textContent = label1;
-            label1Element.className = "label";
-            label2Element.textContent = label2;
-            label2Element.className = "label";
-
-            return {
-                container,
-                bytesElement,
-                suffixElement,
-                imageElement,
-                value1Element,
-                value2Element,
-            };
-        }
-
-        let sendingSection = networkSection.appendChild(document.createElement("div"));
-        sendingSection.className = "subsection";
-
-        let sendingComponents = createSizeComponents(sendingSection, WI.UIString("Bytes Sent"), "Images/Sending.svg", WI.UIString("Headers:"), WI.UIString("Body:"));
-        this._sendingBytesElement = sendingComponents.bytesElement;
-        this._sendingBytesSuffixElement = sendingComponents.suffixElement;
-        this._sendingHeaderBytesElement = sendingComponents.value1Element;
-        this._sendingBodyBytesElement = sendingComponents.value2Element;
-
-        let bytesDivider = networkSection.appendChild(document.createElement("div"));
-        bytesDivider.className = "divider";
-
-        let receivingSection = networkSection.appendChild(document.createElement("div"));
-        receivingSection.className = "subsection";
-
-        let receivingComponents = createSizeComponents(receivingSection, WI.UIString("Bytes Received"), "Images/Receiving.svg", WI.UIString("Headers:"), WI.UIString("Body:"));
-        this._receivingBytesElement = receivingComponents.bytesElement;
-        this._receivingBytesSuffixElement = receivingComponents.suffixElement;
-        this._receivingHeaderBytesElement = receivingComponents.value1Element;
-        this._receivingBodyBytesElement = receivingComponents.value2Element;
-
-        let resourceDivider = networkSection.appendChild(document.createElement("div"));
-        resourceDivider.className = "divider";
-
-        let resourceSection = networkSection.appendChild(document.createElement("div"));
-        resourceSection.className = "subsection large";
-
-        let resourceComponents = createSizeComponents(resourceSection, WI.UIString("Resource Size"), null, WI.UIString("Compression:"), WI.UIString("MIME Type:"));
-        resourceComponents.container.classList.add(WI.ResourceTreeElement.ResourceIconStyleClassName, this._resource.type);
-        resourceComponents.imageElement.classList.add("icon");
-        this._resourceBytesElement = resourceComponents.bytesElement;
-        this._resourceBytesSuffixElement = resourceComponents.suffixElement;
-        this._compressionElement = resourceComponents.value1Element;
-        this._contentTypeElement = resourceComponents.value2Element;
-
-        // Timing.
-
-        this._timingSection = contentElement.appendChild(document.createElement("section"));
-        this._timingSection.className = "timing";
-
-        this._timingSubtitle = document.createElement("div");
-        this._timingSubtitle.className = "subtitle";
-        this._timingSubtitle.textContent = WI.UIString("Timing");
-
-        // Populate.
-
-        this._refreshTransferSizeSections();
-        this._refreshResourceSizeSection();
-        this._refreshTimingSection();
-
-        this._needsTransferSizesRefresh = false;
-        this._needsResourceSizeRefresh = false;
-        this._needsTimingRefresh = false;
-    }
-
-    layout()
-    {
-        super.layout();
-
-        if (this._needsTransferSizesRefresh) {
-            this._refreshTransferSizeSections();
-            this._needsTransferSizesRefresh = false;
-        }
-
-        if (this._needsResourceSizeRefresh) {
-            this._refreshResourceSizeSection();
-            this._needsResourceSizeRefresh = false;
-        }
-
-        if (this._needsTimingRefresh) {
-            this._refreshTimingSection();
-            this._needsTimingRefresh = false;
-        }
-    }
-
-    closed()
-    {
-        this._resource.removeEventListener(null, null, this);
-
-        super.closed();
-    }
-
-    // Private
-
-    _sizeComponents(bytes)
-    {
-        console.assert(bytes >= 0);
-
-        // Prefer KB over B. And prefer 1 decimal point to keep sizes simple
-        // but we will still need B if bytes is less than 0.1 KB.
-        if (bytes < 103)
-            return [bytes.toFixed(0), "B"];
-
-        let kilobytes = bytes / 1024;
-        if (kilobytes < 1024)
-            return [kilobytes.toFixed(1), "KB"];
-
-        let megabytes = kilobytes / 1024;
-        if (megabytes < 1024)
-            return [megabytes.toFixed(1), "MB"];
-
-        let gigabytes = megabytes / 1024;
-        return [gigabytes.toFixed(1), "GB"];
-    }
-
-    _refreshTransferSizeSections()
-    {
-        let bytesSentHeader = this._resource.requestHeadersTransferSize;
-        let bytesSentBody = this._resource.requestBodyTransferSize;
-        let bytesSent = bytesSentHeader + bytesSentBody;
-
-        let bytesReceivedHeader = this._resource.responseHeadersTransferSize;
-        let bytesReceivedBody = this._resource.responseBodyTransferSize;
-        let bytesReceived = bytesReceivedHeader + bytesReceivedBody;
-
-        let [sentValue, sentSuffix] = this._sizeComponents(bytesSent || 0);
-        this._sendingBytesElement.textContent = sentValue;
-        this._sendingBytesSuffixElement.textContent = sentSuffix;
-
-        this._sendingHeaderBytesElement.textContent = bytesSentHeader ? Number.bytesToString(bytesSentHeader) : emDash;
-        this._sendingBodyBytesElement.textContent = bytesSentBody ? Number.bytesToString(bytesSentBody) : emDash;
-
-        let [receivedValue, receivedSuffix] = this._sizeComponents(bytesReceived || 0);
-        this._receivingBytesElement.textContent = receivedValue;
-        this._receivingBytesSuffixElement.textContent = receivedSuffix;
-
-        this._receivingHeaderBytesElement.textContent = bytesReceivedHeader ? Number.bytesToString(bytesReceivedHeader) : emDash;
-        this._receivingBodyBytesElement.textContent = bytesReceivedBody ? Number.bytesToString(bytesReceivedBody) : emDash;
-
-        function appendGoToArrow(parentElement, handler) {
-            let goToButton = parentElement.appendChild(WI.createGoToArrowButton());
-            goToButton.addEventListener("click", handler);
-        }
-
-        if (bytesSentHeader)
-            appendGoToArrow(this._sendingHeaderBytesElement, () => { this._delegate.metricsContentViewGoToHeaders(this); });
-        if (bytesSentBody)
-            appendGoToArrow(this._sendingBodyBytesElement, () => { this._delegate.metricsContentViewGoToRequestBody(this); });
-        if (bytesReceivedHeader)
-            appendGoToArrow(this._receivingHeaderBytesElement, () => { this._delegate.metricsContentViewGoToHeaders(this); });
-        if (bytesReceivedBody)
-            appendGoToArrow(this._receivingBodyBytesElement, () => { this._delegate.metricsContentViewGoToResponseBody(this); });
-    }
-
-    _refreshResourceSizeSection()
-    {
-        let encodedSize = !isNaN(this._resource.networkEncodedSize) ? this._resource.networkEncodedSize : this._resource.estimatedNetworkEncodedSize;
-        let decodedSize = !isNaN(this._resource.networkDecodedSize) ? this._resource.networkDecodedSize : this._resource.size;
-        let compressionRate = decodedSize / encodedSize;
-        let compressionString = compressionRate > 0 && isFinite(compressionRate) ? WI.UIString("%.2f\u00d7").format(compressionRate) : WI.UIString("None");
-
-        let [resourceSizeValue, resourceSizeSuffix] = this._sizeComponents(decodedSize || 0);
-        this._resourceBytesElement.textContent = resourceSizeValue;
-        this._resourceBytesSuffixElement.textContent = resourceSizeSuffix;
-
-        let contentEncoding = this._resource.responseHeaders.valueForCaseInsensitiveKey("Content-Encoding");
-        if (contentEncoding)
-            compressionString += ` (${contentEncoding.toLowerCase()})`;
-
-        this._compressionElement.textContent = compressionString;
-        this._contentTypeElement.textContent = this._resource.mimeType || emDash;
-
-        const minimumSizeBeforeWarning = 1024;
-        if (compressionRate <= 1 && encodedSize >= minimumSizeBeforeWarning && WI.shouldTreatMIMETypeAsText(this._resource.mimeType))
-            this._compressionElement.appendChild(WI.ImageUtilities.useSVGSymbol("Images/Warning.svg", "warning", WI.UIString("This text resource could benefit from compression")));
-    }
-
-    _refreshTimingSection()
-    {
-        this._timingSection.removeChildren();
-
-        this._timingSection.appendChild(this._timingSubtitle);
-
-        if (!this._resource.hasResponse()) {
-            let spinner = new WI.IndeterminateProgressSpinner;
-            this._timingSection.appendChild(spinner.element);
-            return;
-        }
-
-        if (!this._resource.timingData.startTime || !this._resource.timingData.responseEnd) {
-            let p = this._timingSection.appendChild(document.createElement("p"));
-            p.className = "empty";
-            p.textContent = WI.UIString("Resource does not have timing data");
-            return;
-        }
-
-        // FIXME: Converge on using WI.ResourceTimingBreakdownView when a design is finalized.
-
-        let listElement = this._timingSection.appendChild(document.createElement("ul"));
-        listElement.className = "waterfall"; // Include waterfall block styles.
-
-        const graphWidth = 380;
-        const graphStartOffset = 80;
-
-        let {startTime, domainLookupStart, domainLookupEnd, connectStart, connectEnd, secureConnectionStart, requestStart, responseStart, responseEnd} = this._resource.timingData;
-        let graphStartTime = startTime;
-        let graphEndTime = responseEnd;
-        let secondsPerPixel = (responseEnd - startTime) / graphWidth;
-
-        function createBlock(startTime, endTime, className, makeEmpty) {
-            let startOffset = graphStartOffset + ((startTime - graphStartTime) / secondsPerPixel);
-            let width = makeEmpty ? 1 : (endTime - startTime) / secondsPerPixel;
-            let block = document.createElement("div");
-            block.classList.add("block", className);
-            let property = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? "right" : "left";
-            block.style[property] = startOffset + "px";
-            block.style.width = width + "px";
-            return block;
-        }
-
-        function createTimeLabel(endTime, label) {
-            let positionOffset = graphStartOffset + ((endTime - graphStartTime) / secondsPerPixel);
-            positionOffset += 3;
-            let timeLabel = document.createElement("div");
-            timeLabel.className = "time-label";
-            timeLabel.textContent = label;
-            let property = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? "right" : "left";
-            timeLabel.style[property] = positionOffset + "px";
-            return timeLabel;
-        }
-
-        function createRow(label, startTime, endTime, className) {
-            let row = document.createElement("li");
-            let labelElement = row.appendChild(document.createElement("span"));
-            labelElement.className = "row-label";
-            labelElement.textContent = label;
-            row.appendChild(createBlock(startTime, endTime, className));
-            row.appendChild(createTimeLabel(endTime, Number.secondsToMillisecondsString(endTime - startTime)));
-            return row;
-        }
-
-        listElement.appendChild(createRow(WI.UIString("Scheduled"), startTime, domainLookupStart || connectStart || requestStart, "queue"));
-        if (domainLookupStart)
-            listElement.appendChild(createRow(WI.UIString("DNS"), domainLookupStart, domainLookupEnd || connectStart || requestStart, "dns"));
-        if (connectStart)
-            listElement.appendChild(createRow(WI.UIString("TCP"), connectStart, connectEnd || requestStart, "connect"));
-        if (secureConnectionStart)
-            listElement.appendChild(createRow(WI.UIString("Secure"), secureConnectionStart, connectEnd || requestStart, "secure"));
-        listElement.appendChild(createRow(WI.UIString("Request"), requestStart, responseStart, "request"));
-        listElement.appendChild(createRow(WI.UIString("Response"), responseStart, responseEnd, "response"));
-
-        let totalRow = createRow(WI.UIString("Total"), startTime, responseEnd, "total");
-        listElement.appendChild(totalRow);
-        totalRow.classList.add("total");
-    }
-
-    _resourceSizeDidChange(event)
-    {
-        this._needsTransferSizesRefresh = true;
-        this.needsLayout();
-    }
-
-    _resourceTransferSizeDidChange(event)
-    {
-        this._needsTransferSizesRefresh = true;
-        this.needsLayout();
-    }
-
-    _resourceMetricsDidChange(event)
-    {
-        this._needsTransferSizesRefresh = true;
-        this._needsResourceSizeRefresh = true;
-        this._needsTimingRefresh = true;
-        this.needsLayout();
-    }
-
-    _resourceTimestampsDidChange(event)
-    {
-        this._needsTimingRefresh = true;
-        this.needsLayout();
-    }
-};

Added: trunk/Source/WebInspectorUI/UserInterface/Views/ResourceSizesContentView.css (0 => 224851)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ResourceSizesContentView.css	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ResourceSizesContentView.css	2017-11-14 23:22:45 UTC (rev 224851)
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+.resource-sizes {
+    font-family: '-webkit-system-font';
+}
+
+.resource-sizes > .content {
+    width: 550px;
+    margin: 0 auto;
+}
+
+.resource-sizes > .content .label {
+    color: gray;
+}
+
+.resource-sizes > .content > section {
+    position: relative;
+    padding: 10px 0;
+}
+
+.resource-sizes > .content > section .subtitle {
+    margin-bottom: 10px;
+    font-size: 14px;
+    text-align: center;
+    letter-spacing: 0.04em;
+}
+
+.resource-sizes > .content > section.split {
+    display: flex;
+    justify-content: center;
+}
+
+.resource-sizes > .content > section.split > .subsection {
+    width: 160px;
+    margin: 10px 0px;
+}
+
+.resource-sizes > .content > section.split > .subsection.large .icon {
+    width: 32px;
+    height: 32px;
+}
+
+.resource-sizes > .content > section.split > .subsection > table {
+    margin: 0 auto;
+}
+
+.resource-sizes > .content > section.split > .divider {
+    margin: 0 10px;
+    border-right: 1px solid var(--border-color);
+}
+
+.resource-sizes > .content > section.network > .subsection > .container {
+    display: flex;
+    justify-content: center;
+    margin-bottom: 8px;
+}
+
+.resource-sizes > .content > section.network .bytes-group {
+    text-align: start;
+}
+
+.resource-sizes > .content > section.network .bytes {
+    margin-top: 2px;
+    font-size: 28px;
+    display: inline-block;
+}
+
+.resource-sizes > .content > section.network table > tr > td.label {
+    text-align: end;
+}
+
+.resource-sizes > .content > section.network .suffix {
+    display: inline-block;
+    margin: 13px 1px 0 1px;
+    font-size: 15px;
+}
+
+.resource-sizes > .content > section.network img {
+    width: 32px;
+    height: 32px;
+    margin: 3px;
+}
+
+.resource-sizes > .content > section.network .go-to-arrow {
+    bottom: -1px;
+    height: 12px;
+    vertical-align: top;
+}
+
+.resource-sizes > .content > section.network .warning {
+    display: inline-block;
+    width: 10px;
+    height: 10px;
+    -webkit-margin-start: 3px;
+}

Copied: trunk/Source/WebInspectorUI/UserInterface/Views/ResourceSizesContentView.js (from rev 224850, trunk/Source/WebInspectorUI/UserInterface/Views/ResourceMetricsContentView.js) (0 => 224851)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ResourceSizesContentView.js	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ResourceSizesContentView.js	2017-11-14 23:22:45 UTC (rev 224851)
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+WI.ResourceSizesContentView = class ResourceSizesContentView extends WI.ContentView
+{
+    constructor(resource, delegate)
+    {
+        super(null);
+
+        console.assert(resource instanceof WI.Resource);
+        console.assert(delegate);
+
+        this._resource = resource;
+        this._resource.addEventListener(WI.Resource.Event.SizeDidChange, this._resourceSizeDidChange, this);
+        this._resource.addEventListener(WI.Resource.Event.TransferSizeDidChange, this._resourceTransferSizeDidChange, this);
+        this._resource.addEventListener(WI.Resource.Event.MetricsDidChange, this._resourceMetricsDidChange, this);
+
+        this._delegate = delegate;
+
+        this.element.classList.add("resource-details", "resource-sizes");
+
+        this._needsTransferSizesRefresh = false;
+        this._needsResourceSizeRefresh = false;
+    }
+
+    // Protected
+
+    initialLayout()
+    {
+        super.initialLayout();
+
+        let contentElement = this.element.appendChild(document.createElement("div"));
+        contentElement.className = "content";
+
+        let networkSection = contentElement.appendChild(document.createElement("section"));
+        networkSection.className = "network split";
+
+        function createSizeComponents(parentElement, subtitle, imageSource, label1, label2) {
+            let subtitleElement = parentElement.appendChild(document.createElement("div"));
+            subtitleElement.className = "subtitle";
+            subtitleElement.textContent = subtitle;
+
+            let container = parentElement.appendChild(document.createElement("div"));
+            container.className = "container";
+
+            let imageElement = container.appendChild(document.createElement("img"));
+            if (imageSource)
+                imageElement.src = ""
+
+            let groupElement = container.appendChild(document.createElement("div"));
+            groupElement.className = "bytes-group";
+
+            let bytesElement = groupElement.appendChild(document.createElement("div"));
+            bytesElement.className = "bytes";
+
+            let suffixElement = groupElement.appendChild(document.createElement("div"));
+            suffixElement.className = "suffix";
+
+            let table = parentElement.appendChild(document.createElement("table"));
+            let headerRow = table.appendChild(document.createElement("tr"));
+            let label1Element = headerRow.appendChild(document.createElement("td"));
+            let value1Element = headerRow.appendChild(document.createElement("td"));
+            let bodyRow = table.appendChild(document.createElement("tr"));
+            let label2Element = bodyRow.appendChild(document.createElement("td"));
+            let value2Element = bodyRow.appendChild(document.createElement("td"));
+
+            label1Element.textContent = label1;
+            label1Element.className = "label";
+            label2Element.textContent = label2;
+            label2Element.className = "label";
+
+            return {
+                container,
+                bytesElement,
+                suffixElement,
+                imageElement,
+                value1Element,
+                value2Element,
+            };
+        }
+
+        let sendingSection = networkSection.appendChild(document.createElement("div"));
+        sendingSection.className = "subsection";
+
+        let sendingComponents = createSizeComponents(sendingSection, WI.UIString("Bytes Sent"), "Images/Sending.svg", WI.UIString("Headers:"), WI.UIString("Body:"));
+        this._sendingBytesElement = sendingComponents.bytesElement;
+        this._sendingBytesSuffixElement = sendingComponents.suffixElement;
+        this._sendingHeaderBytesElement = sendingComponents.value1Element;
+        this._sendingBodyBytesElement = sendingComponents.value2Element;
+
+        let bytesDivider = networkSection.appendChild(document.createElement("div"));
+        bytesDivider.className = "divider";
+
+        let receivingSection = networkSection.appendChild(document.createElement("div"));
+        receivingSection.className = "subsection";
+
+        let receivingComponents = createSizeComponents(receivingSection, WI.UIString("Bytes Received"), "Images/Receiving.svg", WI.UIString("Headers:"), WI.UIString("Body:"));
+        this._receivingBytesElement = receivingComponents.bytesElement;
+        this._receivingBytesSuffixElement = receivingComponents.suffixElement;
+        this._receivingHeaderBytesElement = receivingComponents.value1Element;
+        this._receivingBodyBytesElement = receivingComponents.value2Element;
+
+        let resourceDivider = networkSection.appendChild(document.createElement("div"));
+        resourceDivider.className = "divider";
+
+        let resourceSection = networkSection.appendChild(document.createElement("div"));
+        resourceSection.className = "subsection large";
+
+        let resourceComponents = createSizeComponents(resourceSection, WI.UIString("Resource Size"), null, WI.UIString("Compression:"), WI.UIString("MIME Type:"));
+        resourceComponents.container.classList.add(WI.ResourceTreeElement.ResourceIconStyleClassName, this._resource.type);
+        resourceComponents.imageElement.classList.add("icon");
+        this._resourceBytesElement = resourceComponents.bytesElement;
+        this._resourceBytesSuffixElement = resourceComponents.suffixElement;
+        this._compressionElement = resourceComponents.value1Element;
+        this._contentTypeElement = resourceComponents.value2Element;
+
+        this._refreshTransferSizeSections();
+        this._refreshResourceSizeSection();
+
+        this._needsTransferSizesRefresh = false;
+        this._needsResourceSizeRefresh = false;
+    }
+
+    layout()
+    {
+        super.layout();
+
+        if (this._needsTransferSizesRefresh) {
+            this._refreshTransferSizeSections();
+            this._needsTransferSizesRefresh = false;
+        }
+
+        if (this._needsResourceSizeRefresh) {
+            this._refreshResourceSizeSection();
+            this._needsResourceSizeRefresh = false;
+        }
+    }
+
+    closed()
+    {
+        this._resource.removeEventListener(null, null, this);
+
+        super.closed();
+    }
+
+    // Private
+
+    _sizeComponents(bytes)
+    {
+        console.assert(bytes >= 0);
+
+        // Prefer KB over B. And prefer 1 decimal point to keep sizes simple
+        // but we will still need B if bytes is less than 0.1 KB.
+        if (bytes < 103)
+            return [bytes.toFixed(0), "B"];
+
+        let kilobytes = bytes / 1024;
+        if (kilobytes < 1024)
+            return [kilobytes.toFixed(1), "KB"];
+
+        let megabytes = kilobytes / 1024;
+        if (megabytes < 1024)
+            return [megabytes.toFixed(1), "MB"];
+
+        let gigabytes = megabytes / 1024;
+        return [gigabytes.toFixed(1), "GB"];
+    }
+
+    _refreshTransferSizeSections()
+    {
+        let bytesSentHeader = this._resource.requestHeadersTransferSize;
+        let bytesSentBody = this._resource.requestBodyTransferSize;
+        let bytesSent = bytesSentHeader + bytesSentBody;
+
+        let bytesReceivedHeader = this._resource.responseHeadersTransferSize;
+        let bytesReceivedBody = this._resource.responseBodyTransferSize;
+        let bytesReceived = bytesReceivedHeader + bytesReceivedBody;
+
+        let [sentValue, sentSuffix] = this._sizeComponents(bytesSent || 0);
+        this._sendingBytesElement.textContent = sentValue;
+        this._sendingBytesSuffixElement.textContent = sentSuffix;
+
+        this._sendingHeaderBytesElement.textContent = bytesSentHeader ? Number.bytesToString(bytesSentHeader) : emDash;
+        this._sendingBodyBytesElement.textContent = bytesSentBody ? Number.bytesToString(bytesSentBody) : emDash;
+
+        let [receivedValue, receivedSuffix] = this._sizeComponents(bytesReceived || 0);
+        this._receivingBytesElement.textContent = receivedValue;
+        this._receivingBytesSuffixElement.textContent = receivedSuffix;
+
+        this._receivingHeaderBytesElement.textContent = bytesReceivedHeader ? Number.bytesToString(bytesReceivedHeader) : emDash;
+        this._receivingBodyBytesElement.textContent = bytesReceivedBody ? Number.bytesToString(bytesReceivedBody) : emDash;
+
+        function appendGoToArrow(parentElement, handler) {
+            let goToButton = parentElement.appendChild(WI.createGoToArrowButton());
+            goToButton.addEventListener("click", handler);
+        }
+
+        if (bytesSentHeader)
+            appendGoToArrow(this._sendingHeaderBytesElement, () => { this._delegate.sizesContentViewGoToHeaders(this); });
+        if (bytesSentBody)
+            appendGoToArrow(this._sendingBodyBytesElement, () => { this._delegate.sizesContentViewGoToRequestBody(this); });
+        if (bytesReceivedHeader)
+            appendGoToArrow(this._receivingHeaderBytesElement, () => { this._delegate.sizesContentViewGoToHeaders(this); });
+        if (bytesReceivedBody)
+            appendGoToArrow(this._receivingBodyBytesElement, () => { this._delegate.sizesContentViewGoToResponseBody(this); });
+    }
+
+    _refreshResourceSizeSection()
+    {
+        let encodedSize = !isNaN(this._resource.networkEncodedSize) ? this._resource.networkEncodedSize : this._resource.estimatedNetworkEncodedSize;
+        let decodedSize = !isNaN(this._resource.networkDecodedSize) ? this._resource.networkDecodedSize : this._resource.size;
+        let compressionRate = decodedSize / encodedSize;
+        let compressionString = compressionRate > 0 && isFinite(compressionRate) ? WI.UIString("%.2f\u00d7").format(compressionRate) : WI.UIString("None");
+
+        let [resourceSizeValue, resourceSizeSuffix] = this._sizeComponents(decodedSize || 0);
+        this._resourceBytesElement.textContent = resourceSizeValue;
+        this._resourceBytesSuffixElement.textContent = resourceSizeSuffix;
+
+        let contentEncoding = this._resource.responseHeaders.valueForCaseInsensitiveKey("Content-Encoding");
+        if (contentEncoding)
+            compressionString += ` (${contentEncoding.toLowerCase()})`;
+
+        this._compressionElement.textContent = compressionString;
+        this._contentTypeElement.textContent = this._resource.mimeType || emDash;
+
+        const minimumSizeBeforeWarning = 1024;
+        if (compressionRate <= 1 && encodedSize >= minimumSizeBeforeWarning && WI.shouldTreatMIMETypeAsText(this._resource.mimeType))
+            this._compressionElement.appendChild(WI.ImageUtilities.useSVGSymbol("Images/Warning.svg", "warning", WI.UIString("This text resource could benefit from compression")));
+    }
+
+    _resourceSizeDidChange(event)
+    {
+        this._needsTransferSizesRefresh = true;
+        this.needsLayout();
+    }
+
+    _resourceTransferSizeDidChange(event)
+    {
+        this._needsTransferSizesRefresh = true;
+        this.needsLayout();
+    }
+
+    _resourceMetricsDidChange(event)
+    {
+        this._needsTransferSizesRefresh = true;
+        this._needsResourceSizeRefresh = true;
+        this.needsLayout();
+    }
+};

Added: trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimingContentView.css (0 => 224851)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimingContentView.css	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimingContentView.css	2017-11-14 23:22:45 UTC (rev 224851)
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+.resource-timing {
+    font-family: '-webkit-system-font';
+}
+
+.resource-timing > .content {
+    width: 550px;
+    margin: 0 auto;
+}
+
+.resource-timing > .content .label {
+    color: gray;
+}
+
+.resource-timing > .content > section.timing {
+    padding: 20px 0;
+}
+
+.resource-timing > .content > section.timing > ul {
+    margin: 0;
+    padding: 0;
+    list-style-type: none;
+}
+
+.resource-timing > .content > section.timing > ul > li {
+    position: relative;
+    height: 20px;
+    padding: 1px 0;
+    line-height: 18px;
+}
+
+.resource-timing > .content > section.timing > .waterfall {
+    width: 500px;
+    margin: auto;
+}
+
+.resource-timing > .content > section.timing > .waterfall .block {
+    top: 4px;
+    min-width: 1px;
+    height: 12px;
+}
+
+.resource-timing > .content > section.timing > ul > li > .row-label {
+    display: inline-block;
+    min-width: 70px;
+    color: black;
+}
+
+.resource-timing > .content > section.timing > ul > li > .row-label {
+    text-align: end;
+}
+
+.resource-timing > .content > section.timing > ul > li > .time-label {
+    position: absolute;
+    top: 1px;
+    color: gray;
+}
+
+.resource-timing > .content > section.timing > ul > li.total .block {
+    display: none;
+}
+
+.resource-timing > .content > section.timing > ul > li.total .time-label {
+    color: black;
+}
+
+.resource-timing > .content > section.timing .indeterminate-progress-spinner {
+    margin: 0 auto;
+}
+
+.resource-timing > .content > section.timing .empty {
+    text-align: center;
+    color: gray;
+}

Added: trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimingContentView.js (0 => 224851)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimingContentView.js	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimingContentView.js	2017-11-14 23:22:45 UTC (rev 224851)
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+WI.ResourceTimingContentView = class ResourceTimingContentView extends WI.ContentView
+{
+    constructor(resource)
+    {
+        super(null);
+
+        console.assert(resource instanceof WI.Resource);
+
+        this._resource = resource;
+        this._resource.addEventListener(WI.Resource.Event.MetricsDidChange, this._resourceMetricsDidChange, this);
+        this._resource.addEventListener(WI.Resource.Event.TimestampsDidChange, this._resourceTimestampsDidChange, this);
+
+        this.element.classList.add("resource-details", "resource-timing");
+
+        this._needsTimingRefresh = false;
+    }
+
+    // Protected
+
+    initialLayout()
+    {
+        super.initialLayout();
+
+        let contentElement = this.element.appendChild(document.createElement("div"));
+        contentElement.className = "content";
+
+        this._timingSection = contentElement.appendChild(document.createElement("section"));
+        this._timingSection.className = "timing";
+
+        this._refreshTimingSection();
+
+        this._needsTimingRefresh = false;
+    }
+
+    layout()
+    {
+        super.layout();
+
+        if (this._needsTimingRefresh) {
+            this._refreshTimingSection();
+            this._needsTimingRefresh = false;
+        }
+    }
+
+    closed()
+    {
+        this._resource.removeEventListener(null, null, this);
+
+        super.closed();
+    }
+
+    // Private
+
+    _refreshTimingSection()
+    {
+        this._timingSection.removeChildren();
+
+        if (!this._resource.hasResponse()) {
+            let spinner = new WI.IndeterminateProgressSpinner;
+            this._timingSection.appendChild(spinner.element);
+            return;
+        }
+
+        if (!this._resource.timingData.startTime || !this._resource.timingData.responseEnd) {
+            let p = this._timingSection.appendChild(document.createElement("p"));
+            p.className = "empty";
+            p.textContent = WI.UIString("Resource does not have timing data");
+            return;
+        }
+
+        // FIXME: Converge on using WI.ResourceTimingBreakdownView when a design is finalized.
+
+        let listElement = this._timingSection.appendChild(document.createElement("ul"));
+        listElement.className = "waterfall"; // Include waterfall block styles.
+
+        const graphWidth = 380;
+        const graphStartOffset = 80;
+
+        let {startTime, domainLookupStart, domainLookupEnd, connectStart, connectEnd, secureConnectionStart, requestStart, responseStart, responseEnd} = this._resource.timingData;
+        let graphStartTime = startTime;
+        let graphEndTime = responseEnd;
+        let secondsPerPixel = (responseEnd - startTime) / graphWidth;
+
+        function createBlock(startTime, endTime, className, makeEmpty) {
+            let startOffset = graphStartOffset + ((startTime - graphStartTime) / secondsPerPixel);
+            let width = makeEmpty ? 1 : (endTime - startTime) / secondsPerPixel;
+            let block = document.createElement("div");
+            block.classList.add("block", className);
+            let property = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? "right" : "left";
+            block.style[property] = startOffset + "px";
+            block.style.width = width + "px";
+            return block;
+        }
+
+        function createTimeLabel(endTime, label) {
+            let positionOffset = graphStartOffset + ((endTime - graphStartTime) / secondsPerPixel);
+            positionOffset += 3;
+            let timeLabel = document.createElement("div");
+            timeLabel.className = "time-label";
+            timeLabel.textContent = label;
+            let property = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? "right" : "left";
+            timeLabel.style[property] = positionOffset + "px";
+            return timeLabel;
+        }
+
+        function createRow(label, startTime, endTime, className) {
+            let row = document.createElement("li");
+            let labelElement = row.appendChild(document.createElement("span"));
+            labelElement.className = "row-label";
+            labelElement.textContent = label;
+            row.appendChild(createBlock(startTime, endTime, className));
+            row.appendChild(createTimeLabel(endTime, Number.secondsToMillisecondsString(endTime - startTime)));
+            return row;
+        }
+
+        listElement.appendChild(createRow(WI.UIString("Scheduled"), startTime, domainLookupStart || connectStart || requestStart, "queue"));
+        if (domainLookupStart)
+            listElement.appendChild(createRow(WI.UIString("DNS"), domainLookupStart, domainLookupEnd || connectStart || requestStart, "dns"));
+        if (connectStart)
+            listElement.appendChild(createRow(WI.UIString("TCP"), connectStart, connectEnd || requestStart, "connect"));
+        if (secureConnectionStart)
+            listElement.appendChild(createRow(WI.UIString("Secure"), secureConnectionStart, connectEnd || requestStart, "secure"));
+        listElement.appendChild(createRow(WI.UIString("Request"), requestStart, responseStart, "request"));
+        listElement.appendChild(createRow(WI.UIString("Response"), responseStart, responseEnd, "response"));
+
+        let totalRow = createRow(WI.UIString("Total"), startTime, responseEnd, "total");
+        listElement.appendChild(totalRow);
+        totalRow.classList.add("total");
+    }
+
+    _resourceMetricsDidChange(event)
+    {
+        this._needsTimingRefresh = true;
+        this.needsLayout();
+    }
+
+    _resourceTimestampsDidChange(event)
+    {
+        this._needsTimingRefresh = true;
+        this.needsLayout();
+    }
+};
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to