Remove LOAD_SUB_FRAME load flag.
[chromium-blink-merge.git] / third_party / polymer / components / core-ajax / core-ajax.html
blobc0ca0adbc25f5919da4c0f25131b4a5e5ed1f01f
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.github.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/CONTRIBUTORS.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/PATENTS.txt
8 -->
10 <!--
11 @group Polymer Core Elements
13 The `core-ajax` element exposes `XMLHttpRequest` functionality.
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>
22 With `auto` set to `true`, the element performs a request whenever
23 its `url`, `params` or `body` properties are changed.
25 Note: The `params` attribute must be double quoted JSON.
27 You can trigger a request explicitly by calling `go` on the
28 element.
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 response error method headers body contentType withCredentials progress loading">
36 <script>
38 Polymer('core-ajax', {
39 /**
40 * Fired when a response is received.
42 * @event core-response
45 /**
46 * Fired when an error is received.
48 * @event core-error
51 /**
52 * Fired whenever a response or an error is received.
54 * @event core-complete
57 /**
58 * The URL target of the request.
60 * @attribute url
61 * @type string
62 * @default ''
64 url: '',
66 /**
67 * Specifies what data to store in the `response` property, and
68 * to deliver as `event.response` in `response` events.
70 * One of:
72 * `text`: uses `XHR.responseText`.
74 * `xml`: uses `XHR.responseXML`.
76 * `json`: uses `XHR.responseText` parsed as JSON.
78 * `arraybuffer`: uses `XHR.response`.
80 * `blob`: uses `XHR.response`.
82 * `document`: uses `XHR.response`.
84 * @attribute handleAs
85 * @type string
86 * @default 'text'
88 handleAs: '',
90 /**
91 * If true, automatically performs an Ajax request when either `url` or `params` changes.
93 * @attribute auto
94 * @type boolean
95 * @default false
97 auto: false,
99 /**
100 * Parameters to send to the specified URL, as JSON.
102 * @attribute params
103 * @type string (JSON)
104 * @default ''
106 params: '',
109 * The response for the current request, or null if it hasn't
110 * completed yet or the request resulted in error.
112 * @attribute response
113 * @type Object
114 * @default null
116 response: null,
119 * The error for the current request, or null if it hasn't
120 * completed yet or the request resulted in success.
122 * @attribute error
123 * @type Object
124 * @default null
126 error: null,
129 * Whether the current request is currently loading.
131 * @attribute loading
132 * @type boolean
133 * @default false
135 loading: false,
138 * The progress of the current request.
140 * @attribute progress
141 * @type {loaded: number, total: number, lengthComputable: boolean}
142 * @default {}
144 progress: null,
147 * The HTTP method to use such as 'GET', 'POST', 'PUT', or 'DELETE'.
148 * Default is 'GET'.
150 * @attribute method
151 * @type string
152 * @default ''
154 method: '',
157 * HTTP request headers to send.
159 * Example:
161 * <core-ajax
162 * auto
163 * url="http://somesite.com"
164 * headers='{"X-Requested-With": "XMLHttpRequest"}'
165 * handleAs="json"
166 * on-core-response="{{handleResponse}}"></core-ajax>
168 * @attribute headers
169 * @type Object
170 * @default null
172 headers: null,
175 * Optional raw body content to send when method === "POST".
177 * Example:
179 * <core-ajax method="POST" auto url="http://somesite.com"
180 * body='{"foo":1, "bar":2}'>
181 * </core-ajax>
183 * @attribute body
184 * @type Object
185 * @default null
187 body: null,
190 * Content type to use when sending data.
192 * @attribute contentType
193 * @type string
194 * @default 'application/x-www-form-urlencoded'
196 contentType: 'application/x-www-form-urlencoded',
199 * Set the withCredentials flag on the request.
201 * @attribute withCredentials
202 * @type boolean
203 * @default false
205 withCredentials: false,
208 * Additional properties to send to core-xhr.
210 * Can be set to an object containing default properties
211 * to send as arguments to the `core-xhr.request()` method
212 * which implements the low-level communication.
214 * @property xhrArgs
215 * @type Object
216 * @default null
218 xhrArgs: null,
220 created: function() {
221 this.progress = {};
224 ready: function() {
225 this.xhr = document.createElement('core-xhr');
228 receive: function(response, xhr) {
229 if (this.isSuccess(xhr)) {
230 this.processResponse(xhr);
231 } else {
232 this.processError(xhr);
234 this.complete(xhr);
237 isSuccess: function(xhr) {
238 var status = xhr.status || 0;
239 return !status || (status >= 200 && status < 300);
242 processResponse: function(xhr) {
243 var response = this.evalResponse(xhr);
244 if (xhr === this.activeRequest) {
245 this.response = response;
247 this.fire('core-response', {response: response, xhr: xhr});
250 processError: function(xhr) {
251 var response = xhr.status + ': ' + xhr.responseText;
252 if (xhr === this.activeRequest) {
253 this.error = response;
255 this.fire('core-error', {response: response, xhr: xhr});
258 processProgress: function(progress, xhr) {
259 if (xhr !== this.activeRequest) {
260 return;
262 // We create a proxy object here because these fields
263 // on the progress event are readonly properties, which
264 // causes problems in common use cases (e.g. binding to
265 // <paper-progress> attributes).
266 var progressProxy = {
267 lengthComputable: progress.lengthComputable,
268 loaded: progress.loaded,
269 total: progress.total
271 this.progress = progressProxy;
274 complete: function(xhr) {
275 if (xhr === this.activeRequest) {
276 this.loading = false;
278 this.fire('core-complete', {response: xhr.status, xhr: xhr});
281 evalResponse: function(xhr) {
282 return this[(this.handleAs || 'text') + 'Handler'](xhr);
285 xmlHandler: function(xhr) {
286 return xhr.responseXML;
289 textHandler: function(xhr) {
290 return xhr.responseText;
293 jsonHandler: function(xhr) {
294 var r = xhr.responseText;
295 try {
296 return JSON.parse(r);
297 } catch (x) {
298 console.warn('core-ajax caught an exception trying to parse response as JSON:');
299 console.warn('url:', this.url);
300 console.warn(x);
301 return r;
305 documentHandler: function(xhr) {
306 return xhr.response;
309 blobHandler: function(xhr) {
310 return xhr.response;
313 arraybufferHandler: function(xhr) {
314 return xhr.response;
317 urlChanged: function() {
318 if (!this.handleAs) {
319 var ext = String(this.url).split('.').pop();
320 switch (ext) {
321 case 'json':
322 this.handleAs = 'json';
323 break;
326 this.autoGo();
329 paramsChanged: function() {
330 this.autoGo();
333 bodyChanged: function() {
334 this.autoGo();
337 autoChanged: function() {
338 this.autoGo();
341 // TODO(sorvell): multiple side-effects could call autoGo
342 // during one micro-task, use a job to have only one action
343 // occur
344 autoGo: function() {
345 if (this.auto) {
346 this.goJob = this.job(this.goJob, this.go, 0);
351 * Performs an Ajax request to the specified URL.
353 * @method go
355 go: function() {
356 var args = this.xhrArgs || {};
357 // TODO(sjmiles): we may want XHR to default to POST if body is set
358 args.body = this.body || args.body;
359 args.params = this.params || args.params;
360 if (args.params && typeof(args.params) == 'string') {
361 args.params = JSON.parse(args.params);
363 args.headers = this.headers || args.headers || {};
364 if (args.headers && typeof(args.headers) == 'string') {
365 args.headers = JSON.parse(args.headers);
367 var hasContentType = Object.keys(args.headers).some(function (header) {
368 return header.toLowerCase() === 'content-type';
370 // No Content-Type should be specified if sending `FormData`.
371 // The UA must set the Content-Type w/ a calculated multipart boundary ID.
372 if (args.body instanceof FormData) {
373 delete args.headers['Content-Type'];
375 else if (!hasContentType && this.contentType) {
376 args.headers['Content-Type'] = this.contentType;
378 if (this.handleAs === 'arraybuffer' || this.handleAs === 'blob' ||
379 this.handleAs === 'document') {
380 args.responseType = this.handleAs;
382 args.withCredentials = this.withCredentials;
383 args.callback = this.receive.bind(this);
384 args.url = this.url;
385 args.method = this.method;
387 this.response = this.error = this.progress = null;
388 this.activeRequest = args.url && this.xhr.request(args);
389 if (this.activeRequest) {
390 this.loading = true;
391 var activeRequest = this.activeRequest;
392 // IE < 10 doesn't support progress events.
393 if ('onprogress' in activeRequest) {
394 this.activeRequest.addEventListener(
395 'progress',
396 function(progress) {
397 this.processProgress(progress, activeRequest);
398 }.bind(this), false);
399 } else {
400 this.progress = {
401 lengthComputable: false,
405 return this.activeRequest;
410 </script>
411 </polymer-element>