| OLD | NEW |
| (Empty) | |
| 1 <!-- |
| 2 Copyright 2017 The LUCI Authors. All rights reserved. |
| 3 Use of this source code is governed under the Apache License, Version 2.0 |
| 4 that can be found in the LICENSE file. |
| 5 |
| 6 It contains the definition of the following Behaviors: |
| 7 |
| 8 IsolateBehaviors.CommonBehavior |
| 9 |
| 10 To use it, include |
| 11 behaviors: [IsolateBehaviors.CommonBehavior] |
| 12 in the creation of any Polymer element. |
| 13 |
| 14 IsolateBehaviors.CommonBehavior contains shared methods to ease |
| 15 templating, such as _or() and _not() as well as general utility methods |
| 16 such as _getJsonAsync. |
| 17 --> |
| 18 |
| 19 <script> |
| 20 window.IsolateBehaviors = window.IsolateBehaviors || {}; |
| 21 (function(){ |
| 22 // This behavior wraps up all the shared isolate functionality. |
| 23 IsolateBehaviors.CommonBehavior = { |
| 24 |
| 25 // _getJsonAsync makes an XHR to a url, parses the response as JSON |
| 26 // and sticks the resulting object into the property with the name given |
| 27 // by "bindTo". If busy is defined, the property with that name will be |
| 28 // set to true while the request is in flight and false afterwards. |
| 29 // request headers (e.g. authentication) and query params will be used if |
| 30 // provided. Query params is an object like {String:Array<String>}. On |
| 31 // error, bindTo will be set to false and the promise will be rejected |
| 32 // with {status:Number, reason:String} where the reason is the text |
| 33 // returned from the server. |
| 34 // The object bindTo is not set to undefined because computed values in |
| 35 // Polymer don't fire if a property is undefined. Clients should check |
| 36 // that bindTo is not falsey. |
| 37 // To avoid multiple requests clobering one another, an object _jsonAsync |
| 38 // is created on "this" to debounce requests - the most recent request |
| 39 // will win out. |
| 40 _getJsonAsync: function(bindTo, url, busy, headers, params) { |
| 41 if (!bindTo || !url || !busy) { |
| 42 console.log("Need at least a polymer element to bind to, a busy elemen
t, and a url"); |
| 43 return; |
| 44 } |
| 45 this.set(busy, true); |
| 46 var now = new Date(); |
| 47 this._jsonAsync = this._jsonAsync || {}; |
| 48 this._jsonAsync[bindTo] = now; |
| 49 if (params) { |
| 50 url = url + "?" + sk.query.fromParamSet(params); |
| 51 } |
| 52 return sk.request("GET", url, "", headers).then(JSON.parse).then(functio
n(json){ |
| 53 if (this._jsonAsync[bindTo] !== now) { |
| 54 console.log("ignoring result because a second request happened."); |
| 55 this.set(busy, false); |
| 56 return; |
| 57 } |
| 58 this.set(bindTo, json); |
| 59 this.set(busy, false); |
| 60 }.bind(this)).catch(function(reason){ |
| 61 console.log("Reason for failure of request to " + url, reason); |
| 62 |
| 63 if (this._jsonAsync[bindTo] !== now) { |
| 64 console.log("ignoring failure because a second request happened."); |
| 65 this.set(busy, false); |
| 66 return; |
| 67 } |
| 68 this.set(bindTo, false); |
| 69 this.set(busy, false); |
| 70 return Promise.reject(reason); |
| 71 }.bind(this)); |
| 72 }, |
| 73 |
| 74 // _getJsonAsyncArr is the array analog to _getJsonAsync. For example, |
| 75 // if there is an array that will contain multiple results rendered with |
| 76 // a dom-repeat, _getJsonAsyncArr will make an XHR GET request and put |
| 77 // the results into the given array at the index specified by idx. |
| 78 // |
| 79 // Prior to making this call, it is assumed that arr is initialized to be |
| 80 // an array of empty (or filler) objects. busyArr be initialized in the |
| 81 // same way. Due to how Polymer deals with arrays, arrays of primitives |
| 82 // are not supported, thus clients observing busyArr should iterate over |
| 83 // all objects in busyArr and test to see if busyArr[i].status is true. |
| 84 // |
| 85 // To avoid multiple requests clobering one another, an object _jsonAsync |
| 86 // is created on "this" to debounce requests - the most recent request |
| 87 // will win out. |
| 88 _getJsonAsyncArr: function(idx, arr, url, busyArr, headers, params) { |
| 89 if (!arr || !url || !busyArr) { |
| 90 console.log("Need at least a polymer array to bind to, a busy element,
and a url"); |
| 91 return; |
| 92 } |
| 93 var key = arr + ":" + idx; |
| 94 this.splice(busyArr, idx, 1, {status:true}); |
| 95 var now = new Date(); |
| 96 this._jsonAsync = this._jsonAsync || {}; |
| 97 this._jsonAsync[key] = now; |
| 98 if (params) { |
| 99 url = url + "?" + sk.query.fromParamSet(params); |
| 100 } |
| 101 return sk.request("GET", url, "", headers).then(JSON.parse).then(functio
n(json){ |
| 102 if (this._jsonAsync[key] !== now) { |
| 103 console.log("ignoring result because a second request happened for "
, key); |
| 104 this.splice(busyArr, idx, 1, {status:false}); |
| 105 return; |
| 106 } |
| 107 this.splice(arr, idx, 1, json); |
| 108 this.splice(busyArr, idx, 1, {status:false}); |
| 109 }.bind(this)).catch(function(reason){ |
| 110 console.log("Reason for failure of request to " + url, reason); |
| 111 |
| 112 if (this._jsonAsync[key] !== now) { |
| 113 console.log("ignoring failure because a second request happened."); |
| 114 this.splice(busyArr, idx, 1, {status:false}); |
| 115 return; |
| 116 } |
| 117 this.splice(busyArr, idx, 1, {status:false}); |
| 118 return Promise.reject(reason); |
| 119 }.bind(this)); |
| 120 }, |
| 121 |
| 122 _not: function(a) { |
| 123 return !a; |
| 124 }, |
| 125 |
| 126 _or: function() { |
| 127 var result = false; |
| 128 // can't use .foreach, as arguments isn't really an Array. |
| 129 for (var i = 0; i < arguments.length; i++) { |
| 130 result = result || arguments[i]; |
| 131 } |
| 132 return result; |
| 133 }, |
| 134 |
| 135 _truthy: function(a){ |
| 136 return !!a; |
| 137 } |
| 138 }; |
| 139 })(); |
| 140 </script> |
| OLD | NEW |