diff --git a/README.md b/README.md
index 700916bc..03372e32 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# vue-resource [![npm package](https://img.shields.io/npm/v/vue-resource.svg)](https://www.npmjs.com/package/vue-resource)
+# vue-resource [![Downloads](https://img.shields.io/npm/dt/vue-resource.svg)](https://www.npmjs.com/package/vue-resource) [![Version](https://img.shields.io/npm/v/vue-resource.svg)](https://www.npmjs.com/package/vue-resource) [![License](https://img.shields.io/npm/l/vue-resource.svg)](https://www.npmjs.com/package/vue-resource)
The plugin for [Vue.js](http://vuejs.org) provides services for making web requests and handle responses using a [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) or JSONP.
@@ -7,7 +7,7 @@ The plugin for [Vue.js](http://vuejs.org) provides services for making web reque
- Supports the [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) API and [URI Templates](https://medialize.github.io/URI.js/uri-template.html)
- Supports [interceptors](docs/http.md#interceptors) for request and response
- Supports latest Firefox, Chrome, Safari, Opera and IE9+
-- Compact size 12KB (4.5KB gzipped)
+- Compact size 14KB (5.3KB gzipped)
## Installation
@@ -22,9 +22,21 @@ $ bower install vue-resource
```
### CDN
-Available on [jsdelivr](https://cdn.jsdelivr.net/vue.resource/0.9.3/vue-resource.min.js), [cdnjs](https://cdnjs.com/libraries/vue-resource) or [npmcdn](https://npmcdn.com/vue-resource@0.9.3/dist/vue-resource.min.js).
+Available on [jsdelivr](https://cdn.jsdelivr.net/vue.resource/1.0.0/vue-resource.min.js), [cdnjs](https://cdnjs.com/libraries/vue-resource) or [npmcdn](https://npmcdn.com/vue-resource@1.0.0/dist/vue-resource.min.js).
```html
-
+
+```
+
+## Example
+```js
+{
+ // GET /someUrl
+ this.$http.get('/someUrl').then((response) => {
+ // success callback
+ }, (response) => {
+ // error callback
+ });
+}
```
## Documentation
@@ -33,6 +45,7 @@ Available on [jsdelivr](https://cdn.jsdelivr.net/vue.resource/0.9.3/vue-resource
- [HTTP Requests/Response](docs/http.md)
- [Creating Resources](docs/resource.md)
- [Code Recipes](docs/recipes.md)
+- [API Reference](docs/api.md)
## Changelog
diff --git a/bower.json b/bower.json
index cd073e2c..035cef1f 100644
--- a/bower.json
+++ b/bower.json
@@ -1,10 +1,16 @@
{
"name": "vue-resource",
"main": "dist/vue-resource.js",
- "description": "A web request service for Vue.js",
- "version": "0.9.3",
+ "version": "1.0.0",
+ "description": "The HTTP client for Vue.js",
"homepage": "https://github.com/vuejs/vue-resource",
"license": "MIT",
+ "keywords": [
+ "vue",
+ "xhr",
+ "http",
+ "ajax"
+ ],
"ignore": [
".*",
"build",
diff --git a/dist/vue-resource.common.js b/dist/vue-resource.common.js
index 51e4d79e..97a08f12 100644
--- a/dist/vue-resource.common.js
+++ b/dist/vue-resource.common.js
@@ -1,5 +1,5 @@
/*!
- * vue-resource v0.9.3
+ * vue-resource v1.0.0
* https://github.com/vuejs/vue-resource
* Released under the MIT License.
*/
@@ -7,182 +7,10 @@
'use strict';
/**
- * Promises/A+ polyfill v1.1.4 (https://github.com/bramstein/promis)
+ * Promise adapter.
*/
-var RESOLVED = 0;
-var REJECTED = 1;
-var PENDING = 2;
-
-function Promise$2(executor) {
-
- this.state = PENDING;
- this.value = undefined;
- this.deferred = [];
-
- var promise = this;
-
- try {
- executor(function (x) {
- promise.resolve(x);
- }, function (r) {
- promise.reject(r);
- });
- } catch (e) {
- promise.reject(e);
- }
-}
-
-Promise$2.reject = function (r) {
- return new Promise$2(function (resolve, reject) {
- reject(r);
- });
-};
-
-Promise$2.resolve = function (x) {
- return new Promise$2(function (resolve, reject) {
- resolve(x);
- });
-};
-
-Promise$2.all = function all(iterable) {
- return new Promise$2(function (resolve, reject) {
- var count = 0,
- result = [];
-
- if (iterable.length === 0) {
- resolve(result);
- }
-
- function resolver(i) {
- return function (x) {
- result[i] = x;
- count += 1;
-
- if (count === iterable.length) {
- resolve(result);
- }
- };
- }
-
- for (var i = 0; i < iterable.length; i += 1) {
- Promise$2.resolve(iterable[i]).then(resolver(i), reject);
- }
- });
-};
-
-Promise$2.race = function race(iterable) {
- return new Promise$2(function (resolve, reject) {
- for (var i = 0; i < iterable.length; i += 1) {
- Promise$2.resolve(iterable[i]).then(resolve, reject);
- }
- });
-};
-
-var p$1 = Promise$2.prototype;
-
-p$1.resolve = function resolve(x) {
- var promise = this;
-
- if (promise.state === PENDING) {
- if (x === promise) {
- throw new TypeError('Promise settled with itself.');
- }
-
- var called = false;
-
- try {
- var then = x && x['then'];
-
- if (x !== null && typeof x === 'object' && typeof then === 'function') {
- then.call(x, function (x) {
- if (!called) {
- promise.resolve(x);
- }
- called = true;
- }, function (r) {
- if (!called) {
- promise.reject(r);
- }
- called = true;
- });
- return;
- }
- } catch (e) {
- if (!called) {
- promise.reject(e);
- }
- return;
- }
-
- promise.state = RESOLVED;
- promise.value = x;
- promise.notify();
- }
-};
-
-p$1.reject = function reject(reason) {
- var promise = this;
-
- if (promise.state === PENDING) {
- if (reason === promise) {
- throw new TypeError('Promise settled with itself.');
- }
-
- promise.state = REJECTED;
- promise.value = reason;
- promise.notify();
- }
-};
-
-p$1.notify = function notify() {
- var promise = this;
-
- nextTick(function () {
- if (promise.state !== PENDING) {
- while (promise.deferred.length) {
- var deferred = promise.deferred.shift(),
- onResolved = deferred[0],
- onRejected = deferred[1],
- resolve = deferred[2],
- reject = deferred[3];
-
- try {
- if (promise.state === RESOLVED) {
- if (typeof onResolved === 'function') {
- resolve(onResolved.call(undefined, promise.value));
- } else {
- resolve(promise.value);
- }
- } else if (promise.state === REJECTED) {
- if (typeof onRejected === 'function') {
- resolve(onRejected.call(undefined, promise.value));
- } else {
- reject(promise.value);
- }
- }
- } catch (e) {
- reject(e);
- }
- }
- }
- });
-};
-
-p$1.then = function then(onResolved, onRejected) {
- var promise = this;
-
- return new Promise$2(function (resolve, reject) {
- promise.deferred.push([onResolved, onRejected, resolve, reject]);
- promise.notify();
- });
-};
-
-p$1.catch = function (onRejected) {
- return this.then(undefined, onRejected);
-};
-
-var PromiseObj = window.Promise || Promise$2;
+var PromiseObj = window.Promise;
function Promise$1(executor, context) {
@@ -251,9 +79,13 @@ p.finally = function (callback) {
});
};
-var debug = false;
-var util = {};
-var array = [];
+/**
+ * Utility functions.
+ */
+
+var debug = false;var util = {};var slice = [].slice;
+
+
function Util (Vue) {
util = Vue.util;
debug = Vue.config.debug || !Vue.config.silent;
@@ -279,6 +111,14 @@ function trim(str) {
return str.replace(/^\s*|\s*$/g, '');
}
+function toLower(str) {
+ return str ? str.toLowerCase() : '';
+}
+
+function toUpper(str) {
+ return str ? str.toUpperCase() : '';
+}
+
var isArray = Array.isArray;
function isString(val) {
@@ -301,6 +141,10 @@ function isPlainObject(obj) {
return isObject(obj) && Object.getPrototypeOf(obj) == Object.prototype;
}
+function isBlob(obj) {
+ return typeof Blob !== 'undefined' && obj instanceof Blob;
+}
+
function isFormData(obj) {
return typeof FormData !== 'undefined' && obj instanceof FormData;
}
@@ -331,7 +175,7 @@ function each(obj, iterator) {
var i, key;
- if (typeof obj.length == 'number') {
+ if (obj && typeof obj.length == 'number') {
for (i = 0; i < obj.length; i++) {
iterator.call(obj[i], obj[i], i);
}
@@ -350,7 +194,7 @@ var assign = Object.assign || _assign;
function merge(target) {
- var args = array.slice.call(arguments, 1);
+ var args = slice.call(arguments, 1);
args.forEach(function (source) {
_merge(target, source, true);
@@ -361,7 +205,7 @@ function merge(target) {
function defaults(target) {
- var args = array.slice.call(arguments, 1);
+ var args = slice.call(arguments, 1);
args.forEach(function (source) {
@@ -377,7 +221,7 @@ function defaults(target) {
function _assign(target) {
- var args = array.slice.call(arguments, 1);
+ var args = slice.call(arguments, 1);
args.forEach(function (source) {
_merge(target, source);
@@ -402,6 +246,10 @@ function _merge(target, source, deep) {
}
}
+/**
+ * Root Prefix Transform.
+ */
+
function root (options, next) {
var url = next(options);
@@ -413,6 +261,10 @@ function root (options, next) {
return url;
}
+/**
+ * Query Parameter Transform.
+ */
+
function query (options, next) {
var urlParams = Object.keys(Url.options.params),
@@ -588,6 +440,10 @@ function encodeReserved(str) {
}).join('');
}
+/**
+ * URL Template (RFC 6570) Transform.
+ */
+
function template (options) {
var variables = [],
@@ -728,6 +584,10 @@ function serialize(params, obj, scope) {
});
}
+/**
+ * XDomain client (Internet Explorer).
+ */
+
function xdrClient (request) {
return new Promise$1(function (resolve) {
@@ -756,6 +616,10 @@ function xdrClient (request) {
});
}
+/**
+ * CORS Interceptor.
+ */
+
var ORIGIN_URL = Url.parse(location.href);
var SUPPORTS_CORS = 'withCredentials' in new XMLHttpRequest();
@@ -784,15 +648,19 @@ function crossOrigin(request) {
return requestUrl.protocol !== ORIGIN_URL.protocol || requestUrl.host !== ORIGIN_URL.host;
}
+/**
+ * Body Interceptor.
+ */
+
function body (request, next) {
if (request.emulateJSON && isPlainObject(request.body)) {
request.body = Url.params(request.body);
- request.headers['Content-Type'] = 'application/x-www-form-urlencoded';
+ request.headers.set('Content-Type', 'application/x-www-form-urlencoded');
}
if (isFormData(request.body)) {
- delete request.headers['Content-Type'];
+ request.headers.delete('Content-Type');
}
if (isPlainObject(request.body)) {
@@ -801,21 +669,39 @@ function body (request, next) {
next(function (response) {
- var contentType = response.headers['Content-Type'];
+ Object.defineProperty(response, 'data', {
+ get: function () {
+ return this.body;
+ },
+ set: function (body) {
+ this.body = body;
+ }
+ });
+
+ return response.bodyText ? when(response.text(), function (text) {
- if (isString(contentType) && contentType.indexOf('application/json') === 0) {
+ var type = response.headers.get('Content-Type');
- try {
- response.data = response.json();
- } catch (e) {
- response.data = null;
+ if (isString(type) && type.indexOf('application/json') === 0) {
+
+ try {
+ response.body = JSON.parse(text);
+ } catch (e) {
+ response.body = null;
+ }
+ } else {
+ response.body = text;
}
- } else {
- response.data = response.text();
- }
+
+ return response;
+ }) : response;
});
}
+/**
+ * JSONP client.
+ */
+
function jsonpClient (request) {
return new Promise$1(function (resolve) {
@@ -858,6 +744,10 @@ function jsonpClient (request) {
});
}
+/**
+ * JSONP Interceptor.
+ */
+
function jsonp (request, next) {
if (request.method == 'JSONP') {
@@ -867,11 +757,21 @@ function jsonp (request, next) {
next(function (response) {
if (request.method == 'JSONP') {
- response.data = response.json();
+
+ return when(response.json(), function (json) {
+
+ response.body = json;
+
+ return response;
+ });
}
});
}
+/**
+ * Before Interceptor.
+ */
+
function before (request, next) {
if (isFunction(request.before)) {
@@ -888,17 +788,26 @@ function before (request, next) {
function method (request, next) {
if (request.emulateHTTP && /^(PUT|PATCH|DELETE)$/i.test(request.method)) {
- request.headers['X-HTTP-Method-Override'] = request.method;
+ request.headers.set('X-HTTP-Method-Override', request.method);
request.method = 'POST';
}
next();
}
+/**
+ * Header Interceptor.
+ */
+
function header (request, next) {
- request.method = request.method.toUpperCase();
- request.headers = assign({}, Http.headers.common, !request.crossOrigin ? Http.headers.custom : {}, Http.headers[request.method.toLowerCase()], request.headers);
+ var headers = assign({}, Http.headers.common, !request.crossOrigin ? Http.headers.custom : {}, Http.headers[toLower(request.method)]);
+
+ each(headers, function (value, name) {
+ if (!request.headers.has(name)) {
+ request.headers.set(name, value);
+ }
+ });
next();
}
@@ -923,6 +832,10 @@ function timeout (request, next) {
});
}
+/**
+ * XMLHttp client.
+ */
+
function xhrClient (request) {
return new Promise$1(function (resolve) {
@@ -931,8 +844,11 @@ function xhrClient (request) {
var response = request.respondWith('response' in xhr ? xhr.response : xhr.responseText, {
status: xhr.status === 1223 ? 204 : xhr.status, // IE9 status bug
- statusText: xhr.status === 1223 ? 'No Content' : trim(xhr.statusText),
- headers: parseHeaders(xhr.getAllResponseHeaders())
+ statusText: xhr.status === 1223 ? 'No Content' : trim(xhr.statusText)
+ });
+
+ each(trim(xhr.getAllResponseHeaders()).split('\n'), function (row) {
+ response.headers.append(row.slice(0, row.indexOf(':')), row.slice(row.indexOf(':') + 1));
});
resolve(response);
@@ -955,46 +871,25 @@ function xhrClient (request) {
}
}
+ if ('responseType' in xhr) {
+ xhr.responseType = 'blob';
+ }
+
if (request.credentials === true) {
xhr.withCredentials = true;
}
- each(request.headers || {}, function (value, header) {
- xhr.setRequestHeader(header, value);
+ request.headers.forEach(function (value, name) {
+ xhr.setRequestHeader(name, value);
});
xhr.send(request.getBody());
});
}
-function parseHeaders(str) {
-
- var headers = {},
- value,
- name,
- i;
-
- each(trim(str).split('\n'), function (row) {
-
- i = row.indexOf(':');
- name = trim(row.slice(0, i));
- value = trim(row.slice(i + 1));
-
- if (headers[name]) {
-
- if (isArray(headers[name])) {
- headers[name].push(value);
- } else {
- headers[name] = [headers[name], value];
- }
- } else {
-
- headers[name] = value;
- }
- });
-
- return headers;
-}
+/**
+ * Base client.
+ */
function Client (context) {
@@ -1066,6 +961,80 @@ var classCallCheck = function (instance, Constructor) {
}
};
+/**
+ * HTTP Headers.
+ */
+
+var Headers = function () {
+ function Headers(headers) {
+ var _this = this;
+
+ classCallCheck(this, Headers);
+
+
+ this.map = {};
+
+ each(headers, function (value, name) {
+ return _this.append(name, value);
+ });
+ }
+
+ Headers.prototype.has = function has(name) {
+ return this.map.hasOwnProperty(normalizeName(name));
+ };
+
+ Headers.prototype.get = function get(name) {
+
+ var list = this.map[normalizeName(name)];
+
+ return list ? list[0] : null;
+ };
+
+ Headers.prototype.getAll = function getAll(name) {
+ return this.map[normalizeName(name)] || [];
+ };
+
+ Headers.prototype.set = function set(name, value) {
+ this.map[normalizeName(name)] = [trim(value)];
+ };
+
+ Headers.prototype.append = function append(name, value) {
+
+ var list = this.map[normalizeName(name)];
+
+ if (!list) {
+ list = this.map[normalizeName(name)] = [];
+ }
+
+ list.push(trim(value));
+ };
+
+ Headers.prototype.delete = function _delete(name) {
+ delete this.map[normalizeName(name)];
+ };
+
+ Headers.prototype.forEach = function forEach(callback, thisArg) {
+ var _this2 = this;
+
+ each(this.map, function (list, name) {
+ each(list, function (value) {
+ return callback.call(thisArg, value, name, _this2);
+ });
+ });
+ };
+
+ return Headers;
+}();
+
+function normalizeName(name) {
+
+ if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) {
+ throw new TypeError('Invalid character in header field name');
+ }
+
+ return toLower(trim(name));
+}
+
/**
* HTTP Response.
*/
@@ -1080,39 +1049,74 @@ var Response = function () {
this.url = url;
- this.body = body;
- this.headers = headers || {};
+ this.ok = status >= 200 && status < 300;
this.status = status || 0;
this.statusText = statusText || '';
- this.ok = status >= 200 && status < 300;
+ this.headers = new Headers(headers);
+ this.body = body;
+
+ if (isString(body)) {
+
+ this.bodyText = body;
+ } else if (isBlob(body)) {
+
+ this.bodyBlob = body;
+
+ if (isBlobText(body)) {
+ this.bodyText = blobText(body);
+ }
+ }
}
- Response.prototype.text = function text() {
- return this.body;
+ Response.prototype.blob = function blob() {
+ return when(this.bodyBlob);
};
- Response.prototype.blob = function blob() {
- return new Blob([this.body]);
+ Response.prototype.text = function text() {
+ return when(this.bodyText);
};
Response.prototype.json = function json() {
- return JSON.parse(this.body);
+ return when(this.text(), function (text) {
+ return JSON.parse(text);
+ });
};
return Response;
}();
+function blobText(body) {
+ return new Promise$1(function (resolve) {
+
+ var reader = new FileReader();
+
+ reader.readAsText(body);
+ reader.onload = function () {
+ resolve(reader.result);
+ };
+ });
+}
+
+function isBlobText(body) {
+ return body.type.indexOf('text') === 0 || body.type.indexOf('json') !== -1;
+}
+
+/**
+ * HTTP Request.
+ */
+
var Request = function () {
function Request(options) {
classCallCheck(this, Request);
- this.method = 'GET';
this.body = null;
this.params = {};
- this.headers = {};
- assign(this, options);
+ assign(this, options, {
+ method: toUpper(options.method || 'GET'),
+ headers: new Headers(options.headers)
+ });
}
Request.prototype.getUrl = function getUrl() {
@@ -1189,6 +1193,186 @@ Http.interceptors = [before, timeout, method, body, jsonp, header, cors];
};
});
+/**
+ * Promises/A+ polyfill v1.1.4 (https://github.com/bramstein/promis)
+ */
+
+var RESOLVED = 0;
+var REJECTED = 1;
+var PENDING = 2;
+
+function Promise$2(executor) {
+
+ this.state = PENDING;
+ this.value = undefined;
+ this.deferred = [];
+
+ var promise = this;
+
+ try {
+ executor(function (x) {
+ promise.resolve(x);
+ }, function (r) {
+ promise.reject(r);
+ });
+ } catch (e) {
+ promise.reject(e);
+ }
+}
+
+Promise$2.reject = function (r) {
+ return new Promise$2(function (resolve, reject) {
+ reject(r);
+ });
+};
+
+Promise$2.resolve = function (x) {
+ return new Promise$2(function (resolve, reject) {
+ resolve(x);
+ });
+};
+
+Promise$2.all = function all(iterable) {
+ return new Promise$2(function (resolve, reject) {
+ var count = 0,
+ result = [];
+
+ if (iterable.length === 0) {
+ resolve(result);
+ }
+
+ function resolver(i) {
+ return function (x) {
+ result[i] = x;
+ count += 1;
+
+ if (count === iterable.length) {
+ resolve(result);
+ }
+ };
+ }
+
+ for (var i = 0; i < iterable.length; i += 1) {
+ Promise$2.resolve(iterable[i]).then(resolver(i), reject);
+ }
+ });
+};
+
+Promise$2.race = function race(iterable) {
+ return new Promise$2(function (resolve, reject) {
+ for (var i = 0; i < iterable.length; i += 1) {
+ Promise$2.resolve(iterable[i]).then(resolve, reject);
+ }
+ });
+};
+
+var p$1 = Promise$2.prototype;
+
+p$1.resolve = function resolve(x) {
+ var promise = this;
+
+ if (promise.state === PENDING) {
+ if (x === promise) {
+ throw new TypeError('Promise settled with itself.');
+ }
+
+ var called = false;
+
+ try {
+ var then = x && x['then'];
+
+ if (x !== null && typeof x === 'object' && typeof then === 'function') {
+ then.call(x, function (x) {
+ if (!called) {
+ promise.resolve(x);
+ }
+ called = true;
+ }, function (r) {
+ if (!called) {
+ promise.reject(r);
+ }
+ called = true;
+ });
+ return;
+ }
+ } catch (e) {
+ if (!called) {
+ promise.reject(e);
+ }
+ return;
+ }
+
+ promise.state = RESOLVED;
+ promise.value = x;
+ promise.notify();
+ }
+};
+
+p$1.reject = function reject(reason) {
+ var promise = this;
+
+ if (promise.state === PENDING) {
+ if (reason === promise) {
+ throw new TypeError('Promise settled with itself.');
+ }
+
+ promise.state = REJECTED;
+ promise.value = reason;
+ promise.notify();
+ }
+};
+
+p$1.notify = function notify() {
+ var promise = this;
+
+ nextTick(function () {
+ if (promise.state !== PENDING) {
+ while (promise.deferred.length) {
+ var deferred = promise.deferred.shift(),
+ onResolved = deferred[0],
+ onRejected = deferred[1],
+ resolve = deferred[2],
+ reject = deferred[3];
+
+ try {
+ if (promise.state === RESOLVED) {
+ if (typeof onResolved === 'function') {
+ resolve(onResolved.call(undefined, promise.value));
+ } else {
+ resolve(promise.value);
+ }
+ } else if (promise.state === REJECTED) {
+ if (typeof onRejected === 'function') {
+ resolve(onRejected.call(undefined, promise.value));
+ } else {
+ reject(promise.value);
+ }
+ }
+ } catch (e) {
+ reject(e);
+ }
+ }
+ }
+ });
+};
+
+p$1.then = function then(onResolved, onRejected) {
+ var promise = this;
+
+ return new Promise$2(function (resolve, reject) {
+ promise.deferred.push([onResolved, onRejected, resolve, reject]);
+ promise.notify();
+ });
+};
+
+p$1.catch = function (onRejected) {
+ return this.then(undefined, onRejected);
+};
+
+/**
+ * Service for interacting with RESTful services.
+ */
+
function Resource(url, params, actions, options) {
var self = this || {},
@@ -1198,7 +1382,7 @@ function Resource(url, params, actions, options) {
each(actions, function (action, name) {
- action = merge({ url: url, params: params || {} }, options, action);
+ action = merge({ url: url, params: assign({}, params) }, options, action);
resource[name] = function () {
return (self.$http || Http)(opts(action, arguments));
@@ -1259,6 +1443,10 @@ Resource.actions = {
};
+/**
+ * Install plugin.
+ */
+
function plugin(Vue) {
if (plugin.installed) {
@@ -1305,8 +1493,15 @@ function plugin(Vue) {
});
}
-if (typeof window !== 'undefined' && window.Vue) {
- window.Vue.use(plugin);
+if (typeof window !== 'undefined') {
+
+ if (!window.Promise) {
+ window.Promise = Promise$2;
+ }
+
+ if (window.Vue) {
+ window.Vue.use(plugin);
+ }
}
module.exports = plugin;
\ No newline at end of file
diff --git a/dist/vue-resource.es2015.js b/dist/vue-resource.es2015.js
index bfc12498..e2aa1f7b 100644
--- a/dist/vue-resource.es2015.js
+++ b/dist/vue-resource.es2015.js
@@ -1,186 +1,14 @@
/*!
- * vue-resource v0.9.3
+ * vue-resource v1.0.0
* https://github.com/vuejs/vue-resource
* Released under the MIT License.
*/
/**
- * Promises/A+ polyfill v1.1.4 (https://github.com/bramstein/promis)
+ * Promise adapter.
*/
-var RESOLVED = 0;
-var REJECTED = 1;
-var PENDING = 2;
-
-function Promise$2(executor) {
-
- this.state = PENDING;
- this.value = undefined;
- this.deferred = [];
-
- var promise = this;
-
- try {
- executor(function (x) {
- promise.resolve(x);
- }, function (r) {
- promise.reject(r);
- });
- } catch (e) {
- promise.reject(e);
- }
-}
-
-Promise$2.reject = function (r) {
- return new Promise$2(function (resolve, reject) {
- reject(r);
- });
-};
-
-Promise$2.resolve = function (x) {
- return new Promise$2(function (resolve, reject) {
- resolve(x);
- });
-};
-
-Promise$2.all = function all(iterable) {
- return new Promise$2(function (resolve, reject) {
- var count = 0,
- result = [];
-
- if (iterable.length === 0) {
- resolve(result);
- }
-
- function resolver(i) {
- return function (x) {
- result[i] = x;
- count += 1;
-
- if (count === iterable.length) {
- resolve(result);
- }
- };
- }
-
- for (var i = 0; i < iterable.length; i += 1) {
- Promise$2.resolve(iterable[i]).then(resolver(i), reject);
- }
- });
-};
-
-Promise$2.race = function race(iterable) {
- return new Promise$2(function (resolve, reject) {
- for (var i = 0; i < iterable.length; i += 1) {
- Promise$2.resolve(iterable[i]).then(resolve, reject);
- }
- });
-};
-
-var p$1 = Promise$2.prototype;
-
-p$1.resolve = function resolve(x) {
- var promise = this;
-
- if (promise.state === PENDING) {
- if (x === promise) {
- throw new TypeError('Promise settled with itself.');
- }
-
- var called = false;
-
- try {
- var then = x && x['then'];
-
- if (x !== null && typeof x === 'object' && typeof then === 'function') {
- then.call(x, function (x) {
- if (!called) {
- promise.resolve(x);
- }
- called = true;
- }, function (r) {
- if (!called) {
- promise.reject(r);
- }
- called = true;
- });
- return;
- }
- } catch (e) {
- if (!called) {
- promise.reject(e);
- }
- return;
- }
-
- promise.state = RESOLVED;
- promise.value = x;
- promise.notify();
- }
-};
-
-p$1.reject = function reject(reason) {
- var promise = this;
-
- if (promise.state === PENDING) {
- if (reason === promise) {
- throw new TypeError('Promise settled with itself.');
- }
-
- promise.state = REJECTED;
- promise.value = reason;
- promise.notify();
- }
-};
-
-p$1.notify = function notify() {
- var promise = this;
-
- nextTick(function () {
- if (promise.state !== PENDING) {
- while (promise.deferred.length) {
- var deferred = promise.deferred.shift(),
- onResolved = deferred[0],
- onRejected = deferred[1],
- resolve = deferred[2],
- reject = deferred[3];
-
- try {
- if (promise.state === RESOLVED) {
- if (typeof onResolved === 'function') {
- resolve(onResolved.call(undefined, promise.value));
- } else {
- resolve(promise.value);
- }
- } else if (promise.state === REJECTED) {
- if (typeof onRejected === 'function') {
- resolve(onRejected.call(undefined, promise.value));
- } else {
- reject(promise.value);
- }
- }
- } catch (e) {
- reject(e);
- }
- }
- }
- });
-};
-
-p$1.then = function then(onResolved, onRejected) {
- var promise = this;
-
- return new Promise$2(function (resolve, reject) {
- promise.deferred.push([onResolved, onRejected, resolve, reject]);
- promise.notify();
- });
-};
-
-p$1.catch = function (onRejected) {
- return this.then(undefined, onRejected);
-};
-
-var PromiseObj = window.Promise || Promise$2;
+var PromiseObj = window.Promise;
function Promise$1(executor, context) {
@@ -249,9 +77,13 @@ p.finally = function (callback) {
});
};
-var debug = false;
-var util = {};
-var array = [];
+/**
+ * Utility functions.
+ */
+
+var debug = false;var util = {};var slice = [].slice;
+
+
function Util (Vue) {
util = Vue.util;
debug = Vue.config.debug || !Vue.config.silent;
@@ -277,6 +109,14 @@ function trim(str) {
return str.replace(/^\s*|\s*$/g, '');
}
+function toLower(str) {
+ return str ? str.toLowerCase() : '';
+}
+
+function toUpper(str) {
+ return str ? str.toUpperCase() : '';
+}
+
var isArray = Array.isArray;
function isString(val) {
@@ -299,6 +139,10 @@ function isPlainObject(obj) {
return isObject(obj) && Object.getPrototypeOf(obj) == Object.prototype;
}
+function isBlob(obj) {
+ return typeof Blob !== 'undefined' && obj instanceof Blob;
+}
+
function isFormData(obj) {
return typeof FormData !== 'undefined' && obj instanceof FormData;
}
@@ -329,7 +173,7 @@ function each(obj, iterator) {
var i, key;
- if (typeof obj.length == 'number') {
+ if (obj && typeof obj.length == 'number') {
for (i = 0; i < obj.length; i++) {
iterator.call(obj[i], obj[i], i);
}
@@ -348,7 +192,7 @@ var assign = Object.assign || _assign;
function merge(target) {
- var args = array.slice.call(arguments, 1);
+ var args = slice.call(arguments, 1);
args.forEach(function (source) {
_merge(target, source, true);
@@ -359,7 +203,7 @@ function merge(target) {
function defaults(target) {
- var args = array.slice.call(arguments, 1);
+ var args = slice.call(arguments, 1);
args.forEach(function (source) {
@@ -375,7 +219,7 @@ function defaults(target) {
function _assign(target) {
- var args = array.slice.call(arguments, 1);
+ var args = slice.call(arguments, 1);
args.forEach(function (source) {
_merge(target, source);
@@ -400,6 +244,10 @@ function _merge(target, source, deep) {
}
}
+/**
+ * Root Prefix Transform.
+ */
+
function root (options, next) {
var url = next(options);
@@ -411,6 +259,10 @@ function root (options, next) {
return url;
}
+/**
+ * Query Parameter Transform.
+ */
+
function query (options, next) {
var urlParams = Object.keys(Url.options.params),
@@ -586,6 +438,10 @@ function encodeReserved(str) {
}).join('');
}
+/**
+ * URL Template (RFC 6570) Transform.
+ */
+
function template (options) {
var variables = [],
@@ -726,6 +582,10 @@ function serialize(params, obj, scope) {
});
}
+/**
+ * XDomain client (Internet Explorer).
+ */
+
function xdrClient (request) {
return new Promise$1(function (resolve) {
@@ -754,6 +614,10 @@ function xdrClient (request) {
});
}
+/**
+ * CORS Interceptor.
+ */
+
var ORIGIN_URL = Url.parse(location.href);
var SUPPORTS_CORS = 'withCredentials' in new XMLHttpRequest();
@@ -782,15 +646,19 @@ function crossOrigin(request) {
return requestUrl.protocol !== ORIGIN_URL.protocol || requestUrl.host !== ORIGIN_URL.host;
}
+/**
+ * Body Interceptor.
+ */
+
function body (request, next) {
if (request.emulateJSON && isPlainObject(request.body)) {
request.body = Url.params(request.body);
- request.headers['Content-Type'] = 'application/x-www-form-urlencoded';
+ request.headers.set('Content-Type', 'application/x-www-form-urlencoded');
}
if (isFormData(request.body)) {
- delete request.headers['Content-Type'];
+ request.headers.delete('Content-Type');
}
if (isPlainObject(request.body)) {
@@ -799,21 +667,39 @@ function body (request, next) {
next(function (response) {
- var contentType = response.headers['Content-Type'];
+ Object.defineProperty(response, 'data', {
+ get: function () {
+ return this.body;
+ },
+ set: function (body) {
+ this.body = body;
+ }
+ });
+
+ return response.bodyText ? when(response.text(), function (text) {
- if (isString(contentType) && contentType.indexOf('application/json') === 0) {
+ var type = response.headers.get('Content-Type');
- try {
- response.data = response.json();
- } catch (e) {
- response.data = null;
+ if (isString(type) && type.indexOf('application/json') === 0) {
+
+ try {
+ response.body = JSON.parse(text);
+ } catch (e) {
+ response.body = null;
+ }
+ } else {
+ response.body = text;
}
- } else {
- response.data = response.text();
- }
+
+ return response;
+ }) : response;
});
}
+/**
+ * JSONP client.
+ */
+
function jsonpClient (request) {
return new Promise$1(function (resolve) {
@@ -856,6 +742,10 @@ function jsonpClient (request) {
});
}
+/**
+ * JSONP Interceptor.
+ */
+
function jsonp (request, next) {
if (request.method == 'JSONP') {
@@ -865,11 +755,21 @@ function jsonp (request, next) {
next(function (response) {
if (request.method == 'JSONP') {
- response.data = response.json();
+
+ return when(response.json(), function (json) {
+
+ response.body = json;
+
+ return response;
+ });
}
});
}
+/**
+ * Before Interceptor.
+ */
+
function before (request, next) {
if (isFunction(request.before)) {
@@ -886,17 +786,26 @@ function before (request, next) {
function method (request, next) {
if (request.emulateHTTP && /^(PUT|PATCH|DELETE)$/i.test(request.method)) {
- request.headers['X-HTTP-Method-Override'] = request.method;
+ request.headers.set('X-HTTP-Method-Override', request.method);
request.method = 'POST';
}
next();
}
+/**
+ * Header Interceptor.
+ */
+
function header (request, next) {
- request.method = request.method.toUpperCase();
- request.headers = assign({}, Http.headers.common, !request.crossOrigin ? Http.headers.custom : {}, Http.headers[request.method.toLowerCase()], request.headers);
+ var headers = assign({}, Http.headers.common, !request.crossOrigin ? Http.headers.custom : {}, Http.headers[toLower(request.method)]);
+
+ each(headers, function (value, name) {
+ if (!request.headers.has(name)) {
+ request.headers.set(name, value);
+ }
+ });
next();
}
@@ -921,6 +830,10 @@ function timeout (request, next) {
});
}
+/**
+ * XMLHttp client.
+ */
+
function xhrClient (request) {
return new Promise$1(function (resolve) {
@@ -929,8 +842,11 @@ function xhrClient (request) {
var response = request.respondWith('response' in xhr ? xhr.response : xhr.responseText, {
status: xhr.status === 1223 ? 204 : xhr.status, // IE9 status bug
- statusText: xhr.status === 1223 ? 'No Content' : trim(xhr.statusText),
- headers: parseHeaders(xhr.getAllResponseHeaders())
+ statusText: xhr.status === 1223 ? 'No Content' : trim(xhr.statusText)
+ });
+
+ each(trim(xhr.getAllResponseHeaders()).split('\n'), function (row) {
+ response.headers.append(row.slice(0, row.indexOf(':')), row.slice(row.indexOf(':') + 1));
});
resolve(response);
@@ -953,46 +869,25 @@ function xhrClient (request) {
}
}
+ if ('responseType' in xhr) {
+ xhr.responseType = 'blob';
+ }
+
if (request.credentials === true) {
xhr.withCredentials = true;
}
- each(request.headers || {}, function (value, header) {
- xhr.setRequestHeader(header, value);
+ request.headers.forEach(function (value, name) {
+ xhr.setRequestHeader(name, value);
});
xhr.send(request.getBody());
});
}
-function parseHeaders(str) {
-
- var headers = {},
- value,
- name,
- i;
-
- each(trim(str).split('\n'), function (row) {
-
- i = row.indexOf(':');
- name = trim(row.slice(0, i));
- value = trim(row.slice(i + 1));
-
- if (headers[name]) {
-
- if (isArray(headers[name])) {
- headers[name].push(value);
- } else {
- headers[name] = [headers[name], value];
- }
- } else {
-
- headers[name] = value;
- }
- });
-
- return headers;
-}
+/**
+ * Base client.
+ */
function Client (context) {
@@ -1064,6 +959,80 @@ var classCallCheck = function (instance, Constructor) {
}
};
+/**
+ * HTTP Headers.
+ */
+
+var Headers = function () {
+ function Headers(headers) {
+ var _this = this;
+
+ classCallCheck(this, Headers);
+
+
+ this.map = {};
+
+ each(headers, function (value, name) {
+ return _this.append(name, value);
+ });
+ }
+
+ Headers.prototype.has = function has(name) {
+ return this.map.hasOwnProperty(normalizeName(name));
+ };
+
+ Headers.prototype.get = function get(name) {
+
+ var list = this.map[normalizeName(name)];
+
+ return list ? list[0] : null;
+ };
+
+ Headers.prototype.getAll = function getAll(name) {
+ return this.map[normalizeName(name)] || [];
+ };
+
+ Headers.prototype.set = function set(name, value) {
+ this.map[normalizeName(name)] = [trim(value)];
+ };
+
+ Headers.prototype.append = function append(name, value) {
+
+ var list = this.map[normalizeName(name)];
+
+ if (!list) {
+ list = this.map[normalizeName(name)] = [];
+ }
+
+ list.push(trim(value));
+ };
+
+ Headers.prototype.delete = function _delete(name) {
+ delete this.map[normalizeName(name)];
+ };
+
+ Headers.prototype.forEach = function forEach(callback, thisArg) {
+ var _this2 = this;
+
+ each(this.map, function (list, name) {
+ each(list, function (value) {
+ return callback.call(thisArg, value, name, _this2);
+ });
+ });
+ };
+
+ return Headers;
+}();
+
+function normalizeName(name) {
+
+ if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) {
+ throw new TypeError('Invalid character in header field name');
+ }
+
+ return toLower(trim(name));
+}
+
/**
* HTTP Response.
*/
@@ -1078,39 +1047,74 @@ var Response = function () {
this.url = url;
- this.body = body;
- this.headers = headers || {};
+ this.ok = status >= 200 && status < 300;
this.status = status || 0;
this.statusText = statusText || '';
- this.ok = status >= 200 && status < 300;
+ this.headers = new Headers(headers);
+ this.body = body;
+
+ if (isString(body)) {
+
+ this.bodyText = body;
+ } else if (isBlob(body)) {
+
+ this.bodyBlob = body;
+
+ if (isBlobText(body)) {
+ this.bodyText = blobText(body);
+ }
+ }
}
- Response.prototype.text = function text() {
- return this.body;
+ Response.prototype.blob = function blob() {
+ return when(this.bodyBlob);
};
- Response.prototype.blob = function blob() {
- return new Blob([this.body]);
+ Response.prototype.text = function text() {
+ return when(this.bodyText);
};
Response.prototype.json = function json() {
- return JSON.parse(this.body);
+ return when(this.text(), function (text) {
+ return JSON.parse(text);
+ });
};
return Response;
}();
+function blobText(body) {
+ return new Promise$1(function (resolve) {
+
+ var reader = new FileReader();
+
+ reader.readAsText(body);
+ reader.onload = function () {
+ resolve(reader.result);
+ };
+ });
+}
+
+function isBlobText(body) {
+ return body.type.indexOf('text') === 0 || body.type.indexOf('json') !== -1;
+}
+
+/**
+ * HTTP Request.
+ */
+
var Request = function () {
function Request(options) {
classCallCheck(this, Request);
- this.method = 'GET';
this.body = null;
this.params = {};
- this.headers = {};
- assign(this, options);
+ assign(this, options, {
+ method: toUpper(options.method || 'GET'),
+ headers: new Headers(options.headers)
+ });
}
Request.prototype.getUrl = function getUrl() {
@@ -1187,6 +1191,186 @@ Http.interceptors = [before, timeout, method, body, jsonp, header, cors];
};
});
+/**
+ * Promises/A+ polyfill v1.1.4 (https://github.com/bramstein/promis)
+ */
+
+var RESOLVED = 0;
+var REJECTED = 1;
+var PENDING = 2;
+
+function Promise$2(executor) {
+
+ this.state = PENDING;
+ this.value = undefined;
+ this.deferred = [];
+
+ var promise = this;
+
+ try {
+ executor(function (x) {
+ promise.resolve(x);
+ }, function (r) {
+ promise.reject(r);
+ });
+ } catch (e) {
+ promise.reject(e);
+ }
+}
+
+Promise$2.reject = function (r) {
+ return new Promise$2(function (resolve, reject) {
+ reject(r);
+ });
+};
+
+Promise$2.resolve = function (x) {
+ return new Promise$2(function (resolve, reject) {
+ resolve(x);
+ });
+};
+
+Promise$2.all = function all(iterable) {
+ return new Promise$2(function (resolve, reject) {
+ var count = 0,
+ result = [];
+
+ if (iterable.length === 0) {
+ resolve(result);
+ }
+
+ function resolver(i) {
+ return function (x) {
+ result[i] = x;
+ count += 1;
+
+ if (count === iterable.length) {
+ resolve(result);
+ }
+ };
+ }
+
+ for (var i = 0; i < iterable.length; i += 1) {
+ Promise$2.resolve(iterable[i]).then(resolver(i), reject);
+ }
+ });
+};
+
+Promise$2.race = function race(iterable) {
+ return new Promise$2(function (resolve, reject) {
+ for (var i = 0; i < iterable.length; i += 1) {
+ Promise$2.resolve(iterable[i]).then(resolve, reject);
+ }
+ });
+};
+
+var p$1 = Promise$2.prototype;
+
+p$1.resolve = function resolve(x) {
+ var promise = this;
+
+ if (promise.state === PENDING) {
+ if (x === promise) {
+ throw new TypeError('Promise settled with itself.');
+ }
+
+ var called = false;
+
+ try {
+ var then = x && x['then'];
+
+ if (x !== null && typeof x === 'object' && typeof then === 'function') {
+ then.call(x, function (x) {
+ if (!called) {
+ promise.resolve(x);
+ }
+ called = true;
+ }, function (r) {
+ if (!called) {
+ promise.reject(r);
+ }
+ called = true;
+ });
+ return;
+ }
+ } catch (e) {
+ if (!called) {
+ promise.reject(e);
+ }
+ return;
+ }
+
+ promise.state = RESOLVED;
+ promise.value = x;
+ promise.notify();
+ }
+};
+
+p$1.reject = function reject(reason) {
+ var promise = this;
+
+ if (promise.state === PENDING) {
+ if (reason === promise) {
+ throw new TypeError('Promise settled with itself.');
+ }
+
+ promise.state = REJECTED;
+ promise.value = reason;
+ promise.notify();
+ }
+};
+
+p$1.notify = function notify() {
+ var promise = this;
+
+ nextTick(function () {
+ if (promise.state !== PENDING) {
+ while (promise.deferred.length) {
+ var deferred = promise.deferred.shift(),
+ onResolved = deferred[0],
+ onRejected = deferred[1],
+ resolve = deferred[2],
+ reject = deferred[3];
+
+ try {
+ if (promise.state === RESOLVED) {
+ if (typeof onResolved === 'function') {
+ resolve(onResolved.call(undefined, promise.value));
+ } else {
+ resolve(promise.value);
+ }
+ } else if (promise.state === REJECTED) {
+ if (typeof onRejected === 'function') {
+ resolve(onRejected.call(undefined, promise.value));
+ } else {
+ reject(promise.value);
+ }
+ }
+ } catch (e) {
+ reject(e);
+ }
+ }
+ }
+ });
+};
+
+p$1.then = function then(onResolved, onRejected) {
+ var promise = this;
+
+ return new Promise$2(function (resolve, reject) {
+ promise.deferred.push([onResolved, onRejected, resolve, reject]);
+ promise.notify();
+ });
+};
+
+p$1.catch = function (onRejected) {
+ return this.then(undefined, onRejected);
+};
+
+/**
+ * Service for interacting with RESTful services.
+ */
+
function Resource(url, params, actions, options) {
var self = this || {},
@@ -1196,7 +1380,7 @@ function Resource(url, params, actions, options) {
each(actions, function (action, name) {
- action = merge({ url: url, params: params || {} }, options, action);
+ action = merge({ url: url, params: assign({}, params) }, options, action);
resource[name] = function () {
return (self.$http || Http)(opts(action, arguments));
@@ -1257,6 +1441,10 @@ Resource.actions = {
};
+/**
+ * Install plugin.
+ */
+
function plugin(Vue) {
if (plugin.installed) {
@@ -1303,8 +1491,15 @@ function plugin(Vue) {
});
}
-if (typeof window !== 'undefined' && window.Vue) {
- window.Vue.use(plugin);
+if (typeof window !== 'undefined') {
+
+ if (!window.Promise) {
+ window.Promise = Promise$2;
+ }
+
+ if (window.Vue) {
+ window.Vue.use(plugin);
+ }
}
export default plugin;
diff --git a/dist/vue-resource.js b/dist/vue-resource.js
index d7981dbe..0c09255f 100644
--- a/dist/vue-resource.js
+++ b/dist/vue-resource.js
@@ -1,5 +1,5 @@
/*!
- * vue-resource v0.9.3
+ * vue-resource v1.0.0
* https://github.com/vuejs/vue-resource
* Released under the MIT License.
*/
@@ -8,1311 +8,1506 @@
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.VueResource = factory());
-}(this, function () { 'use strict';
+}(this, (function () { 'use strict';
- /**
- * Promises/A+ polyfill v1.1.4 (https://github.com/bramstein/promis)
- */
+/**
+ * Promise adapter.
+ */
- var RESOLVED = 0;
- var REJECTED = 1;
- var PENDING = 2;
+var PromiseObj = window.Promise;
- function Promise$2(executor) {
+function Promise$1(executor, context) {
- this.state = PENDING;
- this.value = undefined;
- this.deferred = [];
+ if (executor instanceof PromiseObj) {
+ this.promise = executor;
+ } else {
+ this.promise = new PromiseObj(executor.bind(context));
+ }
- var promise = this;
+ this.context = context;
+}
- try {
- executor(function (x) {
- promise.resolve(x);
- }, function (r) {
- promise.reject(r);
- });
- } catch (e) {
- promise.reject(e);
- }
- }
+Promise$1.all = function (iterable, context) {
+ return new Promise$1(PromiseObj.all(iterable), context);
+};
- Promise$2.reject = function (r) {
- return new Promise$2(function (resolve, reject) {
- reject(r);
- });
- };
-
- Promise$2.resolve = function (x) {
- return new Promise$2(function (resolve, reject) {
- resolve(x);
- });
- };
-
- Promise$2.all = function all(iterable) {
- return new Promise$2(function (resolve, reject) {
- var count = 0,
- result = [];
-
- if (iterable.length === 0) {
- resolve(result);
- }
-
- function resolver(i) {
- return function (x) {
- result[i] = x;
- count += 1;
-
- if (count === iterable.length) {
- resolve(result);
- }
- };
- }
-
- for (var i = 0; i < iterable.length; i += 1) {
- Promise$2.resolve(iterable[i]).then(resolver(i), reject);
- }
- });
- };
-
- Promise$2.race = function race(iterable) {
- return new Promise$2(function (resolve, reject) {
- for (var i = 0; i < iterable.length; i += 1) {
- Promise$2.resolve(iterable[i]).then(resolve, reject);
- }
- });
- };
-
- var p$1 = Promise$2.prototype;
-
- p$1.resolve = function resolve(x) {
- var promise = this;
-
- if (promise.state === PENDING) {
- if (x === promise) {
- throw new TypeError('Promise settled with itself.');
- }
-
- var called = false;
-
- try {
- var then = x && x['then'];
-
- if (x !== null && typeof x === 'object' && typeof then === 'function') {
- then.call(x, function (x) {
- if (!called) {
- promise.resolve(x);
- }
- called = true;
- }, function (r) {
- if (!called) {
- promise.reject(r);
- }
- called = true;
- });
- return;
- }
- } catch (e) {
- if (!called) {
- promise.reject(e);
- }
- return;
- }
-
- promise.state = RESOLVED;
- promise.value = x;
- promise.notify();
- }
- };
-
- p$1.reject = function reject(reason) {
- var promise = this;
-
- if (promise.state === PENDING) {
- if (reason === promise) {
- throw new TypeError('Promise settled with itself.');
- }
-
- promise.state = REJECTED;
- promise.value = reason;
- promise.notify();
- }
- };
-
- p$1.notify = function notify() {
- var promise = this;
-
- nextTick(function () {
- if (promise.state !== PENDING) {
- while (promise.deferred.length) {
- var deferred = promise.deferred.shift(),
- onResolved = deferred[0],
- onRejected = deferred[1],
- resolve = deferred[2],
- reject = deferred[3];
-
- try {
- if (promise.state === RESOLVED) {
- if (typeof onResolved === 'function') {
- resolve(onResolved.call(undefined, promise.value));
- } else {
- resolve(promise.value);
- }
- } else if (promise.state === REJECTED) {
- if (typeof onRejected === 'function') {
- resolve(onRejected.call(undefined, promise.value));
- } else {
- reject(promise.value);
- }
- }
- } catch (e) {
- reject(e);
- }
- }
- }
- });
- };
-
- p$1.then = function then(onResolved, onRejected) {
- var promise = this;
-
- return new Promise$2(function (resolve, reject) {
- promise.deferred.push([onResolved, onRejected, resolve, reject]);
- promise.notify();
- });
- };
-
- p$1.catch = function (onRejected) {
- return this.then(undefined, onRejected);
- };
-
- var PromiseObj = window.Promise || Promise$2;
-
- function Promise$1(executor, context) {
-
- if (executor instanceof PromiseObj) {
- this.promise = executor;
- } else {
- this.promise = new PromiseObj(executor.bind(context));
- }
-
- this.context = context;
- }
+Promise$1.resolve = function (value, context) {
+ return new Promise$1(PromiseObj.resolve(value), context);
+};
- Promise$1.all = function (iterable, context) {
- return new Promise$1(PromiseObj.all(iterable), context);
- };
+Promise$1.reject = function (reason, context) {
+ return new Promise$1(PromiseObj.reject(reason), context);
+};
- Promise$1.resolve = function (value, context) {
- return new Promise$1(PromiseObj.resolve(value), context);
- };
+Promise$1.race = function (iterable, context) {
+ return new Promise$1(PromiseObj.race(iterable), context);
+};
- Promise$1.reject = function (reason, context) {
- return new Promise$1(PromiseObj.reject(reason), context);
- };
+var p = Promise$1.prototype;
- Promise$1.race = function (iterable, context) {
- return new Promise$1(PromiseObj.race(iterable), context);
- };
+p.bind = function (context) {
+ this.context = context;
+ return this;
+};
- var p = Promise$1.prototype;
+p.then = function (fulfilled, rejected) {
- p.bind = function (context) {
- this.context = context;
- return this;
- };
+ if (fulfilled && fulfilled.bind && this.context) {
+ fulfilled = fulfilled.bind(this.context);
+ }
- p.then = function (fulfilled, rejected) {
+ if (rejected && rejected.bind && this.context) {
+ rejected = rejected.bind(this.context);
+ }
- if (fulfilled && fulfilled.bind && this.context) {
- fulfilled = fulfilled.bind(this.context);
- }
+ return new Promise$1(this.promise.then(fulfilled, rejected), this.context);
+};
- if (rejected && rejected.bind && this.context) {
- rejected = rejected.bind(this.context);
- }
+p.catch = function (rejected) {
- return new Promise$1(this.promise.then(fulfilled, rejected), this.context);
- };
+ if (rejected && rejected.bind && this.context) {
+ rejected = rejected.bind(this.context);
+ }
- p.catch = function (rejected) {
+ return new Promise$1(this.promise.catch(rejected), this.context);
+};
- if (rejected && rejected.bind && this.context) {
- rejected = rejected.bind(this.context);
- }
+p.finally = function (callback) {
- return new Promise$1(this.promise.catch(rejected), this.context);
- };
+ return this.then(function (value) {
+ callback.call(this);
+ return value;
+ }, function (reason) {
+ callback.call(this);
+ return PromiseObj.reject(reason);
+ });
+};
- p.finally = function (callback) {
+/**
+ * Utility functions.
+ */
- return this.then(function (value) {
- callback.call(this);
- return value;
- }, function (reason) {
- callback.call(this);
- return PromiseObj.reject(reason);
- });
- };
+var debug = false;var util = {};var slice = [].slice;
- var debug = false;
- var util = {};
- var array = [];
- function Util (Vue) {
- util = Vue.util;
- debug = Vue.config.debug || !Vue.config.silent;
- }
- function warn(msg) {
- if (typeof console !== 'undefined' && debug) {
- console.warn('[VueResource warn]: ' + msg);
- }
- }
+function Util (Vue) {
+ util = Vue.util;
+ debug = Vue.config.debug || !Vue.config.silent;
+}
- function error(msg) {
- if (typeof console !== 'undefined') {
- console.error(msg);
- }
- }
+function warn(msg) {
+ if (typeof console !== 'undefined' && debug) {
+ console.warn('[VueResource warn]: ' + msg);
+ }
+}
- function nextTick(cb, ctx) {
- return util.nextTick(cb, ctx);
- }
+function error(msg) {
+ if (typeof console !== 'undefined') {
+ console.error(msg);
+ }
+}
- function trim(str) {
- return str.replace(/^\s*|\s*$/g, '');
- }
+function nextTick(cb, ctx) {
+ return util.nextTick(cb, ctx);
+}
- var isArray = Array.isArray;
+function trim(str) {
+ return str.replace(/^\s*|\s*$/g, '');
+}
- function isString(val) {
- return typeof val === 'string';
- }
+function toLower(str) {
+ return str ? str.toLowerCase() : '';
+}
- function isBoolean(val) {
- return val === true || val === false;
- }
+function toUpper(str) {
+ return str ? str.toUpperCase() : '';
+}
- function isFunction(val) {
- return typeof val === 'function';
- }
+var isArray = Array.isArray;
- function isObject(obj) {
- return obj !== null && typeof obj === 'object';
- }
+function isString(val) {
+ return typeof val === 'string';
+}
- function isPlainObject(obj) {
- return isObject(obj) && Object.getPrototypeOf(obj) == Object.prototype;
- }
+function isBoolean(val) {
+ return val === true || val === false;
+}
- function isFormData(obj) {
- return typeof FormData !== 'undefined' && obj instanceof FormData;
- }
+function isFunction(val) {
+ return typeof val === 'function';
+}
- function when(value, fulfilled, rejected) {
+function isObject(obj) {
+ return obj !== null && typeof obj === 'object';
+}
- var promise = Promise$1.resolve(value);
+function isPlainObject(obj) {
+ return isObject(obj) && Object.getPrototypeOf(obj) == Object.prototype;
+}
- if (arguments.length < 2) {
- return promise;
- }
+function isBlob(obj) {
+ return typeof Blob !== 'undefined' && obj instanceof Blob;
+}
- return promise.then(fulfilled, rejected);
- }
+function isFormData(obj) {
+ return typeof FormData !== 'undefined' && obj instanceof FormData;
+}
- function options(fn, obj, opts) {
+function when(value, fulfilled, rejected) {
- opts = opts || {};
+ var promise = Promise$1.resolve(value);
- if (isFunction(opts)) {
- opts = opts.call(obj);
- }
+ if (arguments.length < 2) {
+ return promise;
+ }
- return merge(fn.bind({ $vm: obj, $options: opts }), fn, { $options: opts });
- }
+ return promise.then(fulfilled, rejected);
+}
- function each(obj, iterator) {
+function options(fn, obj, opts) {
- var i, key;
+ opts = opts || {};
- if (typeof obj.length == 'number') {
- for (i = 0; i < obj.length; i++) {
- iterator.call(obj[i], obj[i], i);
- }
- } else if (isObject(obj)) {
- for (key in obj) {
- if (obj.hasOwnProperty(key)) {
- iterator.call(obj[key], obj[key], key);
- }
- }
- }
+ if (isFunction(opts)) {
+ opts = opts.call(obj);
+ }
- return obj;
- }
+ return merge(fn.bind({ $vm: obj, $options: opts }), fn, { $options: opts });
+}
- var assign = Object.assign || _assign;
+function each(obj, iterator) {
- function merge(target) {
+ var i, key;
- var args = array.slice.call(arguments, 1);
+ if (obj && typeof obj.length == 'number') {
+ for (i = 0; i < obj.length; i++) {
+ iterator.call(obj[i], obj[i], i);
+ }
+ } else if (isObject(obj)) {
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ iterator.call(obj[key], obj[key], key);
+ }
+ }
+ }
- args.forEach(function (source) {
- _merge(target, source, true);
- });
+ return obj;
+}
- return target;
- }
+var assign = Object.assign || _assign;
- function defaults(target) {
+function merge(target) {
- var args = array.slice.call(arguments, 1);
+ var args = slice.call(arguments, 1);
- args.forEach(function (source) {
+ args.forEach(function (source) {
+ _merge(target, source, true);
+ });
- for (var key in source) {
- if (target[key] === undefined) {
- target[key] = source[key];
- }
- }
- });
+ return target;
+}
- return target;
- }
+function defaults(target) {
- function _assign(target) {
+ var args = slice.call(arguments, 1);
- var args = array.slice.call(arguments, 1);
+ args.forEach(function (source) {
- args.forEach(function (source) {
- _merge(target, source);
- });
+ for (var key in source) {
+ if (target[key] === undefined) {
+ target[key] = source[key];
+ }
+ }
+ });
- return target;
- }
+ return target;
+}
- function _merge(target, source, deep) {
- for (var key in source) {
- if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {
- if (isPlainObject(source[key]) && !isPlainObject(target[key])) {
- target[key] = {};
- }
- if (isArray(source[key]) && !isArray(target[key])) {
- target[key] = [];
- }
- _merge(target[key], source[key], deep);
- } else if (source[key] !== undefined) {
- target[key] = source[key];
- }
- }
- }
+function _assign(target) {
- function root (options, next) {
+ var args = slice.call(arguments, 1);
- var url = next(options);
+ args.forEach(function (source) {
+ _merge(target, source);
+ });
- if (isString(options.root) && !url.match(/^(https?:)?\//)) {
- url = options.root + '/' + url;
- }
+ return target;
+}
- return url;
- }
+function _merge(target, source, deep) {
+ for (var key in source) {
+ if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {
+ if (isPlainObject(source[key]) && !isPlainObject(target[key])) {
+ target[key] = {};
+ }
+ if (isArray(source[key]) && !isArray(target[key])) {
+ target[key] = [];
+ }
+ _merge(target[key], source[key], deep);
+ } else if (source[key] !== undefined) {
+ target[key] = source[key];
+ }
+ }
+}
- function query (options, next) {
+/**
+ * Root Prefix Transform.
+ */
- var urlParams = Object.keys(Url.options.params),
- query = {},
- url = next(options);
+function root (options, next) {
- each(options.params, function (value, key) {
- if (urlParams.indexOf(key) === -1) {
- query[key] = value;
- }
- });
+ var url = next(options);
- query = Url.params(query);
+ if (isString(options.root) && !url.match(/^(https?:)?\//)) {
+ url = options.root + '/' + url;
+ }
- if (query) {
- url += (url.indexOf('?') == -1 ? '?' : '&') + query;
- }
+ return url;
+}
- return url;
- }
+/**
+ * Query Parameter Transform.
+ */
- /**
- * URL Template v2.0.6 (https://github.com/bramstein/url-template)
- */
+function query (options, next) {
- function expand(url, params, variables) {
+ var urlParams = Object.keys(Url.options.params),
+ query = {},
+ url = next(options);
- var tmpl = parse(url),
- expanded = tmpl.expand(params);
+ each(options.params, function (value, key) {
+ if (urlParams.indexOf(key) === -1) {
+ query[key] = value;
+ }
+ });
- if (variables) {
- variables.push.apply(variables, tmpl.vars);
- }
+ query = Url.params(query);
- return expanded;
- }
+ if (query) {
+ url += (url.indexOf('?') == -1 ? '?' : '&') + query;
+ }
- function parse(template) {
-
- var operators = ['+', '#', '.', '/', ';', '?', '&'],
- variables = [];
-
- return {
- vars: variables,
- expand: function (context) {
- return template.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g, function (_, expression, literal) {
- if (expression) {
-
- var operator = null,
- values = [];
-
- if (operators.indexOf(expression.charAt(0)) !== -1) {
- operator = expression.charAt(0);
- expression = expression.substr(1);
- }
-
- expression.split(/,/g).forEach(function (variable) {
- var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable);
- values.push.apply(values, getValues(context, operator, tmp[1], tmp[2] || tmp[3]));
- variables.push(tmp[1]);
- });
-
- if (operator && operator !== '+') {
-
- var separator = ',';
-
- if (operator === '?') {
- separator = '&';
- } else if (operator !== '#') {
- separator = operator;
- }
-
- return (values.length !== 0 ? operator : '') + values.join(separator);
- } else {
- return values.join(',');
- }
- } else {
- return encodeReserved(literal);
- }
- });
- }
- };
- }
+ return url;
+}
- function getValues(context, operator, key, modifier) {
-
- var value = context[key],
- result = [];
-
- if (isDefined(value) && value !== '') {
- if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
- value = value.toString();
-
- if (modifier && modifier !== '*') {
- value = value.substring(0, parseInt(modifier, 10));
- }
-
- result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : null));
- } else {
- if (modifier === '*') {
- if (Array.isArray(value)) {
- value.filter(isDefined).forEach(function (value) {
- result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : null));
- });
- } else {
- Object.keys(value).forEach(function (k) {
- if (isDefined(value[k])) {
- result.push(encodeValue(operator, value[k], k));
- }
- });
- }
- } else {
- var tmp = [];
-
- if (Array.isArray(value)) {
- value.filter(isDefined).forEach(function (value) {
- tmp.push(encodeValue(operator, value));
- });
- } else {
- Object.keys(value).forEach(function (k) {
- if (isDefined(value[k])) {
- tmp.push(encodeURIComponent(k));
- tmp.push(encodeValue(operator, value[k].toString()));
- }
- });
- }
-
- if (isKeyOperator(operator)) {
- result.push(encodeURIComponent(key) + '=' + tmp.join(','));
- } else if (tmp.length !== 0) {
- result.push(tmp.join(','));
- }
- }
- }
- } else {
- if (operator === ';') {
- result.push(encodeURIComponent(key));
- } else if (value === '' && (operator === '&' || operator === '?')) {
- result.push(encodeURIComponent(key) + '=');
- } else if (value === '') {
- result.push('');
- }
- }
-
- return result;
- }
+/**
+ * URL Template v2.0.6 (https://github.com/bramstein/url-template)
+ */
- function isDefined(value) {
- return value !== undefined && value !== null;
- }
+function expand(url, params, variables) {
- function isKeyOperator(operator) {
- return operator === ';' || operator === '&' || operator === '?';
- }
+ var tmpl = parse(url),
+ expanded = tmpl.expand(params);
- function encodeValue(operator, value, key) {
+ if (variables) {
+ variables.push.apply(variables, tmpl.vars);
+ }
- value = operator === '+' || operator === '#' ? encodeReserved(value) : encodeURIComponent(value);
+ return expanded;
+}
+
+function parse(template) {
+
+ var operators = ['+', '#', '.', '/', ';', '?', '&'],
+ variables = [];
+
+ return {
+ vars: variables,
+ expand: function (context) {
+ return template.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g, function (_, expression, literal) {
+ if (expression) {
+
+ var operator = null,
+ values = [];
+
+ if (operators.indexOf(expression.charAt(0)) !== -1) {
+ operator = expression.charAt(0);
+ expression = expression.substr(1);
+ }
+
+ expression.split(/,/g).forEach(function (variable) {
+ var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable);
+ values.push.apply(values, getValues(context, operator, tmp[1], tmp[2] || tmp[3]));
+ variables.push(tmp[1]);
+ });
+
+ if (operator && operator !== '+') {
+
+ var separator = ',';
+
+ if (operator === '?') {
+ separator = '&';
+ } else if (operator !== '#') {
+ separator = operator;
+ }
+
+ return (values.length !== 0 ? operator : '') + values.join(separator);
+ } else {
+ return values.join(',');
+ }
+ } else {
+ return encodeReserved(literal);
+ }
+ });
+ }
+ };
+}
+
+function getValues(context, operator, key, modifier) {
+
+ var value = context[key],
+ result = [];
+
+ if (isDefined(value) && value !== '') {
+ if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
+ value = value.toString();
+
+ if (modifier && modifier !== '*') {
+ value = value.substring(0, parseInt(modifier, 10));
+ }
+
+ result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : null));
+ } else {
+ if (modifier === '*') {
+ if (Array.isArray(value)) {
+ value.filter(isDefined).forEach(function (value) {
+ result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : null));
+ });
+ } else {
+ Object.keys(value).forEach(function (k) {
+ if (isDefined(value[k])) {
+ result.push(encodeValue(operator, value[k], k));
+ }
+ });
+ }
+ } else {
+ var tmp = [];
+
+ if (Array.isArray(value)) {
+ value.filter(isDefined).forEach(function (value) {
+ tmp.push(encodeValue(operator, value));
+ });
+ } else {
+ Object.keys(value).forEach(function (k) {
+ if (isDefined(value[k])) {
+ tmp.push(encodeURIComponent(k));
+ tmp.push(encodeValue(operator, value[k].toString()));
+ }
+ });
+ }
+
+ if (isKeyOperator(operator)) {
+ result.push(encodeURIComponent(key) + '=' + tmp.join(','));
+ } else if (tmp.length !== 0) {
+ result.push(tmp.join(','));
+ }
+ }
+ }
+ } else {
+ if (operator === ';') {
+ result.push(encodeURIComponent(key));
+ } else if (value === '' && (operator === '&' || operator === '?')) {
+ result.push(encodeURIComponent(key) + '=');
+ } else if (value === '') {
+ result.push('');
+ }
+ }
- if (key) {
- return encodeURIComponent(key) + '=' + value;
- } else {
- return value;
- }
- }
+ return result;
+}
- function encodeReserved(str) {
- return str.split(/(%[0-9A-Fa-f]{2})/g).map(function (part) {
- if (!/%[0-9A-Fa-f]/.test(part)) {
- part = encodeURI(part);
- }
- return part;
- }).join('');
- }
+function isDefined(value) {
+ return value !== undefined && value !== null;
+}
- function template (options) {
+function isKeyOperator(operator) {
+ return operator === ';' || operator === '&' || operator === '?';
+}
- var variables = [],
- url = expand(options.url, options.params, variables);
+function encodeValue(operator, value, key) {
- variables.forEach(function (key) {
- delete options.params[key];
- });
+ value = operator === '+' || operator === '#' ? encodeReserved(value) : encodeURIComponent(value);
- return url;
- }
+ if (key) {
+ return encodeURIComponent(key) + '=' + value;
+ } else {
+ return value;
+ }
+}
+
+function encodeReserved(str) {
+ return str.split(/(%[0-9A-Fa-f]{2})/g).map(function (part) {
+ if (!/%[0-9A-Fa-f]/.test(part)) {
+ part = encodeURI(part);
+ }
+ return part;
+ }).join('');
+}
+
+/**
+ * URL Template (RFC 6570) Transform.
+ */
- /**
- * Service for URL templating.
- */
+function template (options) {
- var ie = document.documentMode;
- var el = document.createElement('a');
+ var variables = [],
+ url = expand(options.url, options.params, variables);
- function Url(url, params) {
+ variables.forEach(function (key) {
+ delete options.params[key];
+ });
- var self = this || {},
- options = url,
- transform;
+ return url;
+}
- if (isString(url)) {
- options = { url: url, params: params };
- }
+/**
+ * Service for URL templating.
+ */
- options = merge({}, Url.options, self.$options, options);
+var ie = document.documentMode;
+var el = document.createElement('a');
- Url.transforms.forEach(function (handler) {
- transform = factory(handler, transform, self.$vm);
- });
+function Url(url, params) {
- return transform(options);
- }
+ var self = this || {},
+ options = url,
+ transform;
- /**
- * Url options.
- */
+ if (isString(url)) {
+ options = { url: url, params: params };
+ }
- Url.options = {
- url: '',
- root: null,
- params: {}
- };
+ options = merge({}, Url.options, self.$options, options);
- /**
- * Url transforms.
- */
+ Url.transforms.forEach(function (handler) {
+ transform = factory(handler, transform, self.$vm);
+ });
- Url.transforms = [template, query, root];
+ return transform(options);
+}
- /**
- * Encodes a Url parameter string.
- *
- * @param {Object} obj
- */
+/**
+ * Url options.
+ */
- Url.params = function (obj) {
+Url.options = {
+ url: '',
+ root: null,
+ params: {}
+};
- var params = [],
- escape = encodeURIComponent;
+/**
+ * Url transforms.
+ */
- params.add = function (key, value) {
+Url.transforms = [template, query, root];
- if (isFunction(value)) {
- value = value();
- }
+/**
+ * Encodes a Url parameter string.
+ *
+ * @param {Object} obj
+ */
- if (value === null) {
- value = '';
- }
+Url.params = function (obj) {
- this.push(escape(key) + '=' + escape(value));
- };
+ var params = [],
+ escape = encodeURIComponent;
- serialize(params, obj);
+ params.add = function (key, value) {
- return params.join('&').replace(/%20/g, '+');
- };
+ if (isFunction(value)) {
+ value = value();
+ }
- /**
- * Parse a URL and return its components.
- *
- * @param {String} url
- */
+ if (value === null) {
+ value = '';
+ }
- Url.parse = function (url) {
+ this.push(escape(key) + '=' + escape(value));
+ };
- if (ie) {
- el.href = url;
- url = el.href;
- }
+ serialize(params, obj);
- el.href = url;
+ return params.join('&').replace(/%20/g, '+');
+};
- return {
- href: el.href,
- protocol: el.protocol ? el.protocol.replace(/:$/, '') : '',
- port: el.port,
- host: el.host,
- hostname: el.hostname,
- pathname: el.pathname.charAt(0) === '/' ? el.pathname : '/' + el.pathname,
- search: el.search ? el.search.replace(/^\?/, '') : '',
- hash: el.hash ? el.hash.replace(/^#/, '') : ''
- };
- };
+/**
+ * Parse a URL and return its components.
+ *
+ * @param {String} url
+ */
- function factory(handler, next, vm) {
- return function (options) {
- return handler.call(vm, options, next);
- };
- }
+Url.parse = function (url) {
- function serialize(params, obj, scope) {
+ if (ie) {
+ el.href = url;
+ url = el.href;
+ }
- var array = isArray(obj),
- plain = isPlainObject(obj),
- hash;
+ el.href = url;
+
+ return {
+ href: el.href,
+ protocol: el.protocol ? el.protocol.replace(/:$/, '') : '',
+ port: el.port,
+ host: el.host,
+ hostname: el.hostname,
+ pathname: el.pathname.charAt(0) === '/' ? el.pathname : '/' + el.pathname,
+ search: el.search ? el.search.replace(/^\?/, '') : '',
+ hash: el.hash ? el.hash.replace(/^#/, '') : ''
+ };
+};
+
+function factory(handler, next, vm) {
+ return function (options) {
+ return handler.call(vm, options, next);
+ };
+}
+
+function serialize(params, obj, scope) {
+
+ var array = isArray(obj),
+ plain = isPlainObject(obj),
+ hash;
+
+ each(obj, function (value, key) {
+
+ hash = isObject(value) || isArray(value);
+
+ if (scope) {
+ key = scope + '[' + (plain || hash ? key : '') + ']';
+ }
+
+ if (!scope && array) {
+ params.add(value.name, value.value);
+ } else if (hash) {
+ serialize(params, value, key);
+ } else {
+ params.add(key, value);
+ }
+ });
+}
+
+/**
+ * XDomain client (Internet Explorer).
+ */
- each(obj, function (value, key) {
+function xdrClient (request) {
+ return new Promise$1(function (resolve) {
- hash = isObject(value) || isArray(value);
+ var xdr = new XDomainRequest(),
+ handler = function (event) {
- if (scope) {
- key = scope + '[' + (plain || hash ? key : '') + ']';
- }
+ var response = request.respondWith(xdr.responseText, {
+ status: xdr.status,
+ statusText: xdr.statusText
+ });
- if (!scope && array) {
- params.add(value.name, value.value);
- } else if (hash) {
- serialize(params, value, key);
- } else {
- params.add(key, value);
- }
- });
- }
+ resolve(response);
+ };
- function xdrClient (request) {
- return new Promise$1(function (resolve) {
+ request.abort = function () {
+ return xdr.abort();
+ };
- var xdr = new XDomainRequest(),
- handler = function (event) {
+ xdr.open(request.method, request.getUrl(), true);
+ xdr.timeout = 0;
+ xdr.onload = handler;
+ xdr.onerror = handler;
+ xdr.ontimeout = function () {};
+ xdr.onprogress = function () {};
+ xdr.send(request.getBody());
+ });
+}
- var response = request.respondWith(xdr.responseText, {
- status: xdr.status,
- statusText: xdr.statusText
- });
+/**
+ * CORS Interceptor.
+ */
- resolve(response);
- };
+var ORIGIN_URL = Url.parse(location.href);
+var SUPPORTS_CORS = 'withCredentials' in new XMLHttpRequest();
- request.abort = function () {
- return xdr.abort();
- };
+function cors (request, next) {
- xdr.open(request.method, request.getUrl(), true);
- xdr.timeout = 0;
- xdr.onload = handler;
- xdr.onerror = handler;
- xdr.ontimeout = function () {};
- xdr.onprogress = function () {};
- xdr.send(request.getBody());
- });
- }
+ if (!isBoolean(request.crossOrigin) && crossOrigin(request)) {
+ request.crossOrigin = true;
+ }
- var ORIGIN_URL = Url.parse(location.href);
- var SUPPORTS_CORS = 'withCredentials' in new XMLHttpRequest();
+ if (request.crossOrigin) {
- function cors (request, next) {
+ if (!SUPPORTS_CORS) {
+ request.client = xdrClient;
+ }
- if (!isBoolean(request.crossOrigin) && crossOrigin(request)) {
- request.crossOrigin = true;
- }
+ delete request.emulateHTTP;
+ }
- if (request.crossOrigin) {
+ next();
+}
- if (!SUPPORTS_CORS) {
- request.client = xdrClient;
- }
+function crossOrigin(request) {
- delete request.emulateHTTP;
- }
+ var requestUrl = Url.parse(Url(request));
- next();
- }
+ return requestUrl.protocol !== ORIGIN_URL.protocol || requestUrl.host !== ORIGIN_URL.host;
+}
- function crossOrigin(request) {
+/**
+ * Body Interceptor.
+ */
- var requestUrl = Url.parse(Url(request));
+function body (request, next) {
- return requestUrl.protocol !== ORIGIN_URL.protocol || requestUrl.host !== ORIGIN_URL.host;
- }
+ if (request.emulateJSON && isPlainObject(request.body)) {
+ request.body = Url.params(request.body);
+ request.headers.set('Content-Type', 'application/x-www-form-urlencoded');
+ }
- function body (request, next) {
+ if (isFormData(request.body)) {
+ request.headers.delete('Content-Type');
+ }
- if (request.emulateJSON && isPlainObject(request.body)) {
- request.body = Url.params(request.body);
- request.headers['Content-Type'] = 'application/x-www-form-urlencoded';
- }
+ if (isPlainObject(request.body)) {
+ request.body = JSON.stringify(request.body);
+ }
- if (isFormData(request.body)) {
- delete request.headers['Content-Type'];
- }
+ next(function (response) {
- if (isPlainObject(request.body)) {
- request.body = JSON.stringify(request.body);
- }
+ Object.defineProperty(response, 'data', {
+ get: function () {
+ return this.body;
+ },
+ set: function (body) {
+ this.body = body;
+ }
+ });
- next(function (response) {
+ return response.bodyText ? when(response.text(), function (text) {
- var contentType = response.headers['Content-Type'];
+ var type = response.headers.get('Content-Type');
- if (isString(contentType) && contentType.indexOf('application/json') === 0) {
+ if (isString(type) && type.indexOf('application/json') === 0) {
- try {
- response.data = response.json();
- } catch (e) {
- response.data = null;
- }
- } else {
- response.data = response.text();
- }
- });
- }
+ try {
+ response.body = JSON.parse(text);
+ } catch (e) {
+ response.body = null;
+ }
+ } else {
+ response.body = text;
+ }
- function jsonpClient (request) {
- return new Promise$1(function (resolve) {
+ return response;
+ }) : response;
+ });
+}
- var name = request.jsonp || 'callback',
- callback = '_jsonp' + Math.random().toString(36).substr(2),
- body = null,
- handler,
- script;
+/**
+ * JSONP client.
+ */
- handler = function (event) {
+function jsonpClient (request) {
+ return new Promise$1(function (resolve) {
- var status = 0;
+ var name = request.jsonp || 'callback',
+ callback = '_jsonp' + Math.random().toString(36).substr(2),
+ body = null,
+ handler,
+ script;
- if (event.type === 'load' && body !== null) {
- status = 200;
- } else if (event.type === 'error') {
- status = 404;
- }
+ handler = function (event) {
- resolve(request.respondWith(body, { status: status }));
+ var status = 0;
- delete window[callback];
- document.body.removeChild(script);
- };
+ if (event.type === 'load' && body !== null) {
+ status = 200;
+ } else if (event.type === 'error') {
+ status = 404;
+ }
- request.params[name] = callback;
+ resolve(request.respondWith(body, { status: status }));
- window[callback] = function (result) {
- body = JSON.stringify(result);
- };
+ delete window[callback];
+ document.body.removeChild(script);
+ };
- script = document.createElement('script');
- script.src = request.getUrl();
- script.type = 'text/javascript';
- script.async = true;
- script.onload = handler;
- script.onerror = handler;
+ request.params[name] = callback;
- document.body.appendChild(script);
- });
- }
+ window[callback] = function (result) {
+ body = JSON.stringify(result);
+ };
- function jsonp (request, next) {
+ script = document.createElement('script');
+ script.src = request.getUrl();
+ script.type = 'text/javascript';
+ script.async = true;
+ script.onload = handler;
+ script.onerror = handler;
- if (request.method == 'JSONP') {
- request.client = jsonpClient;
- }
+ document.body.appendChild(script);
+ });
+}
- next(function (response) {
+/**
+ * JSONP Interceptor.
+ */
- if (request.method == 'JSONP') {
- response.data = response.json();
- }
- });
- }
+function jsonp (request, next) {
- function before (request, next) {
+ if (request.method == 'JSONP') {
+ request.client = jsonpClient;
+ }
- if (isFunction(request.before)) {
- request.before.call(this, request);
- }
+ next(function (response) {
- next();
- }
+ if (request.method == 'JSONP') {
- /**
- * HTTP method override Interceptor.
- */
+ return when(response.json(), function (json) {
- function method (request, next) {
+ response.body = json;
- if (request.emulateHTTP && /^(PUT|PATCH|DELETE)$/i.test(request.method)) {
- request.headers['X-HTTP-Method-Override'] = request.method;
- request.method = 'POST';
- }
+ return response;
+ });
+ }
+ });
+}
- next();
- }
+/**
+ * Before Interceptor.
+ */
- function header (request, next) {
+function before (request, next) {
- request.method = request.method.toUpperCase();
- request.headers = assign({}, Http.headers.common, !request.crossOrigin ? Http.headers.custom : {}, Http.headers[request.method.toLowerCase()], request.headers);
+ if (isFunction(request.before)) {
+ request.before.call(this, request);
+ }
- next();
- }
+ next();
+}
- /**
- * Timeout Interceptor.
- */
+/**
+ * HTTP method override Interceptor.
+ */
- function timeout (request, next) {
+function method (request, next) {
- var timeout;
+ if (request.emulateHTTP && /^(PUT|PATCH|DELETE)$/i.test(request.method)) {
+ request.headers.set('X-HTTP-Method-Override', request.method);
+ request.method = 'POST';
+ }
- if (request.timeout) {
- timeout = setTimeout(function () {
- request.abort();
- }, request.timeout);
- }
+ next();
+}
- next(function (response) {
+/**
+ * Header Interceptor.
+ */
- clearTimeout(timeout);
- });
- }
+function header (request, next) {
- function xhrClient (request) {
- return new Promise$1(function (resolve) {
+ var headers = assign({}, Http.headers.common, !request.crossOrigin ? Http.headers.custom : {}, Http.headers[toLower(request.method)]);
- var xhr = new XMLHttpRequest(),
- handler = function (event) {
+ each(headers, function (value, name) {
+ if (!request.headers.has(name)) {
+ request.headers.set(name, value);
+ }
+ });
- var response = request.respondWith('response' in xhr ? xhr.response : xhr.responseText, {
- status: xhr.status === 1223 ? 204 : xhr.status, // IE9 status bug
- statusText: xhr.status === 1223 ? 'No Content' : trim(xhr.statusText),
- headers: parseHeaders(xhr.getAllResponseHeaders())
- });
+ next();
+}
- resolve(response);
- };
+/**
+ * Timeout Interceptor.
+ */
- request.abort = function () {
- return xhr.abort();
- };
+function timeout (request, next) {
- xhr.open(request.method, request.getUrl(), true);
- xhr.timeout = 0;
- xhr.onload = handler;
- xhr.onerror = handler;
+ var timeout;
- if (request.progress) {
- if (request.method === 'GET') {
- xhr.addEventListener('progress', request.progress);
- } else if (/^(POST|PUT)$/i.test(request.method)) {
- xhr.upload.addEventListener('progress', request.progress);
- }
- }
+ if (request.timeout) {
+ timeout = setTimeout(function () {
+ request.abort();
+ }, request.timeout);
+ }
- if (request.credentials === true) {
- xhr.withCredentials = true;
- }
+ next(function (response) {
- each(request.headers || {}, function (value, header) {
- xhr.setRequestHeader(header, value);
- });
+ clearTimeout(timeout);
+ });
+}
- xhr.send(request.getBody());
- });
- }
+/**
+ * XMLHttp client.
+ */
- function parseHeaders(str) {
+function xhrClient (request) {
+ return new Promise$1(function (resolve) {
- var headers = {},
- value,
- name,
- i;
+ var xhr = new XMLHttpRequest(),
+ handler = function (event) {
- each(trim(str).split('\n'), function (row) {
+ var response = request.respondWith('response' in xhr ? xhr.response : xhr.responseText, {
+ status: xhr.status === 1223 ? 204 : xhr.status, // IE9 status bug
+ statusText: xhr.status === 1223 ? 'No Content' : trim(xhr.statusText)
+ });
- i = row.indexOf(':');
- name = trim(row.slice(0, i));
- value = trim(row.slice(i + 1));
+ each(trim(xhr.getAllResponseHeaders()).split('\n'), function (row) {
+ response.headers.append(row.slice(0, row.indexOf(':')), row.slice(row.indexOf(':') + 1));
+ });
- if (headers[name]) {
+ resolve(response);
+ };
- if (isArray(headers[name])) {
- headers[name].push(value);
- } else {
- headers[name] = [headers[name], value];
- }
- } else {
+ request.abort = function () {
+ return xhr.abort();
+ };
- headers[name] = value;
- }
- });
+ xhr.open(request.method, request.getUrl(), true);
+ xhr.timeout = 0;
+ xhr.onload = handler;
+ xhr.onerror = handler;
- return headers;
- }
+ if (request.progress) {
+ if (request.method === 'GET') {
+ xhr.addEventListener('progress', request.progress);
+ } else if (/^(POST|PUT)$/i.test(request.method)) {
+ xhr.upload.addEventListener('progress', request.progress);
+ }
+ }
- function Client (context) {
+ if ('responseType' in xhr) {
+ xhr.responseType = 'blob';
+ }
- var reqHandlers = [sendRequest],
- resHandlers = [],
- handler;
+ if (request.credentials === true) {
+ xhr.withCredentials = true;
+ }
- if (!isObject(context)) {
- context = null;
- }
+ request.headers.forEach(function (value, name) {
+ xhr.setRequestHeader(name, value);
+ });
- function Client(request) {
- return new Promise$1(function (resolve) {
+ xhr.send(request.getBody());
+ });
+}
- function exec() {
+/**
+ * Base client.
+ */
- handler = reqHandlers.pop();
+function Client (context) {
- if (isFunction(handler)) {
- handler.call(context, request, next);
- } else {
- warn('Invalid interceptor of type ' + typeof handler + ', must be a function');
- next();
- }
- }
+ var reqHandlers = [sendRequest],
+ resHandlers = [],
+ handler;
- function next(response) {
+ if (!isObject(context)) {
+ context = null;
+ }
- if (isFunction(response)) {
+ function Client(request) {
+ return new Promise$1(function (resolve) {
- resHandlers.unshift(response);
- } else if (isObject(response)) {
+ function exec() {
- resHandlers.forEach(function (handler) {
- response = when(response, function (response) {
- return handler.call(context, response) || response;
- });
- });
+ handler = reqHandlers.pop();
- when(response, resolve);
+ if (isFunction(handler)) {
+ handler.call(context, request, next);
+ } else {
+ warn('Invalid interceptor of type ' + typeof handler + ', must be a function');
+ next();
+ }
+ }
- return;
- }
+ function next(response) {
- exec();
- }
+ if (isFunction(response)) {
- exec();
- }, context);
- }
+ resHandlers.unshift(response);
+ } else if (isObject(response)) {
- Client.use = function (handler) {
- reqHandlers.push(handler);
- };
+ resHandlers.forEach(function (handler) {
+ response = when(response, function (response) {
+ return handler.call(context, response) || response;
+ });
+ });
- return Client;
- }
+ when(response, resolve);
- function sendRequest(request, resolve) {
+ return;
+ }
- var client = request.client || xhrClient;
+ exec();
+ }
- resolve(client(request));
+ exec();
+ }, context);
+ }
+
+ Client.use = function (handler) {
+ reqHandlers.push(handler);
+ };
+
+ return Client;
+}
+
+function sendRequest(request, resolve) {
+
+ var client = request.client || xhrClient;
+
+ resolve(client(request));
+}
+
+var classCallCheck = function (instance, Constructor) {
+ if (!(instance instanceof Constructor)) {
+ throw new TypeError("Cannot call a class as a function");
}
+};
+
+/**
+ * HTTP Headers.
+ */
+
+var Headers = function () {
+ function Headers(headers) {
+ var _this = this;
- var classCallCheck = function (instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
+ classCallCheck(this, Headers);
+
+
+ this.map = {};
+
+ each(headers, function (value, name) {
+ return _this.append(name, value);
+ });
}
- };
- /**
- * HTTP Response.
- */
+ Headers.prototype.has = function has(name) {
+ return this.map.hasOwnProperty(normalizeName(name));
+ };
- var Response = function () {
- function Response(body, _ref) {
- var url = _ref.url;
- var headers = _ref.headers;
- var status = _ref.status;
- var statusText = _ref.statusText;
- classCallCheck(this, Response);
+ Headers.prototype.get = function get(name) {
+ var list = this.map[normalizeName(name)];
- this.url = url;
- this.body = body;
- this.headers = headers || {};
- this.status = status || 0;
- this.statusText = statusText || '';
- this.ok = status >= 200 && status < 300;
- }
+ return list ? list[0] : null;
+ };
- Response.prototype.text = function text() {
- return this.body;
- };
+ Headers.prototype.getAll = function getAll(name) {
+ return this.map[normalizeName(name)] || [];
+ };
- Response.prototype.blob = function blob() {
- return new Blob([this.body]);
- };
+ Headers.prototype.set = function set(name, value) {
+ this.map[normalizeName(name)] = [trim(value)];
+ };
- Response.prototype.json = function json() {
- return JSON.parse(this.body);
- };
+ Headers.prototype.append = function append(name, value) {
- return Response;
- }();
+ var list = this.map[normalizeName(name)];
- var Request = function () {
- function Request(options) {
- classCallCheck(this, Request);
+ if (!list) {
+ list = this.map[normalizeName(name)] = [];
+ }
+ list.push(trim(value));
+ };
- this.method = 'GET';
- this.body = null;
- this.params = {};
- this.headers = {};
+ Headers.prototype.delete = function _delete(name) {
+ delete this.map[normalizeName(name)];
+ };
- assign(this, options);
- }
+ Headers.prototype.forEach = function forEach(callback, thisArg) {
+ var _this2 = this;
- Request.prototype.getUrl = function getUrl() {
- return Url(this);
- };
+ each(this.map, function (list, name) {
+ each(list, function (value) {
+ return callback.call(thisArg, value, name, _this2);
+ });
+ });
+ };
- Request.prototype.getBody = function getBody() {
- return this.body;
- };
+ return Headers;
+}();
- Request.prototype.respondWith = function respondWith(body, options) {
- return new Response(body, assign(options || {}, { url: this.getUrl() }));
- };
+function normalizeName(name) {
- return Request;
- }();
+ if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) {
+ throw new TypeError('Invalid character in header field name');
+ }
- /**
- * Service for sending network requests.
- */
+ return toLower(trim(name));
+}
- var CUSTOM_HEADERS = { 'X-Requested-With': 'XMLHttpRequest' };
- var COMMON_HEADERS = { 'Accept': 'application/json, text/plain, */*' };
- var JSON_CONTENT_TYPE = { 'Content-Type': 'application/json;charset=utf-8' };
+/**
+ * HTTP Response.
+ */
- function Http(options) {
+var Response = function () {
+ function Response(body, _ref) {
+ var url = _ref.url;
+ var headers = _ref.headers;
+ var status = _ref.status;
+ var statusText = _ref.statusText;
+ classCallCheck(this, Response);
- var self = this || {},
- client = Client(self.$vm);
- defaults(options || {}, self.$options, Http.options);
+ this.url = url;
+ this.ok = status >= 200 && status < 300;
+ this.status = status || 0;
+ this.statusText = statusText || '';
+ this.headers = new Headers(headers);
+ this.body = body;
- Http.interceptors.forEach(function (handler) {
- client.use(handler);
- });
+ if (isString(body)) {
- return client(new Request(options)).then(function (response) {
+ this.bodyText = body;
+ } else if (isBlob(body)) {
- return response.ok ? response : Promise$1.reject(response);
- }, function (response) {
+ this.bodyBlob = body;
- if (response instanceof Error) {
- error(response);
- }
+ if (isBlobText(body)) {
+ this.bodyText = blobText(body);
+ }
+ }
+ }
- return Promise$1.reject(response);
- });
- }
+ Response.prototype.blob = function blob() {
+ return when(this.bodyBlob);
+ };
- Http.options = {};
+ Response.prototype.text = function text() {
+ return when(this.bodyText);
+ };
- Http.headers = {
- put: JSON_CONTENT_TYPE,
- post: JSON_CONTENT_TYPE,
- patch: JSON_CONTENT_TYPE,
- delete: JSON_CONTENT_TYPE,
- custom: CUSTOM_HEADERS,
- common: COMMON_HEADERS
- };
+ Response.prototype.json = function json() {
+ return when(this.text(), function (text) {
+ return JSON.parse(text);
+ });
+ };
- Http.interceptors = [before, timeout, method, body, jsonp, header, cors];
+ return Response;
+}();
- ['get', 'delete', 'head', 'jsonp'].forEach(function (method) {
+function blobText(body) {
+ return new Promise$1(function (resolve) {
- Http[method] = function (url, options) {
- return this(assign(options || {}, { url: url, method: method }));
- };
- });
+ var reader = new FileReader();
- ['post', 'put', 'patch'].forEach(function (method) {
+ reader.readAsText(body);
+ reader.onload = function () {
+ resolve(reader.result);
+ };
+ });
+}
- Http[method] = function (url, body, options) {
- return this(assign(options || {}, { url: url, method: method, body: body }));
- };
- });
+function isBlobText(body) {
+ return body.type.indexOf('text') === 0 || body.type.indexOf('json') !== -1;
+}
- function Resource(url, params, actions, options) {
+/**
+ * HTTP Request.
+ */
- var self = this || {},
- resource = {};
+var Request = function () {
+ function Request(options) {
+ classCallCheck(this, Request);
- actions = assign({}, Resource.actions, actions);
- each(actions, function (action, name) {
+ this.body = null;
+ this.params = {};
- action = merge({ url: url, params: params || {} }, options, action);
+ assign(this, options, {
+ method: toUpper(options.method || 'GET'),
+ headers: new Headers(options.headers)
+ });
+ }
- resource[name] = function () {
- return (self.$http || Http)(opts(action, arguments));
- };
- });
+ Request.prototype.getUrl = function getUrl() {
+ return Url(this);
+ };
- return resource;
- }
+ Request.prototype.getBody = function getBody() {
+ return this.body;
+ };
- function opts(action, args) {
+ Request.prototype.respondWith = function respondWith(body, options) {
+ return new Response(body, assign(options || {}, { url: this.getUrl() }));
+ };
- var options = assign({}, action),
- params = {},
- body;
+ return Request;
+}();
- switch (args.length) {
+/**
+ * Service for sending network requests.
+ */
- case 2:
+var CUSTOM_HEADERS = { 'X-Requested-With': 'XMLHttpRequest' };
+var COMMON_HEADERS = { 'Accept': 'application/json, text/plain, */*' };
+var JSON_CONTENT_TYPE = { 'Content-Type': 'application/json;charset=utf-8' };
- params = args[0];
- body = args[1];
+function Http(options) {
- break;
+ var self = this || {},
+ client = Client(self.$vm);
- case 1:
+ defaults(options || {}, self.$options, Http.options);
- if (/^(POST|PUT|PATCH)$/i.test(options.method)) {
- body = args[0];
- } else {
- params = args[0];
- }
+ Http.interceptors.forEach(function (handler) {
+ client.use(handler);
+ });
- break;
+ return client(new Request(options)).then(function (response) {
- case 0:
+ return response.ok ? response : Promise$1.reject(response);
+ }, function (response) {
- break;
+ if (response instanceof Error) {
+ error(response);
+ }
- default:
+ return Promise$1.reject(response);
+ });
+}
- throw 'Expected up to 4 arguments [params, body], got ' + args.length + ' arguments';
- }
+Http.options = {};
- options.body = body;
- options.params = assign({}, options.params, params);
+Http.headers = {
+ put: JSON_CONTENT_TYPE,
+ post: JSON_CONTENT_TYPE,
+ patch: JSON_CONTENT_TYPE,
+ delete: JSON_CONTENT_TYPE,
+ custom: CUSTOM_HEADERS,
+ common: COMMON_HEADERS
+};
- return options;
- }
+Http.interceptors = [before, timeout, method, body, jsonp, header, cors];
+
+['get', 'delete', 'head', 'jsonp'].forEach(function (method) {
- Resource.actions = {
+ Http[method] = function (url, options) {
+ return this(assign(options || {}, { url: url, method: method }));
+ };
+});
- get: { method: 'GET' },
- save: { method: 'POST' },
- query: { method: 'GET' },
- update: { method: 'PUT' },
- remove: { method: 'DELETE' },
- delete: { method: 'DELETE' }
+['post', 'put', 'patch'].forEach(function (method) {
- };
+ Http[method] = function (url, body, options) {
+ return this(assign(options || {}, { url: url, method: method, body: body }));
+ };
+});
- function plugin(Vue) {
+/**
+ * Promises/A+ polyfill v1.1.4 (https://github.com/bramstein/promis)
+ */
- if (plugin.installed) {
- return;
- }
+var RESOLVED = 0;
+var REJECTED = 1;
+var PENDING = 2;
- Util(Vue);
+function Promise$2(executor) {
- Vue.url = Url;
- Vue.http = Http;
- Vue.resource = Resource;
- Vue.Promise = Promise$1;
+ this.state = PENDING;
+ this.value = undefined;
+ this.deferred = [];
- Object.defineProperties(Vue.prototype, {
+ var promise = this;
+
+ try {
+ executor(function (x) {
+ promise.resolve(x);
+ }, function (r) {
+ promise.reject(r);
+ });
+ } catch (e) {
+ promise.reject(e);
+ }
+}
+
+Promise$2.reject = function (r) {
+ return new Promise$2(function (resolve, reject) {
+ reject(r);
+ });
+};
+
+Promise$2.resolve = function (x) {
+ return new Promise$2(function (resolve, reject) {
+ resolve(x);
+ });
+};
+
+Promise$2.all = function all(iterable) {
+ return new Promise$2(function (resolve, reject) {
+ var count = 0,
+ result = [];
+
+ if (iterable.length === 0) {
+ resolve(result);
+ }
+
+ function resolver(i) {
+ return function (x) {
+ result[i] = x;
+ count += 1;
+
+ if (count === iterable.length) {
+ resolve(result);
+ }
+ };
+ }
+
+ for (var i = 0; i < iterable.length; i += 1) {
+ Promise$2.resolve(iterable[i]).then(resolver(i), reject);
+ }
+ });
+};
+
+Promise$2.race = function race(iterable) {
+ return new Promise$2(function (resolve, reject) {
+ for (var i = 0; i < iterable.length; i += 1) {
+ Promise$2.resolve(iterable[i]).then(resolve, reject);
+ }
+ });
+};
+
+var p$1 = Promise$2.prototype;
+
+p$1.resolve = function resolve(x) {
+ var promise = this;
+
+ if (promise.state === PENDING) {
+ if (x === promise) {
+ throw new TypeError('Promise settled with itself.');
+ }
+
+ var called = false;
+
+ try {
+ var then = x && x['then'];
+
+ if (x !== null && typeof x === 'object' && typeof then === 'function') {
+ then.call(x, function (x) {
+ if (!called) {
+ promise.resolve(x);
+ }
+ called = true;
+ }, function (r) {
+ if (!called) {
+ promise.reject(r);
+ }
+ called = true;
+ });
+ return;
+ }
+ } catch (e) {
+ if (!called) {
+ promise.reject(e);
+ }
+ return;
+ }
+
+ promise.state = RESOLVED;
+ promise.value = x;
+ promise.notify();
+ }
+};
- $url: {
- get: function () {
- return options(Vue.url, this, this.$options.url);
- }
- },
+p$1.reject = function reject(reason) {
+ var promise = this;
- $http: {
- get: function () {
- return options(Vue.http, this, this.$options.http);
- }
- },
+ if (promise.state === PENDING) {
+ if (reason === promise) {
+ throw new TypeError('Promise settled with itself.');
+ }
- $resource: {
- get: function () {
- return Vue.resource.bind(this);
- }
- },
+ promise.state = REJECTED;
+ promise.value = reason;
+ promise.notify();
+ }
+};
+
+p$1.notify = function notify() {
+ var promise = this;
+
+ nextTick(function () {
+ if (promise.state !== PENDING) {
+ while (promise.deferred.length) {
+ var deferred = promise.deferred.shift(),
+ onResolved = deferred[0],
+ onRejected = deferred[1],
+ resolve = deferred[2],
+ reject = deferred[3];
+
+ try {
+ if (promise.state === RESOLVED) {
+ if (typeof onResolved === 'function') {
+ resolve(onResolved.call(undefined, promise.value));
+ } else {
+ resolve(promise.value);
+ }
+ } else if (promise.state === REJECTED) {
+ if (typeof onRejected === 'function') {
+ resolve(onRejected.call(undefined, promise.value));
+ } else {
+ reject(promise.value);
+ }
+ }
+ } catch (e) {
+ reject(e);
+ }
+ }
+ }
+ });
+};
+
+p$1.then = function then(onResolved, onRejected) {
+ var promise = this;
+
+ return new Promise$2(function (resolve, reject) {
+ promise.deferred.push([onResolved, onRejected, resolve, reject]);
+ promise.notify();
+ });
+};
+
+p$1.catch = function (onRejected) {
+ return this.then(undefined, onRejected);
+};
+
+/**
+ * Service for interacting with RESTful services.
+ */
- $promise: {
- get: function () {
- var _this = this;
+function Resource(url, params, actions, options) {
- return function (executor) {
- return new Vue.Promise(executor, _this);
- };
- }
- }
+ var self = this || {},
+ resource = {};
- });
- }
+ actions = assign({}, Resource.actions, actions);
- if (typeof window !== 'undefined' && window.Vue) {
- window.Vue.use(plugin);
- }
+ each(actions, function (action, name) {
+
+ action = merge({ url: url, params: assign({}, params) }, options, action);
+
+ resource[name] = function () {
+ return (self.$http || Http)(opts(action, arguments));
+ };
+ });
+
+ return resource;
+}
+
+function opts(action, args) {
+
+ var options = assign({}, action),
+ params = {},
+ body;
+
+ switch (args.length) {
+
+ case 2:
+
+ params = args[0];
+ body = args[1];
+
+ break;
+
+ case 1:
+
+ if (/^(POST|PUT|PATCH)$/i.test(options.method)) {
+ body = args[0];
+ } else {
+ params = args[0];
+ }
+
+ break;
+
+ case 0:
+
+ break;
+
+ default:
+
+ throw 'Expected up to 4 arguments [params, body], got ' + args.length + ' arguments';
+ }
+
+ options.body = body;
+ options.params = assign({}, options.params, params);
+
+ return options;
+}
+
+Resource.actions = {
+
+ get: { method: 'GET' },
+ save: { method: 'POST' },
+ query: { method: 'GET' },
+ update: { method: 'PUT' },
+ remove: { method: 'DELETE' },
+ delete: { method: 'DELETE' }
+
+};
+
+/**
+ * Install plugin.
+ */
+
+function plugin(Vue) {
+
+ if (plugin.installed) {
+ return;
+ }
+
+ Util(Vue);
+
+ Vue.url = Url;
+ Vue.http = Http;
+ Vue.resource = Resource;
+ Vue.Promise = Promise$1;
+
+ Object.defineProperties(Vue.prototype, {
+
+ $url: {
+ get: function () {
+ return options(Vue.url, this, this.$options.url);
+ }
+ },
+
+ $http: {
+ get: function () {
+ return options(Vue.http, this, this.$options.http);
+ }
+ },
+
+ $resource: {
+ get: function () {
+ return Vue.resource.bind(this);
+ }
+ },
+
+ $promise: {
+ get: function () {
+ var _this = this;
+
+ return function (executor) {
+ return new Vue.Promise(executor, _this);
+ };
+ }
+ }
+
+ });
+}
+
+if (typeof window !== 'undefined') {
+
+ if (!window.Promise) {
+ window.Promise = Promise$2;
+ }
+
+ if (window.Vue) {
+ window.Vue.use(plugin);
+ }
+}
- return plugin;
+return plugin;
-}));
\ No newline at end of file
+})));
\ No newline at end of file
diff --git a/dist/vue-resource.min.js b/dist/vue-resource.min.js
index 6bff73a2..87766ee7 100644
--- a/dist/vue-resource.min.js
+++ b/dist/vue-resource.min.js
@@ -1,7 +1,7 @@
/*!
- * vue-resource v0.9.3
+ * vue-resource v1.0.0
* https://github.com/vuejs/vue-resource
* Released under the MIT License.
*/
-!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):t.VueResource=n()}(this,function(){"use strict";function t(t){this.state=Z,this.value=void 0,this.deferred=[];var n=this;try{t(function(t){n.resolve(t)},function(t){n.reject(t)})}catch(e){n.reject(e)}}function n(t,n){t instanceof nt?this.promise=t:this.promise=new nt(t.bind(n)),this.context=n}function e(t){rt=t.util,ot=t.config.debug||!t.config.silent}function o(t){"undefined"!=typeof console&&ot&&console.warn("[VueResource warn]: "+t)}function r(t){"undefined"!=typeof console&&console.error(t)}function i(t,n){return rt.nextTick(t,n)}function u(t){return t.replace(/^\s*|\s*$/g,"")}function s(t){return"string"==typeof t}function c(t){return t===!0||t===!1}function a(t){return"function"==typeof t}function f(t){return null!==t&&"object"==typeof t}function h(t){return f(t)&&Object.getPrototypeOf(t)==Object.prototype}function p(t){return"undefined"!=typeof FormData&&t instanceof FormData}function l(t,e,o){var r=n.resolve(t);return arguments.length<2?r:r.then(e,o)}function d(t,n,e){return e=e||{},a(e)&&(e=e.call(n)),v(t.bind({$vm:n,$options:e}),t,{$options:e})}function m(t,n){var e,o;if("number"==typeof t.length)for(e=0;e=200&&i<300}return t.prototype.text=function(){return this.body},t.prototype.blob=function(){return new Blob([this.body])},t.prototype.json=function(){return JSON.parse(this.body)},t}(),dt=function(){function t(n){pt(this,t),this.method="GET",this.body=null,this.params={},this.headers={},st(this,n)}return t.prototype.getUrl=function(){return R(this)},t.prototype.getBody=function(){return this.body},t.prototype.respondWith=function(t,n){return new lt(t,st(n||{},{url:this.getUrl()}))},t}(),mt={"X-Requested-With":"XMLHttpRequest"},vt={Accept:"application/json, text/plain, */*"},yt={"Content-Type":"application/json;charset=utf-8"};return V.options={},V.headers={put:yt,post:yt,patch:yt,"delete":yt,custom:mt,common:vt},V.interceptors=[D,X,J,L,N,M,H],["get","delete","head","jsonp"].forEach(function(t){V[t]=function(n,e){return this(st(e||{},{url:n,method:t}))}}),["post","put","patch"].forEach(function(t){V[t]=function(n,e,o){return this(st(o||{},{url:n,method:t,body:e}))}}),_.actions={get:{method:"GET"},save:{method:"POST"},query:{method:"GET"},update:{method:"PUT"},remove:{method:"DELETE"},"delete":{method:"DELETE"}},"undefined"!=typeof window&&window.Vue&&window.Vue.use(K),K});
\ No newline at end of file
+!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):t.VueResource=n()}(this,function(){"use strict";function t(t,n){t instanceof et?this.promise=t:this.promise=new et(t.bind(n)),this.context=n}function n(t){it=t.util,rt=t.config.debug||!t.config.silent}function e(t){"undefined"!=typeof console&&rt&&console.warn("[VueResource warn]: "+t)}function o(t){"undefined"!=typeof console&&console.error(t)}function r(t,n){return it.nextTick(t,n)}function i(t){return t.replace(/^\s*|\s*$/g,"")}function u(t){return t?t.toLowerCase():""}function s(t){return t?t.toUpperCase():""}function c(t){return"string"==typeof t}function a(t){return t===!0||t===!1}function f(t){return"function"==typeof t}function p(t){return null!==t&&"object"==typeof t}function h(t){return p(t)&&Object.getPrototypeOf(t)==Object.prototype}function l(t){return"undefined"!=typeof Blob&&t instanceof Blob}function d(t){return"undefined"!=typeof FormData&&t instanceof FormData}function m(n,e,o){var r=t.resolve(n);return arguments.length<2?r:r.then(e,o)}function y(t,n,e){return e=e||{},f(e)&&(e=e.call(n)),b(t.bind({$vm:n,$options:e}),t,{$options:e})}function v(t,n){var e,o;if(t&&"number"==typeof t.length)for(e=0;e=200&&i<300,this.status=i||0,this.statusText=u||"",this.headers=new dt(r),this.body=n,c(n)?this.bodyText=n:l(n)&&(this.bodyBlob=n,K(n)&&(this.bodyText=z(n)))}return t.prototype.blob=function(){return m(this.bodyBlob)},t.prototype.text=function(){return m(this.bodyText)},t.prototype.json=function(){return m(this.text(),function(t){return JSON.parse(t)})},t}(),yt=function(){function t(n){lt(this,t),this.body=null,this.params={},ct(this,n,{method:s(n.method||"GET"),headers:new dt(n.headers)})}return t.prototype.getUrl=function(){return S(this)},t.prototype.getBody=function(){return this.body},t.prototype.respondWith=function(t,n){return new mt(t,ct(n||{},{url:this.getUrl()}))},t}(),vt={"X-Requested-With":"XMLHttpRequest"},bt={Accept:"application/json, text/plain, */*"},wt={"Content-Type":"application/json;charset=utf-8"};Q.options={},Q.headers={put:wt,post:wt,patch:wt,delete:wt,custom:vt,common:bt},Q.interceptors=[D,F,M,q,J,X,L],["get","delete","head","jsonp"].forEach(function(t){Q[t]=function(n,e){return this(ct(e||{},{url:n,method:t}))}}),["post","put","patch"].forEach(function(t){Q[t]=function(n,e,o){return this(ct(o||{},{url:n,method:t,body:e}))}});var gt=0,Tt=1,xt=2;Y.reject=function(t){return new Y(function(n,e){e(t)})},Y.resolve=function(t){return new Y(function(n,e){n(t)})},Y.all=function(t){return new Y(function(n,e){function o(e){return function(o){i[e]=o,r+=1,r===t.length&&n(i)}}var r=0,i=[];0===t.length&&n(i);for(var u=0;u {
- // success callback
- }, (response) => {
- // error callback
- });
-
- }
-
-})
+{
+ // GET /someUrl
+ this.$http.get('/someUrl').then((response) => {
+ // success callback
+ }, (response) => {
+ // error callback
+ });
+}
```
## Methods
@@ -51,10 +45,10 @@ List of shortcut methods:
Parameter | Type | Description
--------- | ---- | -----------
url | `string` | URL to which the request is sent
-method | `string` | HTTP method (e.g. GET, POST, ...)
-body | `Object`, `FormData` `string` | Data to be sent as the request body
-params | `Object` | Parameters object to be sent as URL parameters
+body | `Object`, `FormData`, `string` | Data to be sent as the request body
headers | `Object` | Headers object to be sent as HTTP request headers
+params | `Object` | Parameters object to be sent as URL parameters
+method | `string` | HTTP method (e.g. GET, POST, ...)
timeout | `number` | Request timeout in milliseconds (`0` means no timeout)
before | `function(request)` | Callback function to modify the request options before it is sent
progress | `function(event)` | Callback function to handle the [ProgressEvent](https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent) of uploads
@@ -66,49 +60,58 @@ emulateJSON | `boolean` | Send request body as `application/x-www-form-urlencode
A request resolves to a response object with the following properties and methods:
-Method | Type | Description
+Property | Type | Description
-------- | ---- | -----------
-text() | `string` | Response body as string
-json() | `Object` | Response body as parsed JSON object
-blob() | `Blob` | Response body as Blob object
-**Property** | **Type** | **Description**
+url | `string` | Response URL origin
+body | `Object`, `Blob`, `string` | Response body data
+headers | `Header` | Response Headers object
ok | `boolean` | HTTP status code between 200 and 299
status | `number` | HTTP status code of the response
statusText | `string` | HTTP status text of the response
-headers | `Object` | HTTP headers of the response
+**Method** | **Type** | **Description**
+text() | `Promise` | Resolves the body as string
+json() | `Promise` | Resolves the body as parsed JSON object
+blob() | `Promise` | Resolves the body as Blob object
## Example
```js
-new Vue({
-
- ready() {
+{
+ // POST /someUrl
+ this.$http.post('/someUrl', {foo: 'bar'}).then((response) => {
- // POST /someUrl
- this.$http.post('/someUrl', {foo: 'bar'}).then((response) => {
+ // get status
+ response.status;
- // get status
- response.status;
+ // get status text
+ response.statusText;
- // get status text
- response.statusText;
+ // get 'Expires' header
+ response.headers.get('Expires');
- // get all headers
- response.headers;
+ // set data on vm
+ this.$set('someData', response.body);
- // get 'Expires' header
- response.headers['Expires'];
+ }, (response) => {
+ // error callback
+ });
+}
+```
- // set data on vm
- this.$set('someData', response.json())
+Fetch an image and use the blob() method to extract the image body content from the response.
- }, (response) => {
- // error callback
- });
+```js
+{
+ // GET /image.jpg
+ this.$http.get('/image.jpg').then((response) => {
- }
+ // resolve to Blob
+ return response.blob();
-})
+ }).then(blob) => {
+ // use image Blob
+ });
+}
```
## Interceptors
@@ -119,11 +122,11 @@ Interceptors can be defined globally and are used for pre- and postprocessing of
```js
Vue.http.interceptors.push((request, next) => {
- // modify request
- request.method = 'POST';
+ // modify request
+ request.method = 'POST';
- // continue to next interceptor
- next();
+ // continue to next interceptor
+ next();
});
```
@@ -131,16 +134,16 @@ Vue.http.interceptors.push((request, next) => {
```js
Vue.http.interceptors.push((request, next) => {
- // modify request
- request.method = 'POST';
+ // modify request
+ request.method = 'POST';
- // continue to next interceptor
- next((response) => {
+ // continue to next interceptor
+ next((response) => {
- // modify response
- response.body = '...';
+ // modify response
+ response.body = '...';
- });
+ });
});
```
@@ -148,12 +151,12 @@ Vue.http.interceptors.push((request, next) => {
```js
Vue.http.interceptors.push((request, next) => {
- // modify request ...
+ // modify request ...
- // stop and return response
- next(request.respondWith(body, {
- status: 404,
- statusText: 'Not found'
- }));
+ // stop and return response
+ next(request.respondWith(body, {
+ status: 404,
+ statusText: 'Not found'
+ }));
});
```
diff --git a/docs/recipes.md b/docs/recipes.md
index 0da6c0b5..201692db 100644
--- a/docs/recipes.md
+++ b/docs/recipes.md
@@ -8,20 +8,20 @@ Sending forms using [FormData](https://developer.mozilla.org/en-US/docs/Web/API/
```js
{
- var formData = new FormData();
+ var formData = new FormData();
- // append string
- formData.append('foo', 'bar');
+ // append string
+ formData.append('foo', 'bar');
- // append Blob/File object
- formData.append('pic', fileInput, 'mypic.jpg');
+ // append Blob/File object
+ formData.append('pic', fileInput, 'mypic.jpg');
- // POST /someUrl
- this.$http.post('/someUrl', formData).then((response) => {
- // success callback
- }, (response) => {
- // error callback
- });
+ // POST /someUrl
+ this.$http.post('/someUrl', formData).then((response) => {
+ // success callback
+ }, (response) => {
+ // error callback
+ });
}
```
@@ -31,25 +31,25 @@ Abort a previous request when a new request is about to be sent. For example whe
```js
{
- // GET /someUrl
- this.$http.get('/someUrl', {
-
- // use before callback
- before(request) {
-
- // abort previous request, if exists
- if (this.previousRequest) {
- this.previousRequest.abort();
- }
-
- // set previous request on Vue instance
- this.previousRequest = request;
- }
-
- }).then((response) => {
- // success callback
- }, (response) => {
- // error callback
- });
+ // GET /someUrl
+ this.$http.get('/someUrl', {
+
+ // use before callback
+ before(request) {
+
+ // abort previous request, if exists
+ if (this.previousRequest) {
+ this.previousRequest.abort();
+ }
+
+ // set previous request on Vue instance
+ this.previousRequest = request;
+ }
+
+ }).then((response) => {
+ // success callback
+ }, (response) => {
+ // error callback
+ });
}
```
diff --git a/docs/resource.md b/docs/resource.md
index 7834f589..cc390fd1 100644
--- a/docs/resource.md
+++ b/docs/resource.md
@@ -20,63 +20,51 @@ delete: {method: 'DELETE'}
## Example
```js
-new Vue({
-
- ready() {
-
- var resource = this.$resource('someItem{/id}');
-
- // GET someItem/1
- resource.get({id: 1}).then((response) => {
- this.$set('item', response.json())
- });
-
- // POST someItem/1
- resource.save({id: 1}, {item: this.item}).then((response) => {
- // success callback
- }, (response) => {
- // error callback
- });
-
- // DELETE someItem/1
- resource.delete({id: 1}).then((response) => {
- // success callback
- }, (response) => {
- // error callback
- });
-
- }
-
-})
+{
+ var resource = this.$resource('someItem{/id}');
+
+ // GET someItem/1
+ resource.get({id: 1}).then((response) => {
+ this.$set('item', response.json())
+ });
+
+ // POST someItem/1
+ resource.save({id: 1}, {item: this.item}).then((response) => {
+ // success callback
+ }, (response) => {
+ // error callback
+ });
+
+ // DELETE someItem/1
+ resource.delete({id: 1}).then((response) => {
+ // success callback
+ }, (response) => {
+ // error callback
+ });
+}
```
## Custom Actions
```js
-new Vue({
-
- ready() {
-
- var customActions = {
- foo: {method: 'GET', url: 'someItem/foo{/id}'},
- bar: {method: 'POST', url: 'someItem/bar{/id}'}
- }
-
- var resource = this.$resource('someItem{/id}', {}, customActions);
-
- // GET someItem/foo/1
- resource.foo({id: 1}).then((response) => {
- this.$set('item', response.json())
- });
-
- // POST someItem/bar/1
- resource.bar({id: 1}, {item: this.item}).then((response) => {
- // success callback
- }, (response) => {
- // error callback
- });
-
- }
-
-})
+{
+ var customActions = {
+ foo: {method: 'GET', url: 'someItem/foo{/id}'},
+ bar: {method: 'POST', url: 'someItem/bar{/id}'}
+ }
+
+ var resource = this.$resource('someItem{/id}', {}, customActions);
+
+ // GET someItem/foo/1
+ resource.foo({id: 1}).then((response) => {
+ this.$set('item', response.json())
+ });
+
+ // POST someItem/bar/1
+ resource.bar({id: 1}, {item: this.item}).then((response) => {
+ // success callback
+ }, (response) => {
+ // error callback
+ });
+}
```
diff --git a/package.json b/package.json
index 6f71c44a..0d393eda 100644
--- a/package.json
+++ b/package.json
@@ -1,42 +1,42 @@
{
"name": "vue-resource",
- "version": "0.9.3",
- "description": "A web request service for Vue.js",
+ "version": "1.0.0",
"main": "dist/vue-resource.common.js",
"jsnext:main": "dist/vue-resource.es2015.js",
- "scripts": {
- "test": "webpack --config test/webpack.config.js",
- "build": "node build/build.js",
- "release": "node build/release.js"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/vuejs/vue-resource.git"
- },
+ "description": "The HTTP client for Vue.js",
+ "homepage": "https://github.com/vuejs/vue-resource#readme",
+ "license": "MIT",
"keywords": [
"vue",
- "vuejs",
- "resource",
- "mvvm"
+ "xhr",
+ "http",
+ "ajax"
],
- "license": "MIT",
"bugs": {
"url": "https://github.com/vuejs/vue-resource/issues"
},
- "homepage": "https://github.com/vuejs/vue-resource#readme",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/vuejs/vue-resource.git"
+ },
+ "scripts": {
+ "test": "webpack --config test/webpack.config.js",
+ "build": "node build/build.js",
+ "release": "node build/release.js"
+ },
"devDependencies": {
- "babel-core": "^6.10.4",
- "babel-loader": "^6.2.4",
- "babel-plugin-transform-runtime": "^6.9.0",
- "babel-preset-es2015-loose": "^7.0.0",
+ "babel-core": "^6.14.0",
+ "babel-loader": "^6.2.5",
+ "babel-plugin-transform-runtime": "^6.15.0",
+ "babel-preset-es2015": "^6.14.0",
"babel-preset-es2015-loose-rollup": "^7.0.0",
- "babel-runtime": "^6.9.2",
- "jasmine-core": "^2.3.4",
- "replace-in-file": "^1.1.1",
- "rollup": "^0.33.0",
+ "generate-release": "^0.10.1",
+ "jasmine-core": "^2.5.0",
+ "replace-in-file": "^2.0.1",
+ "rollup": "^0.34.13",
"rollup-plugin-babel": "^2.6.1",
- "uglify-js": "^2.6.4",
+ "uglify-js": "^2.7.3",
"vue": "^1.0.26",
- "webpack": "^1.13.1"
+ "webpack": "2.1.0-beta.21"
}
}
diff --git a/src/http/client/xhr.js b/src/http/client/xhr.js
index 61ea7bc0..87ad48ac 100644
--- a/src/http/client/xhr.js
+++ b/src/http/client/xhr.js
@@ -3,7 +3,7 @@
*/
import Promise from '../../promise';
-import { each, trim, isArray } from '../../util';
+import { each, trim } from '../../util';
export default function (request) {
return new Promise((resolve) => {
@@ -13,11 +13,14 @@ export default function (request) {
var response = request.respondWith(
'response' in xhr ? xhr.response : xhr.responseText, {
status: xhr.status === 1223 ? 204 : xhr.status, // IE9 status bug
- statusText: xhr.status === 1223 ? 'No Content' : trim(xhr.statusText),
- headers: parseHeaders(xhr.getAllResponseHeaders()),
+ statusText: xhr.status === 1223 ? 'No Content' : trim(xhr.statusText)
}
);
+ each(trim(xhr.getAllResponseHeaders()).split('\n'), (row) => {
+ response.headers.append(row.slice(0, row.indexOf(':')), row.slice(row.indexOf(':') + 1));
+ });
+
resolve(response);
};
@@ -36,42 +39,18 @@ export default function (request) {
}
}
+ if ('responseType' in xhr) {
+ xhr.responseType = 'blob';
+ }
+
if (request.credentials === true) {
xhr.withCredentials = true;
}
- each(request.headers || {}, (value, header) => {
- xhr.setRequestHeader(header, value);
+ request.headers.forEach((value, name) => {
+ xhr.setRequestHeader(name, value);
});
xhr.send(request.getBody());
});
}
-
-function parseHeaders(str) {
-
- var headers = {}, value, name, i;
-
- each(trim(str).split('\n'), (row) => {
-
- i = row.indexOf(':');
- name = trim(row.slice(0, i));
- value = trim(row.slice(i + 1));
-
- if (headers[name]) {
-
- if (isArray(headers[name])) {
- headers[name].push(value);
- } else {
- headers[name] = [headers[name], value];
- }
-
- } else {
-
- headers[name] = value;
- }
-
- });
-
- return headers;
-}
diff --git a/src/http/headers.js b/src/http/headers.js
new file mode 100644
index 00000000..b758d0e0
--- /dev/null
+++ b/src/http/headers.js
@@ -0,0 +1,65 @@
+/**
+ * HTTP Headers.
+ */
+
+import { each, trim, toLower } from '../util';
+
+export default class Headers {
+
+ constructor(headers) {
+
+ this.map = {};
+
+ each(headers, (value, name) => this.append(name, value));
+ }
+
+ has(name) {
+ return this.map.hasOwnProperty(normalizeName(name));
+ }
+
+ get(name) {
+
+ var list = this.map[normalizeName(name)];
+
+ return list ? list[0] : null;
+ }
+
+ getAll(name) {
+ return this.map[normalizeName(name)] || [];
+ }
+
+ set(name, value) {
+ this.map[normalizeName(name)] = [trim(value)];
+ }
+
+ append(name, value){
+
+ var list = this.map[normalizeName(name)];
+
+ if (!list) {
+ list = this.map[normalizeName(name)] = [];
+ }
+
+ list.push(trim(value));
+ }
+
+ delete(name){
+ delete this.map[normalizeName(name)];
+ }
+
+ forEach(callback, thisArg) {
+ each(this.map, (list, name) => {
+ each(list, value => callback.call(thisArg, value, name, this));
+ });
+ }
+
+}
+
+function normalizeName(name) {
+
+ if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) {
+ throw new TypeError('Invalid character in header field name');
+ }
+
+ return toLower(trim(name));
+}
diff --git a/src/http/interceptor/body.js b/src/http/interceptor/body.js
index e71c3947..583a0d88 100644
--- a/src/http/interceptor/body.js
+++ b/src/http/interceptor/body.js
@@ -3,17 +3,17 @@
*/
import Url from '../../url/index';
-import { isString, isFormData, isPlainObject } from '../../util';
+import { when, isString, isFormData, isPlainObject } from '../../util';
export default function (request, next) {
if (request.emulateJSON && isPlainObject(request.body)) {
request.body = Url.params(request.body);
- request.headers['Content-Type'] = 'application/x-www-form-urlencoded';
+ request.headers.set('Content-Type', 'application/x-www-form-urlencoded');
}
if (isFormData(request.body)) {
- delete request.headers['Content-Type'];
+ request.headers.delete('Content-Type');
}
if (isPlainObject(request.body)) {
@@ -22,19 +22,37 @@ export default function (request, next) {
next((response) => {
- var contentType = response.headers['Content-Type'];
+ Object.defineProperty(response, 'data', {
- if (isString(contentType) && contentType.indexOf('application/json') === 0) {
+ get() {
+ return this.body;
+ },
- try {
- response.data = response.json();
- } catch (e) {
- response.data = null;
+ set(body) {
+ this.body = body;
}
- } else {
- response.data = response.text();
- }
+ });
+
+ return response.bodyText ? when(response.text(), text => {
+
+ var type = response.headers.get('Content-Type');
+
+ if (isString(type) && type.indexOf('application/json') === 0) {
+
+ try {
+ response.body = JSON.parse(text);
+ } catch (e) {
+ response.body = null;
+ }
+
+ } else {
+ response.body = text;
+ }
+
+ return response;
+
+ }) : response;
});
}
diff --git a/src/http/interceptor/header.js b/src/http/interceptor/header.js
index 8d2e4eb1..193b8db2 100644
--- a/src/http/interceptor/header.js
+++ b/src/http/interceptor/header.js
@@ -3,16 +3,20 @@
*/
import Http from '../index';
-import { assign } from '../../util';
+import { assign, each, toLower } from '../../util';
export default function (request, next) {
- request.method = request.method.toUpperCase();
- request.headers = assign({}, Http.headers.common,
+ var headers = assign({}, Http.headers.common,
!request.crossOrigin ? Http.headers.custom : {},
- Http.headers[request.method.toLowerCase()],
- request.headers
+ Http.headers[toLower(request.method)]
);
+ each(headers, (value, name) => {
+ if (!request.headers.has(name)) {
+ request.headers.set(name, value);
+ }
+ });
+
next();
}
diff --git a/src/http/interceptor/jsonp.js b/src/http/interceptor/jsonp.js
index ab92da94..160c508a 100644
--- a/src/http/interceptor/jsonp.js
+++ b/src/http/interceptor/jsonp.js
@@ -3,6 +3,7 @@
*/
import jsonpClient from '../client/jsonp';
+import { when } from '../../util';
export default function (request, next) {
@@ -13,7 +14,13 @@ export default function (request, next) {
next((response) => {
if (request.method == 'JSONP') {
- response.data = response.json();
+
+ return when(response.json(), json => {
+
+ response.body = json;
+
+ return response;
+ });
}
});
diff --git a/src/http/interceptor/method.js b/src/http/interceptor/method.js
index 8489e98c..ad393ce2 100644
--- a/src/http/interceptor/method.js
+++ b/src/http/interceptor/method.js
@@ -5,7 +5,7 @@
export default function (request, next) {
if (request.emulateHTTP && /^(PUT|PATCH|DELETE)$/i.test(request.method)) {
- request.headers['X-HTTP-Method-Override'] = request.method;
+ request.headers.set('X-HTTP-Method-Override', request.method);
request.method = 'POST';
}
diff --git a/src/http/request.js b/src/http/request.js
index cd7c41c2..070afa42 100644
--- a/src/http/request.js
+++ b/src/http/request.js
@@ -3,19 +3,21 @@
*/
import Url from '../url/index';
+import Headers from './headers';
import Response from './response';
-import { assign } from '../util';
+import { assign, toUpper } from '../util';
export default class Request {
constructor(options) {
- this.method = 'GET';
this.body = null;
this.params = {};
- this.headers = {};
- assign(this, options);
+ assign(this, options, {
+ method: toUpper(options.method || 'GET'),
+ headers: new Headers(options.headers)
+ });
}
getUrl(){
diff --git a/src/http/response.js b/src/http/response.js
index 2de5519b..8c5792d9 100644
--- a/src/http/response.js
+++ b/src/http/response.js
@@ -2,29 +2,62 @@
* HTTP Response.
*/
+import Headers from './headers';
+import Promise from '../promise';
+import { when, isBlob, isString } from '../util';
+
export default class Response {
constructor(body, {url, headers, status, statusText}) {
this.url = url;
- this.body = body;
- this.headers = headers || {};
+ this.ok = status >= 200 && status < 300;
this.status = status || 0;
this.statusText = statusText || '';
- this.ok = status >= 200 && status < 300;
+ this.headers = new Headers(headers);
+ this.body = body;
- }
+ if (isString(body)) {
- text() {
- return this.body;
+ this.bodyText = body;
+
+ } else if (isBlob(body)) {
+
+ this.bodyBlob = body;
+
+ if (isBlobText(body)) {
+ this.bodyText = blobText(body);
+ }
+ }
}
blob() {
- return new Blob([this.body]);
+ return when(this.bodyBlob);
+ }
+
+ text() {
+ return when(this.bodyText);
}
json() {
- return JSON.parse(this.body);
+ return when(this.text(), text => JSON.parse(text));
}
}
+
+function blobText(body) {
+ return new Promise((resolve) => {
+
+ var reader = new FileReader();
+
+ reader.readAsText(body);
+ reader.onload = () => {
+ resolve(reader.result);
+ };
+
+ });
+}
+
+function isBlobText(body) {
+ return body.type.indexOf('text') === 0 || body.type.indexOf('json') !== -1;
+}
diff --git a/src/index.js b/src/index.js
index fb4a40af..8c68e092 100644
--- a/src/index.js
+++ b/src/index.js
@@ -5,6 +5,7 @@
import Url from './url/index';
import Http from './http/index';
import Promise from './promise';
+import PromiseLib from './lib/promise';
import Resource from './resource';
import Util, { options } from './util';
@@ -50,8 +51,16 @@ function plugin(Vue) {
});
}
-if (typeof window !== 'undefined' && window.Vue) {
- window.Vue.use(plugin);
+if (typeof window !== 'undefined') {
+
+ if (!window.Promise) {
+ window.Promise = PromiseLib;
+ }
+
+ if (window.Vue) {
+ window.Vue.use(plugin);
+ }
+
}
export default plugin;
diff --git a/src/promise.js b/src/promise.js
index 1286acef..83acdc7d 100644
--- a/src/promise.js
+++ b/src/promise.js
@@ -2,9 +2,7 @@
* Promise adapter.
*/
-import PromiseLib from './lib/promise';
-
-var PromiseObj = window.Promise || PromiseLib;
+var PromiseObj = window.Promise;
export default function Promise(executor, context) {
diff --git a/src/resource.js b/src/resource.js
index a79fdd8b..dd90d8df 100644
--- a/src/resource.js
+++ b/src/resource.js
@@ -16,7 +16,7 @@ export default function Resource(url, params, actions, options) {
each(actions, (action, name) => {
- action = merge({url, params: params || {}}, options, action);
+ action = merge({url, params: assign({}, params)}, options, action);
resource[name] = function () {
return (self.$http || Http)(opts(action, arguments));
diff --git a/src/util.js b/src/util.js
index b252621a..33b4ded6 100644
--- a/src/util.js
+++ b/src/util.js
@@ -4,7 +4,7 @@
import Promise from './promise';
-var debug = false, util = {}, array = [];
+var debug = false, util = {}, { slice } = [];
export default function (Vue) {
util = Vue.util;
@@ -31,6 +31,14 @@ export function trim(str) {
return str.replace(/^\s*|\s*$/g, '');
}
+export function toLower(str) {
+ return str ? str.toLowerCase() : '';
+}
+
+export function toUpper(str) {
+ return str ? str.toUpperCase() : '';
+}
+
export const isArray = Array.isArray;
export function isString(val) {
@@ -53,6 +61,10 @@ export function isPlainObject(obj) {
return isObject(obj) && Object.getPrototypeOf(obj) == Object.prototype;
}
+export function isBlob(obj) {
+ return typeof Blob !== 'undefined' && obj instanceof Blob;
+}
+
export function isFormData(obj) {
return typeof FormData !== 'undefined' && obj instanceof FormData;
}
@@ -83,7 +95,7 @@ export function each(obj, iterator) {
var i, key;
- if (typeof obj.length == 'number') {
+ if (obj && typeof obj.length == 'number') {
for (i = 0; i < obj.length; i++) {
iterator.call(obj[i], obj[i], i);
}
@@ -102,7 +114,7 @@ export const assign = Object.assign || _assign;
export function merge(target) {
- var args = array.slice.call(arguments, 1);
+ var args = slice.call(arguments, 1);
args.forEach((source) => {
_merge(target, source, true);
@@ -113,7 +125,7 @@ export function merge(target) {
export function defaults(target) {
- var args = array.slice.call(arguments, 1);
+ var args = slice.call(arguments, 1);
args.forEach((source) => {
@@ -130,7 +142,7 @@ export function defaults(target) {
function _assign(target) {
- var args = array.slice.call(arguments, 1);
+ var args = slice.call(arguments, 1);
args.forEach((source) => {
_merge(target, source);
diff --git a/test/http.js b/test/http.js
index ae201b2f..f0262157 100644
--- a/test/http.js
+++ b/test/http.js
@@ -8,10 +8,9 @@ describe('Vue.http', function () {
expect(res.ok).toBe(true);
expect(res.status).toBe(200);
- expect(res.data).toBe('text');
- expect(res.blob() instanceof Blob).toBe(true);
- expect(res.headers['Content-Type']).toBe('text/plain');
- expect(res.headers['Content-Length']).toBe('4');
+ expect(res.body).toBe('text');
+ expect(res.headers.get('Content-Type')).toBe('text/plain');
+ expect(res.headers.get('Content-Length')).toBe('4');
done();
});
@@ -24,8 +23,8 @@ describe('Vue.http', function () {
expect(res.ok).toBe(true);
expect(res.status).toBe(200);
- expect(res.data.foo).toBe('bar');
- expect(typeof res.json()).toBe('object');
+ expect(typeof res.body).toBe('object');
+ expect(res.body.foo).toBe('bar');
done();
});
@@ -38,7 +37,21 @@ describe('Vue.http', function () {
expect(res.ok).toBe(true);
expect(res.status).toBe(200);
- expect(res.data).toBeNull();
+ expect(res.body).toBeNull();
+
+ done();
+ });
+
+ });
+
+ it('get("github.com/avatar")', (done) => {
+
+ Vue.http.get('https://avatars1.githubusercontent.com/u/6128107').then((res) => {
+
+ expect(res.ok).toBe(true);
+ expect(res.status).toBe(200);
+ expect(res.body instanceof Blob).toBe(true);
+ expect(res.body.type).toBe('image/png');
done();
});
@@ -51,9 +64,9 @@ describe('Vue.http', function () {
expect(res.ok).toBe(true);
expect(res.status).toBe(200);
- expect(res.data.shift().requestType).toBe('cors');
- expect(res.headers['Content-Type']).toBe('application/json');
- expect(typeof res.json()).toBe('object');
+ expect(typeof res.body).toBe('object');
+ expect(res.body.shift().requestType).toBe('cors');
+ expect(res.headers.get('Content-Type')).toBe('application/json');
done();
});
@@ -66,8 +79,8 @@ describe('Vue.http', function () {
expect(res.ok).toBe(true);
expect(res.status).toBe(200);
- expect(res.data.foo).toBe('bar');
- expect(typeof res.json()).toBe('object');
+ expect(typeof res.body).toBe('object');
+ expect(res.body.foo).toBe('bar');
done();
});
@@ -89,8 +102,8 @@ describe('this.$http', function () {
expect(this).toBe(vm);
expect(res.ok).toBe(true);
expect(res.status).toBe(200);
- expect(res.data.foo).toBe('bar');
- expect(typeof res.json()).toBe('object');
+ expect(typeof res.body).toBe('object');
+ expect(res.body.foo).toBe('bar');
done();
diff --git a/test/webpack.config.js b/test/webpack.config.js
index e5022a69..a7c5910c 100644
--- a/test/webpack.config.js
+++ b/test/webpack.config.js
@@ -6,7 +6,7 @@ module.exports = {
},
module: {
loaders: [
- {test: /.js/, exclude: /node_modules/, loader: 'babel', query: {presets: ['es2015-loose']}}
+ {test: /.js/, exclude: /node_modules/, loader: 'babel', query: {presets: [['es2015', {modules: false}]]}}
]
}
};