-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcachable-ajax.html
170 lines (144 loc) · 5.46 KB
/
cachable-ajax.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../core-ajax/core-ajax.html">
<link rel="import" href="../core-localstorage/core-localstorage.html">
<script src="../js-md5/js/md5.min.js"></script>
<script src="../es6-promise-polyfill/promise.min.js"></script>
<!--
This element extends core-ajax element. It exposes the same API (docs: https://www.polymer-project.org/docs/elements/core-elements.html#core-ajax).
A connection point between core-ajax component and core-localstorage, where
the content downloaded from the server, can be cached on the localstorage, if that is the wish of the user.
This element extends the core-ajax element exposing the same interface (events and attributes).
Value is cached in the local storage as the MD5 hash from the xhrArgs object (request object).
If some value is found in cache, it is returned to through the core-response event. The detail.response
property will contain the object returned from cache. It is the same property as in case of
core-ajax and it's usual response.
If user will start the ajax request for the first time, he/she should get just one callback of
core-response handler. On any consecutive same ajax request, data will be taken from cache,
before returning the value from server (core-response event callback will fire twice).
##### Example
<cachable-ajax
auto
url="http://gdata.youtube.com/feeds/api/videos/"
params='{"alt":"json", "q":"chrome"}'
handleAs="json"
on-core-response="{{handleResponse}}"
cacheResponse="true"
cacheTTL="3600"
key="localStorageKey"></cachable-ajax>
@element cachable-ajax
@blurb A connection point between core-ajax component and core-localstorage.
@homepage http://domderen.github.io/cachable-ajax
-->
<polymer-element name="cachable-ajax" hidden extends="core-ajax" attributes="cacheResponse">
<script>
(function () {
var store = document.createElement('core-localstorage');
var self;
var resolveRequestPromise;
var rejectRequestPromise;
Polymer({
/**
* Fired when a response is received. In cached content is found, this event will be fired twice.
*
* @event cachable-response
*/
/**
* Fired when an error is received.
*
* @event core-error
*/
/**
* Fired whenever a response or an error is received.
*
* @event core-complete
*/
/**
* `cacheResponse` is a property defining if the ajax response should be cached using the local storage.
*
* @property cacheResponse
* @type bool
* @default true
*/
cacheResponse: true,
/**
* `cacheTTL` is a property defining after how many seconds the cache entry should be invalidated.
*
* @property cacheTTL
* @type int
* @default Number.MAX_VALUE
*/
cacheTTL: Number.MAX_VALUE,
/**
* `storageKey` is a property defining the key to use in communication with local storage.
* If the value is falsy, storage key will be generated based on the request parameters.
*
* @property storageKey
* @type string
* @default undefined
*/
storageKey: undefined,
ready: function () {
self = this;
self.super();
store.useRaw = false;
store.autoSaveDisabled = true;
store.addEventListener('core-localstorage-load', function () {
if (store.value.expire > Date.now()) {
self.fire('core-response', {
response: store.value.data
});
}
});
},
/**
* Performs an Ajax request to the specified URL. If cacheResponse is set to true,
* it also tries to load the value for this request from the localstorage.
*
* @method go
* @returns (Promise) A promise object that will be resolved with the server response.
*/
go: function () {
return new Promise(function (resolve, reject) {
resolveRequestPromise = resolve;
rejectRequestPromise = reject;
var key;
self.xhrArgs = self.xhrArgs || {};
//TODO: This looks like an unnecessary dirty hack. Is that necessary?
// This is equivalent with 'this.super()', but for some reason, the proper version
// does not want to work here. Probably some internal Polymer issue?
self.__proto__.__proto__.go.call(self);
// https://github.com/Polymer/polymer/issues/898
if (self.cacheResponse) {
if (self.storageKey) {
key = self.storageKey;
} else {
key = md5(self.args);
}
store.name = key;
store.load();
}
});
},
processError: function (xhr) {
self.super([xhr]);
if(rejectRequestPromise) {
rejectRequestPromise(self.error);
}
},
processResponse: function (xhr) {
self.super([xhr]);
if (self.cacheResponse && store.name) {
store.value = {
expire: Date.now() + self.cacheTTL,
data: self.response
};
store.save();
}
if(resolveRequestPromise) {
resolveRequestPromise(self.response);
}
}
});
})();
</script>
</polymer-element>