UNPKG

monaca-lib

Version:

Monaca cloud API bindings for JavaScript

278 lines (247 loc) 12.2 kB
/* * Copyright (C) 2010 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "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 THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor * @extends {WebInspector.VBox} * @param {!WebInspector.NetworkRequest} request * @param {!WebInspector.NetworkTimeCalculator} calculator */ WebInspector.RequestTimingView = function(request, calculator) { WebInspector.VBox.call(this); this.element.classList.add("resource-timing-view"); this._request = request; this._calculator = calculator; } WebInspector.RequestTimingView.prototype = { wasShown: function() { this._request.addEventListener(WebInspector.NetworkRequest.Events.TimingChanged, this._refresh, this); this._request.addEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._refresh, this); this._calculator.addEventListener(WebInspector.NetworkTimeCalculator.Events.BoundariesChanged, this._refresh, this); this._refresh(); }, willHide: function() { this._request.removeEventListener(WebInspector.NetworkRequest.Events.TimingChanged, this._refresh, this); this._request.removeEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._refresh, this); this._calculator.removeEventListener(WebInspector.NetworkTimeCalculator.Events.BoundariesChanged, this._refresh, this); }, _refresh: function() { if (this._tableElement) this._tableElement.remove(); this._tableElement = WebInspector.RequestTimingView.createTimingTable(this._request, this._calculator.minimumBoundary()); this.element.appendChild(this._tableElement); }, __proto__: WebInspector.VBox.prototype } /** @enum {string} */ WebInspector.RequestTimeRangeNames = { Blocking: "blocking", Connecting: "connecting", DNS: "dns", Proxy: "proxy", Receiving: "receiving", Sending: "sending", ServiceWorker: "serviceworker", ServiceWorkerPreparation: "serviceworker-preparation", SSL: "ssl", Total: "total", Waiting: "waiting" }; WebInspector.RequestTimingView.ConnectionSetupRangeNames = [ WebInspector.RequestTimeRangeNames.Blocking, WebInspector.RequestTimeRangeNames.Connecting, WebInspector.RequestTimeRangeNames.DNS, WebInspector.RequestTimeRangeNames.Proxy, WebInspector.RequestTimeRangeNames.SSL ].keySet(); /** @typedef {{name: !WebInspector.RequestTimeRangeNames, start: number, end: number}} */ WebInspector.RequestTimeRange; /** * @param {!WebInspector.RequestTimeRangeNames} name * @return {string} */ WebInspector.RequestTimingView._timeRangeTitle = function(name) { switch (name) { case WebInspector.RequestTimeRangeNames.Blocking: return WebInspector.UIString("Stalled"); case WebInspector.RequestTimeRangeNames.Connecting: return WebInspector.UIString("Initial connection"); case WebInspector.RequestTimeRangeNames.DNS: return WebInspector.UIString("DNS Lookup"); case WebInspector.RequestTimeRangeNames.Proxy: return WebInspector.UIString("Proxy negotiation"); case WebInspector.RequestTimeRangeNames.Receiving: return WebInspector.UIString("Content Download"); case WebInspector.RequestTimeRangeNames.Sending: return WebInspector.UIString("Request sent"); case WebInspector.RequestTimeRangeNames.ServiceWorker: return WebInspector.UIString("Request to ServiceWorker"); case WebInspector.RequestTimeRangeNames.ServiceWorkerPreparation: return WebInspector.UIString("ServiceWorker Preparation"); case WebInspector.RequestTimeRangeNames.SSL: return WebInspector.UIString("SSL"); case WebInspector.RequestTimeRangeNames.Total: return WebInspector.UIString("Total"); case WebInspector.RequestTimeRangeNames.Waiting: return WebInspector.UIString("Waiting (TTFB)"); default: return WebInspector.UIString(name); } } /** * @param {!WebInspector.NetworkRequest} request * @return {!Array.<!WebInspector.RequestTimeRange>} */ WebInspector.RequestTimingView.calculateRequestTimeRanges = function(request) { var result = []; /** * @param {!WebInspector.RequestTimeRangeNames} name * @param {number} start * @param {number} end */ function addRange(name, start, end) { if (start < Number.MAX_VALUE && start <= end) result.push({name: name, start: start, end: end}); } /** * @param {!Array.<number>} numbers * @return {number|undefined} */ function firstPositive(numbers) { for (var i = 0; i < numbers.length; ++i) { if (numbers[i] > 0) return numbers[i]; } return undefined; } /** * @param {!WebInspector.RequestTimeRangeNames} name * @param {number} start * @param {number} end */ function addOffsetRange(name, start, end) { if (start >= 0 && end >= 0) addRange(name, startTime + (start / 1000), startTime + (end / 1000)); } var timing = request.timing; if (!timing) { var start = request.issueTime() !== -1 ? request.issueTime() : request.startTime !== -1 ? request.startTime : 0; var middle = (request.responseReceivedTime === -1) ? Number.MAX_VALUE : request.responseReceivedTime; var end = (request.endTime === -1) ? Number.MAX_VALUE : request.endTime; addRange(WebInspector.RequestTimeRangeNames.Total, start, end); addRange(WebInspector.RequestTimeRangeNames.Blocking, start, middle); addRange(WebInspector.RequestTimeRangeNames.Receiving, middle, end); return result; } var issueTime = request.issueTime(); var startTime = timing.requestTime; var endTime = firstPositive([request.endTime, request.responseReceivedTime]) || startTime; addRange(WebInspector.RequestTimeRangeNames.Total, issueTime < startTime ? issueTime : startTime, endTime); if (request.fetchedViaServiceWorker) { addOffsetRange(WebInspector.RequestTimeRangeNames.Blocking, 0, timing.serviceWorkerFetchStart); addOffsetRange(WebInspector.RequestTimeRangeNames.ServiceWorker, timing.serviceWorkerFetchStart, timing.serviceWorkerFetchEnd); addOffsetRange(WebInspector.RequestTimeRangeNames.ServiceWorkerPreparation, timing.serviceWorkerFetchStart, timing.serviceWorkerFetchReady); addOffsetRange(WebInspector.RequestTimeRangeNames.Waiting, timing.serviceWorkerFetchEnd, timing.receiveHeadersEnd); } else { var blocking = firstPositive([timing.dnsStart, timing.connectStart, timing.sendStart]) || 0; addOffsetRange(WebInspector.RequestTimeRangeNames.Blocking, 0, blocking); addOffsetRange(WebInspector.RequestTimeRangeNames.Proxy, timing.proxyStart, timing.proxyEnd); addOffsetRange(WebInspector.RequestTimeRangeNames.DNS, timing.dnsStart, timing.dnsEnd); addOffsetRange(WebInspector.RequestTimeRangeNames.Connecting, timing.connectStart, timing.connectEnd); addOffsetRange(WebInspector.RequestTimeRangeNames.SSL, timing.sslStart, timing.sslEnd); addOffsetRange(WebInspector.RequestTimeRangeNames.Sending, timing.sendStart, timing.sendEnd); addOffsetRange(WebInspector.RequestTimeRangeNames.Waiting, timing.sendEnd, timing.receiveHeadersEnd); } if (request.endTime !== -1) addRange(WebInspector.RequestTimeRangeNames.Receiving, request.responseReceivedTime, endTime); return result; } /** * @param {!WebInspector.NetworkRequest} request * @param {number} navigationStart * @return {!Element} */ WebInspector.RequestTimingView.createTimingTable = function(request, navigationStart) { var tableElement = createElementWithClass("table", "network-timing-table"); var colgroup = tableElement.createChild("colgroup"); colgroup.createChild("col", "labels"); colgroup.createChild("col", "bars"); colgroup.createChild("col", "duration"); var timeRanges = WebInspector.RequestTimingView.calculateRequestTimeRanges(request); var startTime = timeRanges[0].start; var endTime = timeRanges[0].end; var scale = 100 / (endTime - startTime); var connectionHeader; var dataHeader; var totalDuration = 0; for (var i = 0; i < timeRanges.length; ++i) { var range = timeRanges[i]; var rangeName = range.name; if (rangeName === WebInspector.RequestTimeRangeNames.Total) { totalDuration = range.end - range.start; continue; } if (WebInspector.RequestTimingView.ConnectionSetupRangeNames[rangeName]) { if (!connectionHeader) { connectionHeader = tableElement.createChild("tr", "network-timing-table-header"); connectionHeader.createChild("td").createTextChild("Connection Setup"); connectionHeader.createChild("td").createTextChild(""); connectionHeader.createChild("td").createTextChild("TIME"); } } else { if (!dataHeader) { dataHeader = tableElement.createChild("tr", "network-timing-table-header"); dataHeader.createChild("td").createTextChild("Request/Response"); dataHeader.createChild("td").createTextChild(""); dataHeader.createChild("td").createTextChild("TIME"); } } var left = (scale * (range.start - startTime)); var right = (scale * (endTime - range.end)); var duration = range.end - range.start; var tr = tableElement.createChild("tr"); tr.createChild("td").createTextChild(WebInspector.RequestTimingView._timeRangeTitle(rangeName)); var row = tr.createChild("td").createChild("div", "network-timing-row"); var bar = row.createChild("span", "network-timing-bar " + rangeName); bar.style.left = left + "%"; bar.style.right = right + "%"; bar.textContent = "\u200B"; // Important for 0-time items to have 0 width. var label = tr.createChild("td").createChild("div", "network-timing-bar-title"); label.textContent = Number.secondsToString(duration, true); } if (!request.finished) { var cell = tableElement.createChild("tr").createChild("td", "caution"); cell.colSpan = 3; cell.createTextChild(WebInspector.UIString("CAUTION: request is not finished yet!")); } var footer = tableElement.createChild("tr", "network-timing-footer"); var note = footer.createChild("td"); note.colSpan = 2; note.appendChild(WebInspector.createDocumentationAnchor("network#resource-network-timing", WebInspector.UIString("Explanation"))); footer.createChild("td").createTextChild(Number.secondsToString(totalDuration, true)); return tableElement; }