api-console-assets
Version:
This repo only exists to publish api console components to npm
385 lines (363 loc) • 13 kB
HTML
<!--
@license
Copyright 2016 The Advanced REST client authors <arc@mulesoft.com>
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
-->
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../paper-progress/paper-progress.html">
<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="../date-time/date-time.html">
<!--
`<request-timings>`
An element to display request timings information as a timeline according to the HAR 1.2 spec.
The `timings` property should contain timings object as defined in [HAR 1.2 spec](https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HAR/Overview.html#sec-object-types-timings).
The timings object is consisted of:
- **blocked** [number, optional] - Time spent in a queue waiting for a network connection. Use -1 if the timing does not apply to the current request.
- **dns** [number, optional] - DNS resolution time. The time required to resolve a host name. Use -1 if the timing does not apply to the current request.
- **connect** [number, optional] - Time required to create TCP connection. Use -1 if the timing does not apply to the current request.
- **send** [number] - Time required to send HTTP request to the server.
- **wait** [number] - Waiting for a response from the server.
- **receive** [number] - Time required to read entire response from the server (or cache).
- **ssl** [number, optional] - Time required for SSL/TLS negotiation. If this field is defined then the time is also included in the connect field (to ensure backward compatibility with HAR 1.1). Use -1 if the timing does not apply to the current request.
Additionally the object can contain the `startTime` property that indicates
the request start time. If can be Date object, timestamp or formatted string
representing a date.
The timeline for `connect`, `send`, `wait` and `receive` are always shown.
`blocked`, `dns` and `ssl` are visible only if values for it was set and value
was > 0.
### Example
```
<request-timings timings="[[requestTimings]]"></request-timings>
```
### Styling
`<request-timings>` provides the following custom properties and mixins for styling:
Custom property | Description | Default
----------------|-------------|----------
`--request-timings` | Mixin applied to the element | `{}`
`--select-text` | Mixin applied to the text elements that should have text selection enabled (in some platforms text selection is disabled by default) | `{}`
`--form-label` | Mixin applied to labels elements | `{}`
`--request-timings-progress-height` | The height of the progress bar | `12px`
`--request-timings-progress-background` | Background color of the progress bar. | `#F5F5F5`
`--request-timings-progress-color` | Color of the progress bar. | `#4a4`
`--request-timings-label-width` | Width of the label | `160px`
`--request-timings-value-width` | Width of the value column | `120px`
@group UI Elements
@element request-timings
@demo demo/index.html
-->
<dom-module id="request-timings">
<template>
<style>
:host {
display: block;
--paper-progress-height: var(--request-timings-progress-height, 12px);
--paper-progress-container-color: var(--request-timings-progress-background, #F5F5F5);
--paper-progress-active-color: var(--request-timings-progress-background, #F5F5F5);
--paper-progress-secondary-color: var(--request-timings-progress-color, #4a4);
@apply(--request-timings);
}
.row {
@apply(--layout-horizontal);
@apply(--layout-center);
}
.flex,
.timing-chart {
@apply(--layout-flex);
}
.label,
.date-value {
@apply(--select-text);
@apply(--form-label);
}
.timing-label {
width: var(--request-timings-label-width, 160px);
@apply(--form-label);
}
.timing-value {
width: var(--request-timings-value-width, 120px);
text-align: right;
@apply(--select-text);
}
paper-progress {
width: 100%;
}
.total {
margin-top: 12px;
padding-top: 12px;
font-weight: 500;
border-top: 2px var(--paper-grey-200, rgba(255, 0, 0, 0.74)) solid;
}
</style>
<div class="row" hidden$="[[!_hasValue(startTime)]]">
<div class="flex">
<span class="label">Start date</span>:
<date-time year="numeric" month="numeric" day="numeric" hour="numeric" minute="numeric" second="numeric" class="date-value" date="[[startTime]]"></date-time>
</div>
</div>
<div class="row" hidden$="[[!_hasValue(blocked)]]">
<div class="timing-label label" id="queueing">
Queueing:
</div>
<div class="timing-chart">
<paper-progress aria-labelledby="queueing" value="0" secondary-progress="[[blocked]]" max="[[fullTime]]" step="0.0001"></paper-progress>
</div>
<span class="timing-value">[[_round(blocked)]] ms</span>
</div>
<div class="row" hidden$="[[!_hasValue(dns)]]">
<div class="timing-label label" id="dnsLookup">
DNS Lookup:
</div>
<div class="timing-chart">
<paper-progress aria-labelledby="dnsLookup" value="[[_computeSum(blocked)]]" secondary-progress="[[_computeSum(blocked, dns)]]" max="[[fullTime]]" step="0.0001"></paper-progress>
</div>
<span class="timing-value">[[_round(dns)]] ms</span>
</div>
<div class="row">
<div class="timing-label label" id="ttc">
Time to connect:
</div>
<div class="timing-chart">
<paper-progress aria-labelledby="ttc" value="[[_computeSum(blocked, dns)]]" secondary-progress="[[_computeSum(blocked, dns, connect)]]" max="[[fullTime]]" step="0.0001"></paper-progress>
</div>
<span class="timing-value">[[_round(connect)]] ms</span>
</div>
<div class="row" hidden$="[[!_hasValue(ssl)]]">
<div class="timing-label label" id="ssl">
SSL negotiation:
</div>
<div class="timing-chart">
<paper-progress aria-labelledby="ssl" secondary-progress="[[_computeSum(blocked, dns, connect, ssl)]]" value="[[_computeSum(blocked, dns, connect)]]" max="[[fullTime]]" step="0.0001"></paper-progress>
</div>
<span class="timing-value">[[_round(ssl)]] ms</span>
</div>
<div class="row">
<div class="timing-label label" id="sendTime">
Send time:
</div>
<div class="timing-chart">
<paper-progress aria-labelledby="sendTime" secondary-progress="[[_computeSum(blocked, dns, connect, ssl, send)]]" value="[[_computeSum(blocked, dns, connect, ssl)]]" max="[[fullTime]]" step="0.0001"></paper-progress>
</div>
<span class="timing-value">[[_round(send)]] ms</span>
</div>
<div class="row">
<div class="timing-label label" id="ttfb">
Wait time (TTFB):
</div>
<div class="timing-chart">
<paper-progress aria-labelledby="ttfb" secondary-progress="[[_computeSum(blocked, dns, connect, send, ssl, wait)]]" value="[[_computeSum(blocked, dns, connect, send, ssl)]]" max="[[fullTime]]" step="0.0001"></paper-progress>
</div>
<span class="timing-value">[[_round(wait)]] ms</span>
</div>
<div class="row">
<div class="timing-label label" id="receive">
Content download:
</div>
<div class="timing-chart">
<paper-progress aria-labelledby="receive" secondary-progress="[[_computeSum(blocked, dns, connect, send, ssl, wait, receive)]]" value="[[_computeSum(blocked, dns, connect, send, ssl, wait)]]" max="[[fullTime]]" step="0.0001"></paper-progress>
</div>
<span class="timing-value">[[_round(receive)]] ms</span>
</div>
<div class="row">
<div class="flex"></div>
<span class="timing-value total">[[_round(fullTime)]] ms</span>
</div>
</template>
<script>
Polymer({
is: 'request-timings',
properties: {
/**
* A timings object as described in HAR 1.2 spec.
*/
timings: {
type: Object
},
/**
* Request stat time. It can be either Date object,
* timestamp or a string representing the date.
*
* If the `timings` property contains the `startTime` property it
* will be overwritten.
*/
startTime: {
type: String
},
/**
* Computed value. Calculated full time of the request and response
*/
fullTime: {
type: Number,
readOnly: true
},
// Computed value. Time required to establish the connection
connect: {
type: Number,
readOnly: true
},
// Computed value. Time of receiving data from the remote machine.
receive: {
type: Number,
readOnly: true
},
// Computed value. Time to send data to the remote machine.
send: {
type: Number,
readOnly: true
},
// Computed value. Wait time for the first byte to arrive.
wait: {
type: Number,
readOnly: true
},
// Computed value. Time spent in a queue waiting for a network connection
blocked: {
type: Number,
readOnly: true
},
// Computed value. DNS resolution time.
dns: {
type: Number,
readOnly: true
},
// Computed value. Time required for SSL/TLS negotiation.
ssl: {
type: Number,
readOnly: true
}
},
observers: [
'_update(timings.*)'
],
ready: function() {
this.isReady = true;
this._update();
},
detached: function() {
this.reset();
},
// Resets the timeline.
reset: function() {
this._setFullTime(0);
this._setConnect(0);
this._setReceive(0);
this._setSend(0);
this._setWait(0);
this._setDns(-1);
this._setBlocked(-1);
this._setSsl(-1);
this.startTime = 0;
},
// Updates the view after `timings` change.
_update: function() {
if (!this.isReady) {
return;
}
var timings = this.timings || {};
var fullTime = 0;
var connect = Number(timings.connect);
var receive = Number(timings.receive);
var send = Number(timings.send);
var wait = Number(timings.wait);
var blocked = Number(timings.blocked);
var dns = Number(timings.dns);
var ssl = Number(timings.ssl);
if (connect !== connect || connect < 0) {
connect = 0;
}
if (receive !== receive || receive < 0) {
receive = 0;
}
if (send !== send || send < 0) {
send = 0;
}
if (wait !== wait || wait < 0) {
wait = 0;
}
if (dns !== dns || dns < 0) {
dns = -1;
}
if (blocked !== blocked || blocked < 0) {
blocked = -1;
}
if (ssl !== ssl || ssl < 0) {
ssl = -1;
}
fullTime += connect + receive + send + wait;
if (dns > 0) {
fullTime += dns;
}
if (blocked > 0) {
fullTime += blocked;
}
if (ssl > 0) {
fullTime += ssl;
}
this._setFullTime(fullTime);
this._setConnect(connect);
this._setReceive(receive);
this._setSend(send);
this._setWait(wait);
this._setDns(dns);
this._setBlocked(blocked);
this._setSsl(ssl);
if (timings.startTime) {
this.set('startTime', timings.startTime);
} else {
this.set('startTime', this.startTime || -1);
}
},
/**
* Round numeric value to presision defined in the `power` argument.
*
* @param {Number} value The value to round
* @param {Number} power The precision. 0 for integers. Default 4.
* @return {Number} Rounded value.
*/
_round: function(value, power) {
value = Number(value);
if (value !== value) {
return 'unknown';
}
power = +power;
if (power === 0) {
return Math.round(value);
}
if (!power || power !== power) {
power = 4;
}
power = Math.pow(10, power);
return Math.round(value * power) / power;
},
// Computes sum of the arguments.
_computeSum: function(/* args */) {
var sum = 0;
var values = Array.prototype.slice.call(arguments);
values.forEach(function(i) {
i = Number(i);
if (i < 0) {
return;
}
sum += i;
});
return sum;
},
_hasValue: function(num) {
if (num === undefined) {
return false;
}
if (typeof num === 'string') {
return !!num;
}
return num > 0;
}
});
</script>
</dom-module>