UNPKG

api-console-assets

Version:

This repo only exists to publish api console components to npm

336 lines (320 loc) 11.4 kB
<!-- @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"> <!-- Polyfill for the Response, Request, and Headers objects --> <link rel="import" href="../promise-polyfill/promise-polyfill-lite.html"> <link rel="import" href="../fetch-polyfill/fetch-polyfill.html"> <link rel="import" href="../response-status-view/response-status-view.html"> <link rel="import" href="../response-error-view/response-error-view.html"> <link rel="import" href="../response-body-view/response-body-view.html"> <!-- `<response-view>` An element to display the HTTP response view. It uses the Fetch API's objects to pass the [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) data. The element import polyfils for the Promises API and for the Fetch API. ### Example ``` <response-view loading-time="200.123" is-xhr></response-view> <script> var panel = document.querySelector('response-view'); panel.request = request; // A Request class instance panel.response = response; // A Response class instance panel.responseError = undefined; // Clean if it was set previously. </script> ``` If the transport can provide more details about the request like detailed timings, redirects information or source message sent to the server you can set corresponding attributes to display this information. Otherwise set `isXhr` attribute to display a basic view. To see detailed information about data format see the [response-status-view](https://elements.advancedrestclient.com/elements/response-status-view) element documentation. ## Request additional properties The element will attempt to read the `rawMessage` on the `request` object. If it's set and `isXhr` is not set then the source message will be displayed in the `request headers` panel. If this property is set but the app have this information, just set the `sentHttpMessage` property. ### Styling `<response-view>` provides the following custom properties and mixins for styling: Custom property | Description | Default ----------------|-------------|---------- `--response-view` | Mixin applied to the element | `{}` `--no-info-message` | Mixin applied to the information about lack of the response | `{}` Use: `response-status-view`, `response-body-view` and `response-error-view` styles to style this element. @group UI Elements @element response-view @demo demo/index.html --> <dom-module id="response-view"> <template> <style> :host { display: block; @apply(--response-view); } .empty-info { @apply(--no-info-message); } </style> <response-status-view status-code="[[statusCode]]" status-message="[[statusMessage]]" request-headers="[[requestHeaders]]" response-headers="[[responseHeaders]]" loading-time="[[loadingTime]]" http-message="[[sentHttpMessage]]" redirects="[[redirects]]" redirect-timings="[[redirectTimings]]" timings="[[responseTimings]]" is-xhr="[[isXhr]]" request-url="[[requestUrl]]" request-method="[[requestMethod]]"></response-status-view> <template is="dom-if" if="[[hasResponse]]"> <template is="dom-if" if="[[isError]]"> <response-error-view message="[[responseError.message]]"></response-error-view> </template> <template is="dom-if" if="[[hasResponseBody]]"> <response-body-view response-text="[[responseBody]]" content-type="[[contentType]]"></response-body-view> </template> </template> <template is="dom-if" if="[[!hasResponse]]"> <p class="empty-info">This response does not carry a payload.</p> </template> </template> <script> Polymer({ is: 'response-view', properties: { /** * The `Response` object as defined in the Fetch API spec. * * This element will read the response body from it so it need to not * be read before setting this to this element. According to the Fetch * API the response can be read only once. * * The element will set a `responseBody` property which will be a String * of the response. * * This element imports a polyfill for the Fetch API. */ response: { type: Response, observer: '_responseChanged' }, /** * The `Request` object as defined in the Fetch API spec. * This element provides the polyfill for the Fetch API. * * This element will read the request body from it so it need to not * be read before setting this to this element. According to the Fetch * API the body can be read only once. * * Please, use the `Request.clone()` method and set a copy if you need * to read the body elsewhere. */ request: { type: Request, observer: '_requestChanged' }, /** * An Error object associated with the request if the response was errored. * It should have a `message` property set to the human readable explenation of the error. * If not set the default message will be displaed. */ responseError: Object, /** * A response body read from the `resposne` object. * The element will throw an error if the response body was read before * passing it to this element. * * Please, use the `Response.clone()` method and set a copy if you need * to read the body elsewhere. */ responseBody: { type: String, notify: true }, /** * Returned status code. * Ths value will be computed from the `response` when set. */ statusCode: Number, /** * Returned status message (if any). * Ths value will be computed from the `response` when set. */ statusMessage: String, /** * Request headers sent to the server. */ requestHeaders: String, /** * Returned from the server headers. * Ths value will be computed from the `response` when set. */ responseHeaders: String, /** * The response content type header if present */ contentType: String, /** * If available, the request / response timings as defined in HAR 1.2 * spec. * It will be used to calculate the `loadingTime` property. */ responseTimings: Object, /** * The total time of the request / response load. * It will be computed (and overwitted) if the `responseTimings` * object will be set. */ loadingTime: Number, /** * If this information available, the source HTTP message sent to * the remote machine. * `socket-fetch` element sets this additional property on the * response object. */ sentHttpMessage: String, /** * The list of the `Response` objects representing a redirection during * the request. * The list should be ordered list of redirections. */ redirects: Array, /** * If timings stats are available for redirects, the list of the * `timings` object as defined in HAR 1.2 specification. * The list should be ordered list of redirections. */ redirectTimings: Array, /** * Computed value, false if the response is set and it is a HEAD type * request (which can't have the response). */ hasResponse: { type: Boolean, value: false, computed: '_computeHasResponse(request)' }, /** * Computed value, true when the response body has a value. */ hasResponseBody: { type: Boolean, value: false, computed: '_computeHasResponseBody(responseBody)' }, // Computed value, true if the response has error object set. isError: { type: Boolean, value: false, computed: '_computeIsError(responseError)' }, /** * If true it means that the request has been made by the basic * transport and advanced details of the request/response like * redirects, timings, source message are not available. * It this case it will hide unused tabs. */ isXhr: { type: Boolean, value: false }, // A request URL that has been used to make a request requestUrl: String, // A HTTP method used to make a request requestMethod: String }, // resets the initial variables for the Response change handler. _reset: function() { this.set('statusCode', undefined); this.set('statusMessage', undefined); this.set('responseHeaders', undefined); this.set('responseBody', undefined); this.set('contentType', undefined); }, _responseChanged: function(response) { this._reset(); if (!response) { return; } this.set('statusCode', response.status); this.set('statusMessage', response.statusText); var headers = response.headers; var responseHeaders = ''; headers.forEach(function(value, name) { if (responseHeaders) { responseHeaders += '\n'; } responseHeaders += name + ': ' + value; }); this.set('responseHeaders', responseHeaders); var ct = headers.get('content-type'); if (!ct) { ct = 'text/plain'; } var content = this; response.text() .then(function(body) { content.set('responseBody', body); content.set('contentType', ct); }) .catch(function(e) { content.fire('app-log', { level: 'error', message: e }); }); }, _resetRequestData: function() { this.set('requestHeaders', undefined); }, _requestChanged: function(request) { this._resetRequestData(); if (!request) { return; } this.set('requestUrl', request.url); this.set('requestMethod', request.method); var headers = request.headers; var requestHeaders = ''; headers.forEach(function(value, name) { if (requestHeaders) { requestHeaders += '\n'; } requestHeaders += name + ': ' + value; }); this.set('requestHeaders', requestHeaders); }, // Computes if the response panel should be displayed. _computeHasResponse: function(request) { if (request && request.method === 'HEAD') { return false; } return true; }, _computeHasResponseBody: function(body) { return !!body; }, // Computes if the request object has an error _computeIsError: function(error) { return !!error; } }); </script> </dom-module>