/* global window */
import createComponentClass from '../factory.js';
const
XMLHttpRequest = window.XMLHttpRequest;
export default createComponentClass(/** @lends platypus.components.XHR.prototype */{
id: 'XHR',
properties: {
/**
* Sets the XHR method to use.
*
* @property method
* @type String
* @default "GET"
*/
method: "GET",
/**
* Sets the path to connect to the server.
*
* @property path
* @type String
* @default ""
*/
path: "",
/**
* Sets the XHR response type.
*
* @property responseType
* @type String
* @default "text"
*/
responseType: "text",
/**
* Whether cookies should be retained on cross-domain calls.
*
* @property withCredentials
* @type boolean
* @default false
*/
withCredentials: false
},
/**
* This component provides component-based XHR communication with a server.
*
* @memberof platypus.components
* @uses platypus.Component
* @constructs
* @param {*} definition
* @listens platypus.Entity#request
* @fires platypus.Entity#response
*/
initialize: function (definition) {
this.setProperties(definition);
},
events: {// These are messages that this component listens for
/**
* On receiving this message, this component makes a request from the server using the provided information. Note that properties set here will reset the properties set by this component's JSON definition.
*
* @event platypus.Entity#request
* @property {Object} message
* @property {String} message.method XHR method to use: must be "GET" or "POST".
* @property {String} message.path The path to the server resource.
* @property {String} [message.responseType="text"] Response type expected.
* @property {Object} [message.data] An object of string key/value pairs to be transmitted to the server.
* @property {Function} message.onload A function that should be run on receiving a response from the server. This defaults to triggering a "response" message containing the responseText value.
*/
"request": function (resp) {
this.setProperties(resp);
if (this.method === "GET") {
this.get();
} else if (this.method === "POST") {
this.post();
} else {
throw "Method must be GET or POST";
}
}
},
methods: {// These are methods that are called on the component
setProperties: function (properties) {
var key = '',
divider = '',
props = properties || this;
this.method = props.method || this.method || "GET";
this.path = props.path || this.path || null;
this.responseType = props.responseType || this.responseType || "text";
this.withCredentials = props.withCredentials || this.withCredentials || false;
if ((props !== this) && props.data) {
this.data = '';
for (key in props.data) {
if (props.data.hasOwnProperty(key)) {
this.data += divider + key + '=' + props.data[key];
divider = '&';
}
}
} else {
this.data = '';
}
this.onload = props.onload || this.onload || function () {
if (this.status === 200) {
/**
* This message is triggered on receiving a response from the server (if "onload" is not set by the original "request" message).
*
* @event platypus.Entity#response
* @param message {String} The message contains the responseText returned by the server.
*/
this.owner.triggerEvent('response', this.responseText);
}
}.bind(this);
},
get: function () {
var xhr = new XMLHttpRequest(),
path = this.path;
if (this.data) {
path += '?' + this.data;
}
xhr.open(this.method, path, true);
xhr.withCredentials = this.withCredentials;
xhr.responseType = this.responseType;
xhr.onload = this.onload;
xhr.send();
},
post: function () {
var xhr = new XMLHttpRequest();
xhr.open(this.method, this.path, true);
xhr.withCredentials = this.withCredentials;
xhr.responseType = this.responseType;
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.onload = this.onload;
xhr.send(this.data);
}
}
});