angularjs-rails 1.2.16 → 1.2.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/angularjs-rails/version.rb +2 -2
- data/vendor/assets/javascripts/angular-animate.js +25 -8
- data/vendor/assets/javascripts/angular-cookies.js +21 -13
- data/vendor/assets/javascripts/angular-loader.js +8 -6
- data/vendor/assets/javascripts/angular-mocks.js +8 -6
- data/vendor/assets/javascripts/angular-resource.js +19 -10
- data/vendor/assets/javascripts/angular-route.js +3 -3
- data/vendor/assets/javascripts/angular-sanitize.js +9 -3
- data/vendor/assets/javascripts/angular-scenario.js +874 -620
- data/vendor/assets/javascripts/angular-touch.js +17 -8
- data/vendor/assets/javascripts/angular.js +870 -616
- data/vendor/assets/javascripts/unstable/angular-animate.js +28 -9
- data/vendor/assets/javascripts/unstable/angular-cookies.js +21 -13
- data/vendor/assets/javascripts/unstable/angular-loader.js +13 -6
- data/vendor/assets/javascripts/unstable/angular-messages.js +400 -0
- data/vendor/assets/javascripts/unstable/angular-mocks.js +51 -18
- data/vendor/assets/javascripts/unstable/angular-resource.js +286 -236
- data/vendor/assets/javascripts/unstable/angular-route.js +4 -5
- data/vendor/assets/javascripts/unstable/angular-sanitize.js +9 -3
- data/vendor/assets/javascripts/unstable/angular-scenario.js +2159 -1346
- data/vendor/assets/javascripts/unstable/angular-touch.js +65 -18
- data/vendor/assets/javascripts/unstable/angular.js +2138 -1322
- metadata +3 -2
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.3.0-beta.
|
2
|
+
* @license AngularJS v1.3.0-beta.13
|
3
3
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -774,7 +774,8 @@ angular.mock.animate = angular.module('ngAnimateMock', ['ng'])
|
|
774
774
|
};
|
775
775
|
});
|
776
776
|
|
777
|
-
$provide.decorator('$animate',
|
777
|
+
$provide.decorator('$animate', ['$delegate', '$$asyncCallback',
|
778
|
+
function($delegate, $$asyncCallback) {
|
778
779
|
var animate = {
|
779
780
|
queue : [],
|
780
781
|
enabled : $delegate.enabled,
|
@@ -802,7 +803,7 @@ angular.mock.animate = angular.module('ngAnimateMock', ['ng'])
|
|
802
803
|
});
|
803
804
|
|
804
805
|
return animate;
|
805
|
-
});
|
806
|
+
}]);
|
806
807
|
|
807
808
|
}]);
|
808
809
|
|
@@ -900,7 +901,7 @@ angular.mock.dump = function(object) {
|
|
900
901
|
* When an Angular application needs some data from a server, it calls the $http service, which
|
901
902
|
* sends the request to a real server using $httpBackend service. With dependency injection, it is
|
902
903
|
* easy to inject $httpBackend mock (which has the same API as $httpBackend) and use it to verify
|
903
|
-
* the requests and respond with some testing data without sending a request to real server.
|
904
|
+
* the requests and respond with some testing data without sending a request to a real server.
|
904
905
|
*
|
905
906
|
* There are two ways to specify what test data should be returned as http responses by the mock
|
906
907
|
* backend when the code under test makes http requests:
|
@@ -1526,7 +1527,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1526
1527
|
|
1527
1528
|
|
1528
1529
|
function createShortMethods(prefix) {
|
1529
|
-
angular.forEach(['GET', 'DELETE', 'JSONP'], function(method) {
|
1530
|
+
angular.forEach(['GET', 'DELETE', 'JSONP', 'HEAD'], function(method) {
|
1530
1531
|
$httpBackend[prefix + method] = function(url, headers) {
|
1531
1532
|
return $httpBackend[prefix](method, url, undefined, headers);
|
1532
1533
|
};
|
@@ -1643,7 +1644,7 @@ function MockXhr() {
|
|
1643
1644
|
* that adds a "flush" and "verifyNoPendingTasks" methods.
|
1644
1645
|
*/
|
1645
1646
|
|
1646
|
-
angular.mock.$TimeoutDecorator = function($delegate, $browser) {
|
1647
|
+
angular.mock.$TimeoutDecorator = ['$delegate', '$browser', function ($delegate, $browser) {
|
1647
1648
|
|
1648
1649
|
/**
|
1649
1650
|
* @ngdoc method
|
@@ -1682,9 +1683,9 @@ angular.mock.$TimeoutDecorator = function($delegate, $browser) {
|
|
1682
1683
|
}
|
1683
1684
|
|
1684
1685
|
return $delegate;
|
1685
|
-
};
|
1686
|
+
}];
|
1686
1687
|
|
1687
|
-
angular.mock.$RAFDecorator = function($delegate) {
|
1688
|
+
angular.mock.$RAFDecorator = ['$delegate', function($delegate) {
|
1688
1689
|
var queue = [];
|
1689
1690
|
var rafFn = function(fn) {
|
1690
1691
|
var index = queue.length;
|
@@ -1710,9 +1711,9 @@ angular.mock.$RAFDecorator = function($delegate) {
|
|
1710
1711
|
};
|
1711
1712
|
|
1712
1713
|
return rafFn;
|
1713
|
-
};
|
1714
|
+
}];
|
1714
1715
|
|
1715
|
-
angular.mock.$AsyncCallbackDecorator = function($delegate) {
|
1716
|
+
angular.mock.$AsyncCallbackDecorator = ['$delegate', function($delegate) {
|
1716
1717
|
var callbacks = [];
|
1717
1718
|
var addFn = function(fn) {
|
1718
1719
|
callbacks.push(fn);
|
@@ -1724,7 +1725,7 @@ angular.mock.$AsyncCallbackDecorator = function($delegate) {
|
|
1724
1725
|
callbacks = [];
|
1725
1726
|
};
|
1726
1727
|
return addFn;
|
1727
|
-
};
|
1728
|
+
}];
|
1728
1729
|
|
1729
1730
|
/**
|
1730
1731
|
*
|
@@ -1742,7 +1743,7 @@ angular.mock.$RootElementProvider = function() {
|
|
1742
1743
|
*
|
1743
1744
|
* # ngMock
|
1744
1745
|
*
|
1745
|
-
* The `ngMock` module
|
1746
|
+
* The `ngMock` module provides support to inject and mock Angular services into unit tests.
|
1746
1747
|
* In addition, ngMock also extends various core ng services such that they can be
|
1747
1748
|
* inspected and controlled in a synchronous manner within test code.
|
1748
1749
|
*
|
@@ -1816,7 +1817,9 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) {
|
|
1816
1817
|
*
|
1817
1818
|
* // adds a new phone to the phones array
|
1818
1819
|
* $httpBackend.whenPOST('/phones').respond(function(method, url, data) {
|
1819
|
-
*
|
1820
|
+
* var phone = angular.fromJson(data);
|
1821
|
+
* phones.push(phone);
|
1822
|
+
* return [200, phone, {}];
|
1820
1823
|
* });
|
1821
1824
|
* $httpBackend.whenGET(/^\/templates\//).passThrough();
|
1822
1825
|
* //...
|
@@ -1980,11 +1983,11 @@ if(window.jasmine || window.mocha) {
|
|
1980
1983
|
};
|
1981
1984
|
|
1982
1985
|
|
1983
|
-
beforeEach(function() {
|
1986
|
+
(window.beforeEach || window.setup)(function() {
|
1984
1987
|
currentSpec = this;
|
1985
1988
|
});
|
1986
1989
|
|
1987
|
-
afterEach(function() {
|
1990
|
+
(window.afterEach || window.teardown)(function() {
|
1988
1991
|
var injector = currentSpec.$injector;
|
1989
1992
|
|
1990
1993
|
currentSpec.$injector = null;
|
@@ -2026,7 +2029,7 @@ if(window.jasmine || window.mocha) {
|
|
2026
2029
|
* @param {...(string|Function|Object)} fns any number of modules which are represented as string
|
2027
2030
|
* aliases or as anonymous module initialization functions. The modules are used to
|
2028
2031
|
* configure the injector. The 'ng' and 'ngMock' modules are automatically loaded. If an
|
2029
|
-
* object literal is passed they will be
|
2032
|
+
* object literal is passed they will be registered as values in the module, the key being
|
2030
2033
|
* the module name and the value being what is returned.
|
2031
2034
|
*/
|
2032
2035
|
window.module = angular.mock.module = function() {
|
@@ -2158,14 +2161,28 @@ if(window.jasmine || window.mocha) {
|
|
2158
2161
|
/////////////////////
|
2159
2162
|
function workFn() {
|
2160
2163
|
var modules = currentSpec.$modules || [];
|
2161
|
-
|
2164
|
+
var strictDi = !!currentSpec.$injectorStrict;
|
2162
2165
|
modules.unshift('ngMock');
|
2163
2166
|
modules.unshift('ng');
|
2164
2167
|
var injector = currentSpec.$injector;
|
2165
2168
|
if (!injector) {
|
2166
|
-
|
2169
|
+
if (strictDi) {
|
2170
|
+
// If strictDi is enabled, annotate the providerInjector blocks
|
2171
|
+
angular.forEach(modules, function(moduleFn) {
|
2172
|
+
if (typeof moduleFn === "function") {
|
2173
|
+
angular.injector.$$annotate(moduleFn);
|
2174
|
+
}
|
2175
|
+
});
|
2176
|
+
}
|
2177
|
+
injector = currentSpec.$injector = angular.injector(modules, strictDi);
|
2178
|
+
currentSpec.$injectorStrict = strictDi;
|
2167
2179
|
}
|
2168
2180
|
for(var i = 0, ii = blockFns.length; i < ii; i++) {
|
2181
|
+
if (currentSpec.$injectorStrict) {
|
2182
|
+
// If the injector is strict / strictDi, and the spec wants to inject using automatic
|
2183
|
+
// annotation, then annotate the function here.
|
2184
|
+
injector.annotate(blockFns[i]);
|
2185
|
+
}
|
2169
2186
|
try {
|
2170
2187
|
/* jshint -W040 *//* Jasmine explicitly provides a `this` object when calling functions */
|
2171
2188
|
injector.invoke(blockFns[i] || angular.noop, this);
|
@@ -2181,6 +2198,22 @@ if(window.jasmine || window.mocha) {
|
|
2181
2198
|
}
|
2182
2199
|
}
|
2183
2200
|
};
|
2201
|
+
|
2202
|
+
|
2203
|
+
angular.mock.inject.strictDi = function(value) {
|
2204
|
+
value = arguments.length ? !!value : true;
|
2205
|
+
return isSpecRunning() ? workFn() : workFn;
|
2206
|
+
|
2207
|
+
function workFn() {
|
2208
|
+
if (value !== currentSpec.$injectorStrict) {
|
2209
|
+
if (currentSpec.$injector) {
|
2210
|
+
throw new Error('Injector already created, can not modify strict annotations');
|
2211
|
+
} else {
|
2212
|
+
currentSpec.$injectorStrict = value;
|
2213
|
+
}
|
2214
|
+
}
|
2215
|
+
}
|
2216
|
+
};
|
2184
2217
|
}
|
2185
2218
|
|
2186
2219
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.3.0-beta.
|
2
|
+
* @license AngularJS v1.3.0-beta.13
|
3
3
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -78,6 +78,18 @@ function shallowClearAndCopy(src, dst) {
|
|
78
78
|
*
|
79
79
|
* Requires the {@link ngResource `ngResource`} module to be installed.
|
80
80
|
*
|
81
|
+
* By default, trailing slashes will be stripped from the calculated URLs,
|
82
|
+
* which can pose problems with server backends that do not expect that
|
83
|
+
* behavior. This can be disabled by configuring the `$resourceProvider` like
|
84
|
+
* this:
|
85
|
+
*
|
86
|
+
* ```js
|
87
|
+
app.config(['$resourceProvider', function ($resourceProvider) {
|
88
|
+
// Don't strip trailing slashes from calculated URLs
|
89
|
+
$resourceProvider.defaults.stripTrailingSlashes = false;
|
90
|
+
}]);
|
91
|
+
* ```
|
92
|
+
*
|
81
93
|
* @param {string} url A parametrized URL template with parameters prefixed by `:` as in
|
82
94
|
* `/user/:username`. If you are using a URL with a port number (e.g.
|
83
95
|
* `http://example.com:8080/api`), it will be respected.
|
@@ -99,8 +111,8 @@ function shallowClearAndCopy(src, dst) {
|
|
99
111
|
* Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in
|
100
112
|
* URL `/path/greet?salutation=Hello`.
|
101
113
|
*
|
102
|
-
* If the parameter value is prefixed with `@` then the value of that parameter
|
103
|
-
* the data object (useful for non-GET operations).
|
114
|
+
* If the parameter value is prefixed with `@` then the value of that parameter will be taken
|
115
|
+
* from the corresponding key on the data object (useful for non-GET operations).
|
104
116
|
*
|
105
117
|
* @param {Object.<Object>=} actions Hash with declaration of custom action that should extend
|
106
118
|
* the default set of resource actions. The declaration should be created in the format of {@link
|
@@ -147,6 +159,14 @@ function shallowClearAndCopy(src, dst) {
|
|
147
159
|
* `response` and `responseError`. Both `response` and `responseError` interceptors get called
|
148
160
|
* with `http response` object. See {@link ng.$http $http interceptors}.
|
149
161
|
*
|
162
|
+
* @param {Object} options Hash with custom settings that should extend the
|
163
|
+
* default `$resourceProvider` behavior. The only supported option is
|
164
|
+
*
|
165
|
+
* Where:
|
166
|
+
*
|
167
|
+
* - **`stripTrailingSlashes`** – {boolean} – If true then the trailing
|
168
|
+
* slashes from any calculated URL will be stripped. (Defaults to true.)
|
169
|
+
*
|
150
170
|
* @returns {Object} A resource "class" object with methods for the default set of resource actions
|
151
171
|
* optionally extended with custom `actions`. The default set contains these actions:
|
152
172
|
* ```js
|
@@ -322,289 +342,319 @@ function shallowClearAndCopy(src, dst) {
|
|
322
342
|
* ```
|
323
343
|
*/
|
324
344
|
angular.module('ngResource', ['ng']).
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
345
|
+
provider('$resource', function () {
|
346
|
+
var provider = this;
|
347
|
+
|
348
|
+
this.defaults = {
|
349
|
+
// Strip slashes by default
|
350
|
+
stripTrailingSlashes: true,
|
351
|
+
|
352
|
+
// Default actions configuration
|
353
|
+
actions: {
|
354
|
+
'get': {method: 'GET'},
|
355
|
+
'save': {method: 'POST'},
|
356
|
+
'query': {method: 'GET', isArray: true},
|
357
|
+
'remove': {method: 'DELETE'},
|
358
|
+
'delete': {method: 'DELETE'}
|
359
|
+
}
|
333
360
|
};
|
334
|
-
|
361
|
+
|
362
|
+
this.$get = ['$http', '$q', function ($http, $q) {
|
363
|
+
|
364
|
+
var noop = angular.noop,
|
335
365
|
forEach = angular.forEach,
|
336
366
|
extend = angular.extend,
|
337
367
|
copy = angular.copy,
|
338
368
|
isFunction = angular.isFunction;
|
339
369
|
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
370
|
+
/**
|
371
|
+
* We need our custom method because encodeURIComponent is too aggressive and doesn't follow
|
372
|
+
* http://www.ietf.org/rfc/rfc3986.txt with regards to the character set
|
373
|
+
* (pchar) allowed in path segments:
|
374
|
+
* segment = *pchar
|
375
|
+
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
376
|
+
* pct-encoded = "%" HEXDIG HEXDIG
|
377
|
+
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
378
|
+
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
379
|
+
* / "*" / "+" / "," / ";" / "="
|
380
|
+
*/
|
381
|
+
function encodeUriSegment(val) {
|
382
|
+
return encodeUriQuery(val, true).
|
383
|
+
replace(/%26/gi, '&').
|
384
|
+
replace(/%3D/gi, '=').
|
385
|
+
replace(/%2B/gi, '+');
|
386
|
+
}
|
357
387
|
|
358
388
|
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
389
|
+
/**
|
390
|
+
* This method is intended for encoding *key* or *value* parts of query component. We need a
|
391
|
+
* custom method because encodeURIComponent is too aggressive and encodes stuff that doesn't
|
392
|
+
* have to be encoded per http://tools.ietf.org/html/rfc3986:
|
393
|
+
* query = *( pchar / "/" / "?" )
|
394
|
+
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
395
|
+
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
396
|
+
* pct-encoded = "%" HEXDIG HEXDIG
|
397
|
+
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
398
|
+
* / "*" / "+" / "," / ";" / "="
|
399
|
+
*/
|
400
|
+
function encodeUriQuery(val, pctEncodeSpaces) {
|
401
|
+
return encodeURIComponent(val).
|
402
|
+
replace(/%40/gi, '@').
|
403
|
+
replace(/%3A/gi, ':').
|
404
|
+
replace(/%24/g, '$').
|
405
|
+
replace(/%2C/gi, ',').
|
406
|
+
replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
|
407
|
+
}
|
378
408
|
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
409
|
+
function Route(template, defaults) {
|
410
|
+
this.template = template;
|
411
|
+
this.defaults = extend({}, provider.defaults, defaults);
|
412
|
+
this.urlParams = {};
|
413
|
+
}
|
384
414
|
|
385
|
-
|
386
|
-
|
387
|
-
|
415
|
+
Route.prototype = {
|
416
|
+
setUrlParams: function (config, params, actionUrl) {
|
417
|
+
var self = this,
|
388
418
|
url = actionUrl || self.template,
|
389
419
|
val,
|
390
420
|
encodedVal;
|
391
421
|
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
422
|
+
var urlParams = self.urlParams = {};
|
423
|
+
forEach(url.split(/\W/), function (param) {
|
424
|
+
if (param === 'hasOwnProperty') {
|
425
|
+
throw $resourceMinErr('badname', "hasOwnProperty is not a valid parameter name.");
|
426
|
+
}
|
427
|
+
if (!(new RegExp("^\\d+$").test(param)) && param &&
|
428
|
+
(new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) {
|
429
|
+
urlParams[param] = true;
|
430
|
+
}
|
431
|
+
});
|
432
|
+
url = url.replace(/\\:/g, ':');
|
433
|
+
|
434
|
+
params = params || {};
|
435
|
+
forEach(self.urlParams, function (_, urlParam) {
|
436
|
+
val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];
|
437
|
+
if (angular.isDefined(val) && val !== null) {
|
438
|
+
encodedVal = encodeUriSegment(val);
|
439
|
+
url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), function (match, p1) {
|
440
|
+
return encodedVal + p1;
|
441
|
+
});
|
442
|
+
} else {
|
443
|
+
url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function (match,
|
444
|
+
leadingSlashes, tail) {
|
445
|
+
if (tail.charAt(0) == '/') {
|
446
|
+
return tail;
|
447
|
+
} else {
|
448
|
+
return leadingSlashes + tail;
|
449
|
+
}
|
450
|
+
});
|
451
|
+
}
|
452
|
+
});
|
423
453
|
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
url = url.replace(/\/\.(?=\w+($|\?))/, '.');
|
429
|
-
// replace escaped `/\.` with `/.`
|
430
|
-
config.url = url.replace(/\/\\\./, '/.');
|
454
|
+
// strip trailing slashes and set the url (unless this behavior is specifically disabled)
|
455
|
+
if (self.defaults.stripTrailingSlashes) {
|
456
|
+
url = url.replace(/\/+$/, '') || '/';
|
457
|
+
}
|
431
458
|
|
459
|
+
// then replace collapse `/.` if found in the last URL path segment before the query
|
460
|
+
// E.g. `http://url.com/id./format?q=x` becomes `http://url.com/id.format?q=x`
|
461
|
+
url = url.replace(/\/\.(?=\w+($|\?))/, '.');
|
462
|
+
// replace escaped `/\.` with `/.`
|
463
|
+
config.url = url.replace(/\/\\\./, '/.');
|
432
464
|
|
433
|
-
// set params - delegate param encoding to $http
|
434
|
-
forEach(params, function(value, key){
|
435
|
-
if (!self.urlParams[key]) {
|
436
|
-
config.params = config.params || {};
|
437
|
-
config.params[key] = value;
|
438
|
-
}
|
439
|
-
});
|
440
|
-
}
|
441
|
-
};
|
442
465
|
|
466
|
+
// set params - delegate param encoding to $http
|
467
|
+
forEach(params, function (value, key) {
|
468
|
+
if (!self.urlParams[key]) {
|
469
|
+
config.params = config.params || {};
|
470
|
+
config.params[key] = value;
|
471
|
+
}
|
472
|
+
});
|
473
|
+
}
|
474
|
+
};
|
443
475
|
|
444
|
-
function resourceFactory(url, paramDefaults, actions) {
|
445
|
-
var route = new Route(url);
|
446
476
|
|
447
|
-
|
477
|
+
function resourceFactory(url, paramDefaults, actions, options) {
|
478
|
+
var route = new Route(url, options);
|
448
479
|
|
449
|
-
|
450
|
-
var ids = {};
|
451
|
-
actionParams = extend({}, paramDefaults, actionParams);
|
452
|
-
forEach(actionParams, function(value, key){
|
453
|
-
if (isFunction(value)) { value = value(); }
|
454
|
-
ids[key] = value && value.charAt && value.charAt(0) == '@' ?
|
455
|
-
lookupDottedPath(data, value.substr(1)) : value;
|
456
|
-
});
|
457
|
-
return ids;
|
458
|
-
}
|
480
|
+
actions = extend({}, provider.defaults.actions, actions);
|
459
481
|
|
460
|
-
|
461
|
-
|
462
|
-
|
482
|
+
function extractParams(data, actionParams) {
|
483
|
+
var ids = {};
|
484
|
+
actionParams = extend({}, paramDefaults, actionParams);
|
485
|
+
forEach(actionParams, function (value, key) {
|
486
|
+
if (isFunction(value)) { value = value(); }
|
487
|
+
ids[key] = value && value.charAt && value.charAt(0) == '@' ?
|
488
|
+
lookupDottedPath(data, value.substr(1)) : value;
|
489
|
+
});
|
490
|
+
return ids;
|
491
|
+
}
|
492
|
+
|
493
|
+
function defaultResponseInterceptor(response) {
|
494
|
+
return response.resource;
|
495
|
+
}
|
496
|
+
|
497
|
+
function Resource(value) {
|
498
|
+
shallowClearAndCopy(value || {}, this);
|
499
|
+
}
|
500
|
+
|
501
|
+
Resource.prototype.toJSON = function () {
|
502
|
+
var data = extend({}, this);
|
503
|
+
delete data.$promise;
|
504
|
+
delete data.$resolved;
|
505
|
+
return data;
|
506
|
+
};
|
463
507
|
|
464
|
-
|
465
|
-
|
466
|
-
}
|
508
|
+
forEach(actions, function (action, name) {
|
509
|
+
var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method);
|
467
510
|
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
Resource[name] = function(a1, a2, a3, a4) {
|
472
|
-
var params = {}, data, success, error;
|
473
|
-
|
474
|
-
/* jshint -W086 */ /* (purposefully fall through case statements) */
|
475
|
-
switch(arguments.length) {
|
476
|
-
case 4:
|
477
|
-
error = a4;
|
478
|
-
success = a3;
|
479
|
-
//fallthrough
|
480
|
-
case 3:
|
481
|
-
case 2:
|
482
|
-
if (isFunction(a2)) {
|
483
|
-
if (isFunction(a1)) {
|
484
|
-
success = a1;
|
485
|
-
error = a2;
|
486
|
-
break;
|
487
|
-
}
|
511
|
+
Resource[name] = function (a1, a2, a3, a4) {
|
512
|
+
var params = {}, data, success, error;
|
488
513
|
|
489
|
-
|
490
|
-
|
514
|
+
/* jshint -W086 */ /* (purposefully fall through case statements) */
|
515
|
+
switch (arguments.length) {
|
516
|
+
case 4:
|
517
|
+
error = a4;
|
518
|
+
success = a3;
|
491
519
|
//fallthrough
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
if (key != 'params' && key != 'isArray' && key != 'interceptor') {
|
521
|
-
httpConfig[key] = copy(value);
|
520
|
+
case 3:
|
521
|
+
case 2:
|
522
|
+
if (isFunction(a2)) {
|
523
|
+
if (isFunction(a1)) {
|
524
|
+
success = a1;
|
525
|
+
error = a2;
|
526
|
+
break;
|
527
|
+
}
|
528
|
+
|
529
|
+
success = a2;
|
530
|
+
error = a3;
|
531
|
+
//fallthrough
|
532
|
+
} else {
|
533
|
+
params = a1;
|
534
|
+
data = a2;
|
535
|
+
success = a3;
|
536
|
+
break;
|
537
|
+
}
|
538
|
+
case 1:
|
539
|
+
if (isFunction(a1)) success = a1;
|
540
|
+
else if (hasBody) data = a1;
|
541
|
+
else params = a1;
|
542
|
+
break;
|
543
|
+
case 0: break;
|
544
|
+
default:
|
545
|
+
throw $resourceMinErr('badargs',
|
546
|
+
"Expected up to 4 arguments [params, data, success, error], got {0} arguments",
|
547
|
+
arguments.length);
|
522
548
|
}
|
523
|
-
|
549
|
+
/* jshint +W086 */ /* (purposefully fall through case statements) */
|
550
|
+
|
551
|
+
var isInstanceCall = this instanceof Resource;
|
552
|
+
var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data));
|
553
|
+
var httpConfig = {};
|
554
|
+
var responseInterceptor = action.interceptor && action.interceptor.response ||
|
555
|
+
defaultResponseInterceptor;
|
556
|
+
var responseErrorInterceptor = action.interceptor && action.interceptor.responseError ||
|
557
|
+
undefined;
|
558
|
+
|
559
|
+
forEach(action, function (value, key) {
|
560
|
+
if (key != 'params' && key != 'isArray' && key != 'interceptor') {
|
561
|
+
httpConfig[key] = copy(value);
|
562
|
+
}
|
563
|
+
});
|
524
564
|
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
565
|
+
if (hasBody) httpConfig.data = data;
|
566
|
+
route.setUrlParams(httpConfig,
|
567
|
+
extend({}, extractParams(data, action.params || {}), params),
|
568
|
+
action.url);
|
529
569
|
|
530
|
-
|
531
|
-
|
570
|
+
var promise = $http(httpConfig).then(function (response) {
|
571
|
+
var data = response.data,
|
532
572
|
promise = value.$promise;
|
533
573
|
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
574
|
+
if (data) {
|
575
|
+
// Need to convert action.isArray to boolean in case it is undefined
|
576
|
+
// jshint -W018
|
577
|
+
if (angular.isArray(data) !== (!!action.isArray)) {
|
578
|
+
throw $resourceMinErr('badcfg',
|
579
|
+
'Error in resource configuration. Expected ' +
|
580
|
+
'response to contain an {0} but got an {1}',
|
581
|
+
action.isArray ? 'array' : 'object',
|
582
|
+
angular.isArray(data) ? 'array' : 'object');
|
583
|
+
}
|
584
|
+
// jshint +W018
|
585
|
+
if (action.isArray) {
|
586
|
+
value.length = 0;
|
587
|
+
forEach(data, function (item) {
|
588
|
+
if (typeof item === "object") {
|
589
|
+
value.push(new Resource(item));
|
590
|
+
} else {
|
591
|
+
// Valid JSON values may be string literals, and these should not be converted
|
592
|
+
// into objects. These items will not have access to the Resource prototype
|
593
|
+
// methods, but unfortunately there
|
594
|
+
value.push(item);
|
595
|
+
}
|
596
|
+
});
|
597
|
+
} else {
|
598
|
+
shallowClearAndCopy(data, value);
|
599
|
+
value.$promise = promise;
|
600
|
+
}
|
541
601
|
}
|
542
|
-
// jshint +W018
|
543
|
-
if (action.isArray) {
|
544
|
-
value.length = 0;
|
545
|
-
forEach(data, function(item) {
|
546
|
-
value.push(new Resource(item));
|
547
|
-
});
|
548
|
-
} else {
|
549
|
-
shallowClearAndCopy(data, value);
|
550
|
-
value.$promise = promise;
|
551
|
-
}
|
552
|
-
}
|
553
602
|
|
554
|
-
|
603
|
+
value.$resolved = true;
|
555
604
|
|
556
|
-
|
605
|
+
response.resource = value;
|
557
606
|
|
558
|
-
|
559
|
-
|
560
|
-
|
607
|
+
return response;
|
608
|
+
}, function (response) {
|
609
|
+
value.$resolved = true;
|
561
610
|
|
562
|
-
|
611
|
+
(error || noop)(response);
|
563
612
|
|
564
|
-
|
565
|
-
|
613
|
+
return $q.reject(response);
|
614
|
+
});
|
566
615
|
|
567
|
-
|
568
|
-
function(response) {
|
616
|
+
promise = promise.then(
|
617
|
+
function (response) {
|
569
618
|
var value = responseInterceptor(response);
|
570
|
-
(success||noop)(value, response.headers);
|
619
|
+
(success || noop)(value, response.headers);
|
571
620
|
return value;
|
572
621
|
},
|
573
622
|
responseErrorInterceptor);
|
574
623
|
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
624
|
+
if (!isInstanceCall) {
|
625
|
+
// we are creating instance / collection
|
626
|
+
// - set the initial promise
|
627
|
+
// - return the instance / collection
|
628
|
+
value.$promise = promise;
|
629
|
+
value.$resolved = false;
|
581
630
|
|
582
|
-
|
583
|
-
|
631
|
+
return value;
|
632
|
+
}
|
584
633
|
|
585
|
-
|
586
|
-
|
587
|
-
|
634
|
+
// instance call
|
635
|
+
return promise;
|
636
|
+
};
|
588
637
|
|
589
638
|
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
639
|
+
Resource.prototype['$' + name] = function (params, success, error) {
|
640
|
+
if (isFunction(params)) {
|
641
|
+
error = success; success = params; params = {};
|
642
|
+
}
|
643
|
+
var result = Resource[name].call(this, params, this, success, error);
|
644
|
+
return result.$promise || result;
|
645
|
+
};
|
646
|
+
});
|
598
647
|
|
599
|
-
|
600
|
-
|
601
|
-
|
648
|
+
Resource.bind = function (additionalParamDefaults) {
|
649
|
+
return resourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions);
|
650
|
+
};
|
602
651
|
|
603
|
-
|
604
|
-
|
652
|
+
return Resource;
|
653
|
+
}
|
605
654
|
|
606
|
-
|
607
|
-
|
655
|
+
return resourceFactory;
|
656
|
+
}];
|
657
|
+
});
|
608
658
|
|
609
659
|
|
610
660
|
})(window, window.angular);
|