Chromium Code Reviews| Index: server/static/rpcexplorer/rpc-call.html |
| diff --git a/server/static/rpcexplorer/rpc-call.html b/server/static/rpcexplorer/rpc-call.html |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..4cece5f580753ee63262cef3649afe3636b5e1e4 |
| --- /dev/null |
| +++ b/server/static/rpcexplorer/rpc-call.html |
| @@ -0,0 +1,278 @@ |
| +<!-- |
| + ~ // Copyright 2016 The Chromium Authors. All rights reserved. |
| + ~ // Use of this source code is governed by a BSD-style license that can be |
| + ~ // found in the LICENSE file. |
| + ~ |
| + --> |
| + |
| +<link rel="import" href="/static/common/third_party/iron-ajax/iron-ajax.html"> |
| +<link rel="import" href="/static/common/third_party/polymer/polymer.html"> |
| + |
| +<link rel="import" href="rpc-codes.html"> |
| +<link rel="import" href="rpc-error.html"> |
| + |
| +<!-- The `rpc-call` element can send a pRPC request. |
| +pRPC protocol: https://godoc.org/github.com/luci/luci-go/common/prpc#hdr-Protocol. |
| +--> |
| +<dom-module id="rpc-call"> |
| + <template> |
| + <iron-ajax |
| + id="ajax" |
| + auto="[[auto]]" |
| + method="POST" url="[[_url]]" |
|
Bons
2016/02/13 17:18:23
place each attribute on it's own line. makes it ea
nodir
2016/02/17 02:02:12
Done.
|
| + body="[[request]]" content-type="application/json" |
| + debounce-duration="[[debounceDuration]]" |
| + timeout="[[timeout]]" |
| + verbose="[[verbose]]" |
| + handle-as="json" json-prefix=")]}'" |
|
Bons
2016/02/13 17:18:25
json is already the default for iron-ajax: https:/
nodir
2016/02/17 02:02:12
Done.
|
| + on-request="_onRequest" |
| + on-loading-changed="_loadingChanged" |
| + on-response="_onResponse" |
| + on-error="_onError" |
| + ></iron-ajax> |
| + </template> |
| + <script> |
| + 'use strict'; |
| + |
| + Polymer({ |
| + is: 'rpc-call', |
|
Bons
2016/02/13 17:18:22
blank lines between top-level properties.
Polymer
nodir
2016/02/17 02:02:12
Done.
|
| + properties: { |
| + /** |
| + * if true, use HTTP instead of HTTPS. |
| + * If null (default) or undefined, determined automatically: |
| + * - if host equals current host and current protocol is http, then |
| + * false |
|
Bons
2016/02/13 17:18:24
this will fit on the previous line. also full sent
nodir
2016/02/17 02:02:12
does not fit with "then"
Bons
2016/02/17 19:27:47
Still needs to be a full sentence.
|
| + * - otherwise true. |
| + */ |
| + insecure: { |
|
Bons
2016/02/13 17:18:25
the property already has a default value of undefi
nodir
2016/02/17 02:02:12
weirdly enough, if I replace it with `insecure: Bo
Bons
2016/02/17 19:27:47
That’s because it is then `undefined` and observer
|
| + type: Boolean, |
| + value: null |
| + }, |
| + |
| + /** |
| + * pRPC server host, defaults to current document host. |
| + */ |
| + host: { |
| + type: String, |
| + value: document.location.host, |
| + }, |
| + |
| + /** |
| + * Full service name, including package name. |
| + */ |
| + service: String, |
| + |
| + /** |
| + * Service method name. |
| + */ |
| + method: String, |
| + |
| + _url: { |
|
Bons
2016/02/13 17:18:25
place private properties below public ones to main
nodir
2016/02/17 02:02:12
Done.
|
| + type: String, |
| + computed: '_generateUrl(insecure, host, service, method)' |
| + }, |
| + |
| + /** |
| + * Request object. |
| + */ |
| + request: { |
| + type: Object, |
| + value: function() { |
| + return {}; |
| + } |
| + }, |
| + |
| + /** |
| + * Request timeout in milliseconds. |
| + */ |
| + timeout: { |
| + type: Number, |
| + value: 0, |
| + observer: '_onTimeoutChanged' |
| + }, |
| + |
| + /** |
| + * If true, automatically sends a request when host, service, method |
| + * or request changes. |
| + */ |
| + auto: { |
| + type: Boolean, |
| + value: false |
| + }, |
| + |
| + /** |
| + * If true, error messages will automatically be logged to the console. |
| + */ |
| + verbose: { |
| + type: Boolean, |
| + value: false |
| + }, |
| + |
| + /** |
| + * The most recent request made by this element. |
| + */ |
| + lastRequest: { |
| + type: Object, |
| + notify: true, |
| + readOnly: true |
| + }, |
| + |
| + /** |
| + * True while lastRequest is in flight. |
| + */ |
| + loading: { |
| + type: Boolean, |
| + notify: true, |
| + readOnly: true |
| + }, |
| + |
| + /** |
| + * lastRequest's response. |
| + * |
| + * Note that lastResponse and lastError are set when |
| + * lastRequest finishes, so if loading is true, lastResponse and lastError |
|
Bons
2016/02/13 17:18:24
> 80 chars.
nodir
2016/02/17 02:02:12
Done.
|
| + * will correspond to the result of the previous request. |
| + */ |
| + lastResponse: { |
| + type: Object, |
| + notify: true, |
| + readOnly: true |
| + }, |
| + |
| + /** |
| + * lastRequest's error, if any. |
| + * May be an instance of rpcExplorer.GrpcError which has response code |
| + * and description. |
| + */ |
| + lastError: { |
| + type: Object, |
| + notify: true, |
| + readOnly: true |
| + }, |
| + |
| + /** |
| + * Length of time in milliseconds to debounce multiple automatically |
| + * generated requests. |
| + */ |
| + debounceDuration: { |
| + type: Number, |
| + value: 0, |
| + notify: true |
| + } |
| + }, |
| + |
| + _loadingChanged: function() { |
| + this._setLoading(this.$.ajax.loading); |
|
Bons
2016/02/13 17:18:23
why not bind to iron-ajax's loading property? http
nodir
2016/02/17 02:02:12
two-way data-binding does not work with read-only
Bons
2016/02/17 19:27:47
in that case, instead of querying for the element,
|
| + }, |
| + |
| + _onTimeoutChanged: function(val) { |
| + var headers = this.$.ajax.requestHeaders; |
| + if (val) { |
| + headers['X-Prpc-Timeout'] = val + 'm'; |
| + } else { |
| + delete headers['X-Prpc-Timeout'] |
| + } |
| + }, |
| + |
| + _generateUrl: function(insecure, host, service, method) { |
| + if (!host || !service || !method) { |
| + return ''; |
| + } |
| + |
| + var protocol; |
| + switch (insecure) { |
|
Bons
2016/02/13 17:18:23
i think this block would read better as a set of i
nodir
2016/02/17 02:02:12
simplified a bit, but I am not sure how to be less
|
| + case true: |
| + protocol = 'http:'; |
| + break; |
| + case undefined: |
| + case null: |
| + if (host == document.location.host) { |
| + protocol = document.location.protocol; |
| + break; |
| + } |
| + default: |
| + protocol = 'https:'; |
| + } |
| + |
| + return protocol + '//' + host + '/prpc/' + service + '/' + method; |
| + }, |
| + |
| + send: function() { |
| + if (!this.$.ajax.url) { |
| + throw new Error('rpc-call is in invalid state'); |
|
Bons
2016/02/13 17:18:25
"new" isn't required.
throw Error(...)
nodir
2016/02/17 02:02:12
Done.
|
| + } |
| + return this.$.ajax.generateRequest(); |
| + }, |
| + |
| + _onRequest: function() { |
| + this._setLastRequest(this.request); |
| + var e = { |
| + host: this.host, |
| + service: this.service, |
| + method: this.method, |
| + request: this.request |
| + }; |
| + this.fire('request', e, {bubbles: false}); |
| + }, |
| + _onError: function(e) { |
|
Bons
2016/02/13 17:18:25
put a blank line between top-level function declar
nodir
2016/02/17 02:02:12
Done.
|
| + this._done(e.detail.request.xhr); |
| + }, |
| + _onResponse: function(e) { |
| + this._done(e.detail.xhr); |
| + }, |
| + _done: function(xhr) { |
| + var ajax = this.$.ajax; |
| + |
| + function parseResponse() { |
| + if (ajax.lastError && typeof xhr.status !== 'number') { |
|
Bons
2016/02/13 17:18:25
you mix strict equality in with non strict. I woul
nodir
2016/02/17 02:02:12
I've updated code to use only ===, except for case
|
| + // Response was not received. |
| + return { |
| + error: ajax.lastError |
| + }; |
| + } |
| + |
| + var codeHeader = xhr.getResponseHeader('X-Prpc-Grpc-Code'); |
| + if (!codeHeader) { |
| + return { |
| + error: new Error( |
| + 'Invalid response: no X-Prpc-Grpc-Code response header') |
| + }; |
| + } |
| + |
| + var code; |
| + try { |
| + code = parseInt(codeHeader, 10); |
| + if (code == null) { |
| + throw new Error('code is not defined'); |
|
Bons
2016/02/13 17:18:25
throw Error
nodir
2016/02/17 02:02:12
Done.
|
| + } |
| + } catch (e) { |
| + return { |
| + error: new Error( |
| + 'Invalid X-Prpc-Grpc-Code response header "' + codeHeader + |
| + '": ' + e |
| + ) |
| + }; |
| + } |
| + |
| + if (code !== rpcExplorer.Codes.OK) { |
| + return { |
| + error: new rpcExplorer.GrpcError(code, xhr.responseText) |
| + }; |
| + } |
| + return { |
| + response: ajax.lastResponse |
| + }; |
| + } |
| + |
| + var result = parseResponse(); |
| + result.response = result.response || null; |
| + result.error = result.error || null; |
| + |
| + this._setLastResponse(result.response); |
| + this._setLastError(result.error); |
| + |
| + this.fire('response', result, {bubbles: false}); |
| + } |
| + }); |
| + </script> |
| +</dom-module> |