OLD | NEW |
| (Empty) |
1 <!-- | |
2 Copyright (c) 2014 The Polymer Project Authors. All rights reserved. | |
3 This code may only be used under the BSD style license found at http://polymer.g
ithub.io/LICENSE.txt | |
4 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt | |
5 The complete set of contributors may be found at http://polymer.github.io/CONTRI
BUTORS.txt | |
6 Code distributed by Google as part of the polymer project is also | |
7 subject to an additional IP rights grant found at http://polymer.github.io/PATEN
TS.txt | |
8 --> | |
9 | |
10 <!-- | |
11 @group Polymer Core Elements | |
12 | |
13 The `core-ajax` element exposes `XMLHttpRequest` functionality. | |
14 | |
15 <core-ajax | |
16 auto | |
17 url="http://gdata.youtube.com/feeds/api/videos/" | |
18 params='{"alt":"json", "q":"chrome"}' | |
19 handleAs="json" | |
20 on-core-response="{{handleResponse}}"></core-ajax> | |
21 | |
22 With `auto` set to `true`, the element performs a request whenever | |
23 its `url` or `params` properties are changed. | |
24 | |
25 Note: The `params` attribute must be double quoted JSON. | |
26 | |
27 You can trigger a request explicitly by calling `go` on the | |
28 element. | |
29 | |
30 @element core-ajax | |
31 @status beta | |
32 @homepage github.io | |
33 --> | |
34 <link rel="import" href="core-xhr.html"> | |
35 <polymer-element name="core-ajax" hidden attributes="url handleAs auto params re
sponse method headers body contentType withCredentials"> | |
36 <script> | |
37 | |
38 Polymer('core-ajax', { | |
39 /** | |
40 * Fired when a response is received. | |
41 * | |
42 * @event core-response | |
43 */ | |
44 | |
45 /** | |
46 * Fired when an error is received. | |
47 * | |
48 * @event core-error | |
49 */ | |
50 | |
51 /** | |
52 * Fired whenever a response or an error is received. | |
53 * | |
54 * @event core-complete | |
55 */ | |
56 | |
57 /** | |
58 * The URL target of the request. | |
59 * | |
60 * @attribute url | |
61 * @type string | |
62 * @default '' | |
63 */ | |
64 url: '', | |
65 | |
66 /** | |
67 * Specifies what data to store in the `response` property, and | |
68 * to deliver as `event.response` in `response` events. | |
69 * | |
70 * One of: | |
71 * | |
72 * `text`: uses `XHR.responseText`. | |
73 * | |
74 * `xml`: uses `XHR.responseXML`. | |
75 * | |
76 * `json`: uses `XHR.responseText` parsed as JSON. | |
77 * | |
78 * `arraybuffer`: uses `XHR.response`. | |
79 * | |
80 * `blob`: uses `XHR.response`. | |
81 * | |
82 * `document`: uses `XHR.response`. | |
83 * | |
84 * @attribute handleAs | |
85 * @type string | |
86 * @default 'text' | |
87 */ | |
88 handleAs: '', | |
89 | |
90 /** | |
91 * If true, automatically performs an Ajax request when either `url` or `par
ams` changes. | |
92 * | |
93 * @attribute auto | |
94 * @type boolean | |
95 * @default false | |
96 */ | |
97 auto: false, | |
98 | |
99 /** | |
100 * Parameters to send to the specified URL, as JSON. | |
101 * | |
102 * @attribute params | |
103 * @type string (JSON) | |
104 * @default '' | |
105 */ | |
106 params: '', | |
107 | |
108 /** | |
109 * Returns the response object. | |
110 * | |
111 * @attribute response | |
112 * @type Object | |
113 * @default null | |
114 */ | |
115 response: null, | |
116 | |
117 /** | |
118 * The HTTP method to use such as 'GET', 'POST', 'PUT', or 'DELETE'. | |
119 * Default is 'GET'. | |
120 * | |
121 * @attribute method | |
122 * @type string | |
123 * @default '' | |
124 */ | |
125 method: '', | |
126 | |
127 /** | |
128 * HTTP request headers to send. | |
129 * | |
130 * Example: | |
131 * | |
132 * <core-ajax | |
133 * auto | |
134 * url="http://somesite.com" | |
135 * headers='{"X-Requested-With": "XMLHttpRequest"}' | |
136 * handleAs="json" | |
137 * on-core-response="{{handleResponse}}"></core-ajax> | |
138 * | |
139 * @attribute headers | |
140 * @type Object | |
141 * @default null | |
142 */ | |
143 headers: null, | |
144 | |
145 /** | |
146 * Optional raw body content to send when method === "POST". | |
147 * | |
148 * Example: | |
149 * | |
150 * <core-ajax method="POST" auto url="http://somesite.com" | |
151 * body='{"foo":1, "bar":2}'> | |
152 * </core-ajax> | |
153 * | |
154 * @attribute body | |
155 * @type Object | |
156 * @default null | |
157 */ | |
158 body: null, | |
159 | |
160 /** | |
161 * Content type to use when sending data. | |
162 * | |
163 * @attribute contentType | |
164 * @type string | |
165 * @default 'application/x-www-form-urlencoded' | |
166 */ | |
167 contentType: 'application/x-www-form-urlencoded', | |
168 | |
169 /** | |
170 * Set the withCredentials flag on the request. | |
171 * | |
172 * @attribute withCredentials | |
173 * @type boolean | |
174 * @default false | |
175 */ | |
176 withCredentials: false, | |
177 | |
178 /** | |
179 * Additional properties to send to core-xhr. | |
180 * | |
181 * Can be set to an object containing default properties | |
182 * to send as arguments to the `core-xhr.request()` method | |
183 * which implements the low-level communication. | |
184 * | |
185 * @property xhrArgs | |
186 * @type Object | |
187 * @default null | |
188 */ | |
189 xhrArgs: null, | |
190 | |
191 ready: function() { | |
192 this.xhr = document.createElement('core-xhr'); | |
193 }, | |
194 | |
195 receive: function(response, xhr) { | |
196 if (this.isSuccess(xhr)) { | |
197 this.processResponse(xhr); | |
198 } else { | |
199 this.error(xhr); | |
200 } | |
201 this.complete(xhr); | |
202 }, | |
203 | |
204 isSuccess: function(xhr) { | |
205 var status = xhr.status || 0; | |
206 return !status || (status >= 200 && status < 300); | |
207 }, | |
208 | |
209 processResponse: function(xhr) { | |
210 var response = this.evalResponse(xhr); | |
211 this.response = response; | |
212 this.fire('core-response', {response: response, xhr: xhr}); | |
213 }, | |
214 | |
215 error: function(xhr) { | |
216 var response = xhr.status + ': ' + xhr.responseText; | |
217 this.fire('core-error', {response: response, xhr: xhr}); | |
218 }, | |
219 | |
220 complete: function(xhr) { | |
221 this.fire('core-complete', {response: xhr.status, xhr: xhr}); | |
222 }, | |
223 | |
224 evalResponse: function(xhr) { | |
225 return this[(this.handleAs || 'text') + 'Handler'](xhr); | |
226 }, | |
227 | |
228 xmlHandler: function(xhr) { | |
229 return xhr.responseXML; | |
230 }, | |
231 | |
232 textHandler: function(xhr) { | |
233 return xhr.responseText; | |
234 }, | |
235 | |
236 jsonHandler: function(xhr) { | |
237 var r = xhr.responseText; | |
238 try { | |
239 return JSON.parse(r); | |
240 } catch (x) { | |
241 console.warn('core-ajax caught an exception trying to parse reponse as J
SON:'); | |
242 console.warn('url:', this.url); | |
243 console.warn(x); | |
244 return r; | |
245 } | |
246 }, | |
247 | |
248 documentHandler: function(xhr) { | |
249 return xhr.response; | |
250 }, | |
251 | |
252 blobHandler: function(xhr) { | |
253 return xhr.response; | |
254 }, | |
255 | |
256 arraybufferHandler: function(xhr) { | |
257 return xhr.response; | |
258 }, | |
259 | |
260 urlChanged: function() { | |
261 if (!this.handleAs) { | |
262 var ext = String(this.url).split('.').pop(); | |
263 switch (ext) { | |
264 case 'json': | |
265 this.handleAs = 'json'; | |
266 break; | |
267 } | |
268 } | |
269 this.autoGo(); | |
270 }, | |
271 | |
272 paramsChanged: function() { | |
273 this.autoGo(); | |
274 }, | |
275 | |
276 autoChanged: function() { | |
277 this.autoGo(); | |
278 }, | |
279 | |
280 // TODO(sorvell): multiple side-effects could call autoGo | |
281 // during one micro-task, use a job to have only one action | |
282 // occur | |
283 autoGo: function() { | |
284 if (this.auto) { | |
285 this.goJob = this.job(this.goJob, this.go, 0); | |
286 } | |
287 }, | |
288 | |
289 /** | |
290 * Performs an Ajax request to the specified URL. | |
291 * | |
292 * @method go | |
293 */ | |
294 go: function() { | |
295 var args = this.xhrArgs || {}; | |
296 // TODO(sjmiles): we may want XHR to default to POST if body is set | |
297 args.body = this.body || args.body; | |
298 args.params = this.params || args.params; | |
299 if (args.params && typeof(args.params) == 'string') { | |
300 args.params = JSON.parse(args.params); | |
301 } | |
302 args.headers = this.headers || args.headers || {}; | |
303 if (args.headers && typeof(args.headers) == 'string') { | |
304 args.headers = JSON.parse(args.headers); | |
305 } | |
306 if (this.contentType) { | |
307 args.headers['content-type'] = this.contentType; | |
308 } | |
309 if (this.handleAs === 'arraybuffer' || this.handleAs === 'blob' || | |
310 this.handleAs === 'document') { | |
311 args.responseType = this.handleAs; | |
312 } | |
313 args.withCredentials = this.withCredentials; | |
314 args.callback = this.receive.bind(this); | |
315 args.url = this.url; | |
316 args.method = this.method; | |
317 return args.url && this.xhr.request(args); | |
318 } | |
319 | |
320 }); | |
321 | |
322 </script> | |
323 </polymer-element> | |
OLD | NEW |