angular-on-rails 1.0.5 → 1.1.3u
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/angularjs/version.rb +1 -1
- data/vendor/assets/javascripts/angular-bootstrap-prettify.js +1 -1
- data/vendor/assets/javascripts/angular-bootstrap.js +1 -1
- data/vendor/assets/javascripts/angular-cookies.js +1 -1
- data/vendor/assets/javascripts/angular-loader.js +1 -1
- data/vendor/assets/javascripts/angular-mocks.js +68 -37
- data/vendor/assets/javascripts/angular-resource.js +99 -37
- data/vendor/assets/javascripts/angular-sanitize.js +25 -4
- data/vendor/assets/javascripts/angular-scenario.js +4204 -3710
- data/vendor/assets/javascripts/angular.js +603 -172
- data/vendor/assets/javascripts/i18n/angular-locale_am-et.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_am.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ar-eg.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ar.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_bg-bg.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_bg.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_bn-bd.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_bn.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ca-es.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ca.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_cs-cz.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_cs.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_da-dk.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_da.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_de-at.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_de-be.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_de-ch.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_de-de.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_de-lu.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_de.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_el-gr.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_el-polyton.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_el.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_en-as.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_en-au.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_en-dsrt-us.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_en-dsrt.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_en-gb.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_en-gu.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_en-ie.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_en-in.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_en-iso.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_en-mh.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_en-mp.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_en-sg.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_en-um.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_en-us.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_en-vi.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_en-za.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_en-zz.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_en.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_es-es.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_es.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_et-ee.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_et.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_eu-es.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_eu.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_fa-ir.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_fa.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_fi-fi.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_fi.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_fil-ph.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_fil.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_fr-bl.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_fr-ca.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_fr-fr.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_fr-gp.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_fr-mc.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_fr-mf.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_fr-mq.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_fr-re.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_fr.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_gl-es.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_gl.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_gsw-ch.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_gsw.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_gu-in.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_gu.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_he-il.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_he.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_hi-in.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_hi.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_hr-hr.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_hr.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_hu-hu.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_hu.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_id-id.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_id.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_in.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_is-is.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_is.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_it-it.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_it.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_iw.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ja-jp.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ja.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_kn-in.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_kn.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ko-kr.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ko.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ln-cd.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ln.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_lt-lt.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_lt.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_lv-lv.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_lv.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ml-in.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ml.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_mo.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_mr-in.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_mr.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ms-my.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ms.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_mt-mt.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_mt.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_nl-nl.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_nl.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_no.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_or-in.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_or.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_pl-pl.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_pl.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_pt-br.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_pt-pt.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_pt.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ro-ro.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ro.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ru-ru.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ru.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_sk-sk.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_sk.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_sl-si.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_sl.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_sq-al.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_sq.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_sr-cyrl-rs.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_sr-latn-rs.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_sr-rs.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_sr.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_sv-se.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_sv.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_sw-tz.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_sw.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ta-in.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ta.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_te-in.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_te.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_th-th.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_th.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_tl-ph.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_tl.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_tr-tr.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_tr.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_uk-ua.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_uk.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ur-pk.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_ur.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_vi-vn.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_vi.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_zh-cn.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_zh-hans-cn.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_zh-hans.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_zh-hk.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_zh-tw.js +4 -0
- data/vendor/assets/javascripts/i18n/angular-locale_zh.js +4 -0
- metadata +160 -10
- data/vendor/assets/javascripts/jstd-scenario-adapter-config.js +0 -6
- data/vendor/assets/javascripts/jstd-scenario-adapter.js +0 -185
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.
|
2
|
+
* @license AngularJS v1.1.3
|
3
3
|
* (c) 2010-2012 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -63,12 +63,32 @@ var /** holds major version number for IE or NaN for real browsers */
|
|
63
63
|
push = [].push,
|
64
64
|
toString = Object.prototype.toString,
|
65
65
|
|
66
|
+
|
67
|
+
_angular = window.angular,
|
66
68
|
/** @name angular */
|
67
69
|
angular = window.angular || (window.angular = {}),
|
68
70
|
angularModule,
|
69
71
|
nodeName_,
|
70
72
|
uid = ['0', '0', '0'];
|
71
73
|
|
74
|
+
/**
|
75
|
+
* @ngdoc function
|
76
|
+
* @name angular.noConflict
|
77
|
+
* @function
|
78
|
+
*
|
79
|
+
* @description
|
80
|
+
* Restores the previous global value of angular and returns the current instance. Other libraries may already use the
|
81
|
+
* angular namespace. Or a previous version of angular is already loaded on the page. In these cases you may want to
|
82
|
+
* restore the previous namespace and keep a reference to angular.
|
83
|
+
*
|
84
|
+
* @return {Object} The current angular namespace
|
85
|
+
*/
|
86
|
+
function noConflict() {
|
87
|
+
var a = window.angular;
|
88
|
+
window.angular = _angular;
|
89
|
+
return a;
|
90
|
+
}
|
91
|
+
|
72
92
|
/**
|
73
93
|
* @ngdoc function
|
74
94
|
* @name angular.forEach
|
@@ -1279,11 +1299,11 @@ function setupModuleLoader(window) {
|
|
1279
1299
|
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
|
1280
1300
|
*/
|
1281
1301
|
var version = {
|
1282
|
-
full: '1.
|
1302
|
+
full: '1.1.3', // all of these placeholder strings will be replaced by rake's
|
1283
1303
|
major: 1, // compile task
|
1284
|
-
minor:
|
1285
|
-
dot:
|
1286
|
-
codeName: '
|
1304
|
+
minor: 1,
|
1305
|
+
dot: 3,
|
1306
|
+
codeName: 'radioactive-gargle'
|
1287
1307
|
};
|
1288
1308
|
|
1289
1309
|
|
@@ -1313,7 +1333,8 @@ function publishExternalAPI(angular){
|
|
1313
1333
|
'isDate': isDate,
|
1314
1334
|
'lowercase': lowercase,
|
1315
1335
|
'uppercase': uppercase,
|
1316
|
-
'callbacks': {counter: 0}
|
1336
|
+
'callbacks': {counter: 0},
|
1337
|
+
'noConflict': noConflict
|
1317
1338
|
});
|
1318
1339
|
|
1319
1340
|
angularModule = setupModuleLoader(window);
|
@@ -1749,11 +1770,11 @@ var JQLitePrototype = JQLite.prototype = {
|
|
1749
1770
|
// value on get.
|
1750
1771
|
//////////////////////////////////////////
|
1751
1772
|
var BOOLEAN_ATTR = {};
|
1752
|
-
forEach('multiple,selected,checked,disabled,readOnly,required'.split(','), function(value) {
|
1773
|
+
forEach('multiple,selected,checked,disabled,readOnly,required,open'.split(','), function(value) {
|
1753
1774
|
BOOLEAN_ATTR[lowercase(value)] = value;
|
1754
1775
|
});
|
1755
1776
|
var BOOLEAN_ELEMENTS = {};
|
1756
|
-
forEach('input,select,option,textarea,button,form'.split(','), function(value) {
|
1777
|
+
forEach('input,select,option,textarea,button,form,details'.split(','), function(value) {
|
1757
1778
|
BOOLEAN_ELEMENTS[uppercase(value)] = true;
|
1758
1779
|
});
|
1759
1780
|
|
@@ -2055,8 +2076,9 @@ forEach({
|
|
2055
2076
|
|
2056
2077
|
append: function(element, node) {
|
2057
2078
|
forEach(new JQLite(node), function(child){
|
2058
|
-
if (element.nodeType === 1)
|
2079
|
+
if (element.nodeType === 1 || element.nodeType === 11) {
|
2059
2080
|
element.appendChild(child);
|
2081
|
+
}
|
2060
2082
|
});
|
2061
2083
|
},
|
2062
2084
|
|
@@ -2678,9 +2700,10 @@ function createInjector(modulesToLoad) {
|
|
2678
2700
|
decorator: decorator
|
2679
2701
|
}
|
2680
2702
|
},
|
2681
|
-
providerInjector =
|
2682
|
-
|
2683
|
-
|
2703
|
+
providerInjector = (providerCache.$injector =
|
2704
|
+
createInternalInjector(providerCache, function() {
|
2705
|
+
throw Error("Unknown provider: " + path.join(' <- '));
|
2706
|
+
})),
|
2684
2707
|
instanceCache = {},
|
2685
2708
|
instanceInjector = (instanceCache.$injector =
|
2686
2709
|
createInternalInjector(instanceCache, function(servicename) {
|
@@ -2757,9 +2780,7 @@ function createInjector(modulesToLoad) {
|
|
2757
2780
|
try {
|
2758
2781
|
for(var invokeQueue = moduleFn._invokeQueue, i = 0, ii = invokeQueue.length; i < ii; i++) {
|
2759
2782
|
var invokeArgs = invokeQueue[i],
|
2760
|
-
provider = invokeArgs[0]
|
2761
|
-
? providerInjector
|
2762
|
-
: providerInjector.get(invokeArgs[0]);
|
2783
|
+
provider = providerInjector.get(invokeArgs[0]);
|
2763
2784
|
|
2764
2785
|
provider[invokeArgs[1]].apply(provider, invokeArgs[2]);
|
2765
2786
|
}
|
@@ -3314,7 +3335,7 @@ function $BrowserProvider(){
|
|
3314
3335
|
* @returns {object} Newly created cache object with the following set of methods:
|
3315
3336
|
*
|
3316
3337
|
* - `{object}` `info()` — Returns id, size, and options of cache.
|
3317
|
-
* - `{
|
3338
|
+
* - `{{*}}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache and returns it.
|
3318
3339
|
* - `{{*}}` `get({string} key)` — Returns cached value for `key` or undefined for cache miss.
|
3319
3340
|
* - `{void}` `remove({string} key)` — Removes a key-value pair from the cache.
|
3320
3341
|
* - `{void}` `removeAll()` — Removes all cached values.
|
@@ -3353,6 +3374,8 @@ function $CacheFactoryProvider() {
|
|
3353
3374
|
if (size > capacity) {
|
3354
3375
|
this.remove(staleEnd.key);
|
3355
3376
|
}
|
3377
|
+
|
3378
|
+
return value;
|
3356
3379
|
},
|
3357
3380
|
|
3358
3381
|
|
@@ -4257,6 +4280,10 @@ function $CompileProvider($provide) {
|
|
4257
4280
|
scope[scopeName] = value;
|
4258
4281
|
});
|
4259
4282
|
attrs.$$observers[attrName].$$scope = parentScope;
|
4283
|
+
if( attrs[attrName] ) {
|
4284
|
+
// If the attribute has been provided then we trigger an interpolation to ensure the value is there for use in the link fn
|
4285
|
+
scope[scopeName] = $interpolate(attrs[attrName])(parentScope);
|
4286
|
+
}
|
4260
4287
|
break;
|
4261
4288
|
}
|
4262
4289
|
|
@@ -4555,7 +4582,7 @@ function $CompileProvider($provide) {
|
|
4555
4582
|
interpolateFn = $interpolate(attr[name], true);
|
4556
4583
|
}
|
4557
4584
|
|
4558
|
-
attr[name] =
|
4585
|
+
attr[name] = interpolateFn(scope);
|
4559
4586
|
($$observers[name] || ($$observers[name] = [])).$$inter = true;
|
4560
4587
|
(attr.$$observers && attr.$$observers[name].$$scope || scope).
|
4561
4588
|
$watch(interpolateFn, function interpolateFnWatchAction(value) {
|
@@ -4838,7 +4865,7 @@ function $InterpolateProvider() {
|
|
4838
4865
|
};
|
4839
4866
|
|
4840
4867
|
|
4841
|
-
this.$get = ['$parse', function($parse) {
|
4868
|
+
this.$get = ['$parse', '$exceptionHandler', function($parse, $exceptionHandler) {
|
4842
4869
|
var startSymbolLength = startSymbol.length,
|
4843
4870
|
endSymbolLength = endSymbol.length;
|
4844
4871
|
|
@@ -4910,18 +4937,24 @@ function $InterpolateProvider() {
|
|
4910
4937
|
if (!mustHaveExpression || hasInterpolation) {
|
4911
4938
|
concat.length = length;
|
4912
4939
|
fn = function(context) {
|
4913
|
-
|
4914
|
-
|
4915
|
-
part =
|
4916
|
-
|
4917
|
-
part
|
4918
|
-
|
4919
|
-
|
4940
|
+
try {
|
4941
|
+
for(var i = 0, ii = length, part; i<ii; i++) {
|
4942
|
+
if (typeof (part = parts[i]) == 'function') {
|
4943
|
+
part = part(context);
|
4944
|
+
if (part == null || part == undefined) {
|
4945
|
+
part = '';
|
4946
|
+
} else if (typeof part != 'string') {
|
4947
|
+
part = toJson(part);
|
4948
|
+
}
|
4920
4949
|
}
|
4950
|
+
concat[i] = part;
|
4921
4951
|
}
|
4922
|
-
concat
|
4952
|
+
return concat.join('');
|
4953
|
+
}
|
4954
|
+
catch(err) {
|
4955
|
+
var newErr = new Error('Error while interpolating: ' + text + '\n' + err.toString());
|
4956
|
+
$exceptionHandler(newErr);
|
4923
4957
|
}
|
4924
|
-
return concat.join('');
|
4925
4958
|
};
|
4926
4959
|
fn.exp = text;
|
4927
4960
|
fn.parts = parts;
|
@@ -5617,7 +5650,33 @@ function $LocationProvider(){
|
|
5617
5650
|
</example>
|
5618
5651
|
*/
|
5619
5652
|
|
5653
|
+
/**
|
5654
|
+
* @ngdoc object
|
5655
|
+
* @name ng.$logProvider
|
5656
|
+
* @description
|
5657
|
+
* Use the `$logProvider` to configure how the application logs messages
|
5658
|
+
*/
|
5620
5659
|
function $LogProvider(){
|
5660
|
+
var debug = true,
|
5661
|
+
self = this;
|
5662
|
+
|
5663
|
+
/**
|
5664
|
+
* @ngdoc property
|
5665
|
+
* @name ng.$logProvider#debugEnabled
|
5666
|
+
* @methodOf ng.$logProvider
|
5667
|
+
* @description
|
5668
|
+
* @param {string=} flag enable or disable debug level messages
|
5669
|
+
* @returns {*} current value if used as getter or itself (chaining) if used as setter
|
5670
|
+
*/
|
5671
|
+
this.debugEnabled = function(flag) {
|
5672
|
+
if (isDefined(flag)) {
|
5673
|
+
debug = flag;
|
5674
|
+
return this;
|
5675
|
+
} else {
|
5676
|
+
return debug;
|
5677
|
+
}
|
5678
|
+
};
|
5679
|
+
|
5621
5680
|
this.$get = ['$window', function($window){
|
5622
5681
|
return {
|
5623
5682
|
/**
|
@@ -5658,7 +5717,25 @@ function $LogProvider(){
|
|
5658
5717
|
* @description
|
5659
5718
|
* Write an error message
|
5660
5719
|
*/
|
5661
|
-
error: consoleLog('error')
|
5720
|
+
error: consoleLog('error'),
|
5721
|
+
|
5722
|
+
/**
|
5723
|
+
* @ngdoc method
|
5724
|
+
* @name ng.$log#debug
|
5725
|
+
* @methodOf ng.$log
|
5726
|
+
*
|
5727
|
+
* @description
|
5728
|
+
* Write a debug message
|
5729
|
+
*/
|
5730
|
+
debug: (function () {
|
5731
|
+
var fn = consoleLog('debug');
|
5732
|
+
|
5733
|
+
return function() {
|
5734
|
+
if (debug) {
|
5735
|
+
fn.apply(self, arguments);
|
5736
|
+
}
|
5737
|
+
}
|
5738
|
+
}())
|
5662
5739
|
};
|
5663
5740
|
|
5664
5741
|
function formatError(arg) {
|
@@ -5717,6 +5794,8 @@ var OPERATORS = {
|
|
5717
5794
|
'%':function(self, locals, a,b){return a(self, locals)%b(self, locals);},
|
5718
5795
|
'^':function(self, locals, a,b){return a(self, locals)^b(self, locals);},
|
5719
5796
|
'=':noop,
|
5797
|
+
'===':function(self, locals, a, b){return a(self, locals)===b(self, locals);},
|
5798
|
+
'!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);},
|
5720
5799
|
'==':function(self, locals, a,b){return a(self, locals)==b(self, locals);},
|
5721
5800
|
'!=':function(self, locals, a,b){return a(self, locals)!=b(self, locals);},
|
5722
5801
|
'<':function(self, locals, a,b){return a(self, locals)<b(self, locals);},
|
@@ -5767,9 +5846,14 @@ function lex(text, csp){
|
|
5767
5846
|
continue;
|
5768
5847
|
} else {
|
5769
5848
|
var ch2 = ch + peek(),
|
5849
|
+
ch3 = ch2 + peek(2),
|
5770
5850
|
fn = OPERATORS[ch],
|
5771
|
-
fn2 = OPERATORS[ch2]
|
5772
|
-
|
5851
|
+
fn2 = OPERATORS[ch2],
|
5852
|
+
fn3 = OPERATORS[ch3];
|
5853
|
+
if (fn3) {
|
5854
|
+
tokens.push({index:index, text:ch3, fn:fn3});
|
5855
|
+
index += 3;
|
5856
|
+
} else if (fn2) {
|
5773
5857
|
tokens.push({index:index, text:ch2, fn:fn2});
|
5774
5858
|
index += 2;
|
5775
5859
|
} else if (fn) {
|
@@ -5791,8 +5875,9 @@ function lex(text, csp){
|
|
5791
5875
|
return chars.indexOf(lastCh) != -1;
|
5792
5876
|
}
|
5793
5877
|
|
5794
|
-
function peek() {
|
5795
|
-
|
5878
|
+
function peek(i) {
|
5879
|
+
var num = i || 1;
|
5880
|
+
return index + num < text.length ? text.charAt(index + num) : false;
|
5796
5881
|
}
|
5797
5882
|
function isNumber(ch) {
|
5798
5883
|
return '0' <= ch && ch <= '9';
|
@@ -5992,6 +6077,8 @@ function parser(text, json, $filter, csp){
|
|
5992
6077
|
if (tokens.length !== 0) {
|
5993
6078
|
throwError("is an unexpected token", tokens[0]);
|
5994
6079
|
}
|
6080
|
+
value.literal = !!value.literal;
|
6081
|
+
value.constant = !!value.constant;
|
5995
6082
|
return value;
|
5996
6083
|
|
5997
6084
|
///////////////////////////////////
|
@@ -6039,15 +6126,19 @@ function parser(text, json, $filter, csp){
|
|
6039
6126
|
}
|
6040
6127
|
|
6041
6128
|
function unaryFn(fn, right) {
|
6042
|
-
return function(self, locals) {
|
6129
|
+
return extend(function(self, locals) {
|
6043
6130
|
return fn(self, locals, right);
|
6044
|
-
}
|
6131
|
+
}, {
|
6132
|
+
constant:right.constant
|
6133
|
+
});
|
6045
6134
|
}
|
6046
6135
|
|
6047
6136
|
function binaryFn(left, fn, right) {
|
6048
|
-
return function(self, locals) {
|
6137
|
+
return extend(function(self, locals) {
|
6049
6138
|
return fn(self, locals, left, right);
|
6050
|
-
}
|
6139
|
+
}, {
|
6140
|
+
constant:left.constant && right.constant
|
6141
|
+
});
|
6051
6142
|
}
|
6052
6143
|
|
6053
6144
|
function statements() {
|
@@ -6153,7 +6244,7 @@ function parser(text, json, $filter, csp){
|
|
6153
6244
|
function equality() {
|
6154
6245
|
var left = relational();
|
6155
6246
|
var token;
|
6156
|
-
if ((token = expect('==','!='))) {
|
6247
|
+
if ((token = expect('==','!=','===','!=='))) {
|
6157
6248
|
left = binaryFn(left, token.fn, equality());
|
6158
6249
|
}
|
6159
6250
|
return left;
|
@@ -6215,6 +6306,9 @@ function parser(text, json, $filter, csp){
|
|
6215
6306
|
if (!primary) {
|
6216
6307
|
throwError("not a primary expression", token);
|
6217
6308
|
}
|
6309
|
+
if (token.json) {
|
6310
|
+
primary.constant = primary.literal = true;
|
6311
|
+
}
|
6218
6312
|
}
|
6219
6313
|
|
6220
6314
|
var next, context;
|
@@ -6303,23 +6397,32 @@ function parser(text, json, $filter, csp){
|
|
6303
6397
|
// This is used with json array declaration
|
6304
6398
|
function arrayDeclaration () {
|
6305
6399
|
var elementFns = [];
|
6400
|
+
var allConstant = true;
|
6306
6401
|
if (peekToken().text != ']') {
|
6307
6402
|
do {
|
6308
|
-
|
6403
|
+
var elementFn = expression();
|
6404
|
+
elementFns.push(elementFn);
|
6405
|
+
if (!elementFn.constant) {
|
6406
|
+
allConstant = false;
|
6407
|
+
}
|
6309
6408
|
} while (expect(','));
|
6310
6409
|
}
|
6311
6410
|
consume(']');
|
6312
|
-
return function(self, locals){
|
6411
|
+
return extend(function(self, locals){
|
6313
6412
|
var array = [];
|
6314
6413
|
for ( var i = 0; i < elementFns.length; i++) {
|
6315
6414
|
array.push(elementFns[i](self, locals));
|
6316
6415
|
}
|
6317
6416
|
return array;
|
6318
|
-
}
|
6417
|
+
}, {
|
6418
|
+
literal:true,
|
6419
|
+
constant:allConstant
|
6420
|
+
});
|
6319
6421
|
}
|
6320
6422
|
|
6321
6423
|
function object () {
|
6322
6424
|
var keyValues = [];
|
6425
|
+
var allConstant = true;
|
6323
6426
|
if (peekToken().text != '}') {
|
6324
6427
|
do {
|
6325
6428
|
var token = expect(),
|
@@ -6327,10 +6430,13 @@ function parser(text, json, $filter, csp){
|
|
6327
6430
|
consume(":");
|
6328
6431
|
var value = expression();
|
6329
6432
|
keyValues.push({key:key, value:value});
|
6433
|
+
if (!value.constant) {
|
6434
|
+
allConstant = false;
|
6435
|
+
}
|
6330
6436
|
} while (expect(','));
|
6331
6437
|
}
|
6332
6438
|
consume('}');
|
6333
|
-
return function(self, locals){
|
6439
|
+
return extend(function(self, locals){
|
6334
6440
|
var object = {};
|
6335
6441
|
for ( var i = 0; i < keyValues.length; i++) {
|
6336
6442
|
var keyValue = keyValues[i];
|
@@ -6338,7 +6444,10 @@ function parser(text, json, $filter, csp){
|
|
6338
6444
|
object[keyValue.key] = value;
|
6339
6445
|
}
|
6340
6446
|
return object;
|
6341
|
-
}
|
6447
|
+
}, {
|
6448
|
+
literal:true,
|
6449
|
+
constant:allConstant
|
6450
|
+
});
|
6342
6451
|
}
|
6343
6452
|
}
|
6344
6453
|
|
@@ -6542,8 +6651,13 @@ function getterFn(path, csp) {
|
|
6542
6651
|
* * `locals` – `{object=}` – local variables context object, useful for overriding values in
|
6543
6652
|
* `context`.
|
6544
6653
|
*
|
6545
|
-
* The
|
6546
|
-
*
|
6654
|
+
* The returned function also has the following properties:
|
6655
|
+
* * `literal` – `{boolean}` – whether the expression's top-level node is a JavaScript
|
6656
|
+
* literal.
|
6657
|
+
* * `constant` – `{boolean}` – whether the expression is made entirely of JavaScript
|
6658
|
+
* constant literals.
|
6659
|
+
* * `assign` – `{?function(context, value)}` – if the expression is assignable, this will be
|
6660
|
+
* set to a function to change its value on the given context.
|
6547
6661
|
*
|
6548
6662
|
*/
|
6549
6663
|
function $ParseProvider() {
|
@@ -7000,9 +7114,18 @@ function $RouteProvider(){
|
|
7000
7114
|
* `$location.path` will be updated to add or drop the trailing slash to exactly match the
|
7001
7115
|
* route definition.
|
7002
7116
|
*
|
7003
|
-
*
|
7004
|
-
*
|
7005
|
-
*
|
7117
|
+
* * `path` can contain named groups starting with a colon (`:name`). All characters up
|
7118
|
+
* to the next slash are matched and stored in `$routeParams` under the given `name`
|
7119
|
+
* when the route matches.
|
7120
|
+
* * `path` can contain named groups starting with a star (`*name`). All characters are
|
7121
|
+
* eagerly stored in `$routeParams` under the given `name` when the route matches.
|
7122
|
+
*
|
7123
|
+
* For example, routes like `/color/:color/largecode/*largecode/edit` will match
|
7124
|
+
* `/color/brown/largecode/code/with/slashs/edit` and extract:
|
7125
|
+
*
|
7126
|
+
* * `color: brown`
|
7127
|
+
* * `largecode: code/with/slashs`.
|
7128
|
+
*
|
7006
7129
|
*
|
7007
7130
|
* @param {Object} route Mapping information to be assigned to `$route.current` on route
|
7008
7131
|
* match.
|
@@ -7012,12 +7135,24 @@ function $RouteProvider(){
|
|
7012
7135
|
* - `controller` – `{(string|function()=}` – Controller fn that should be associated with newly
|
7013
7136
|
* created scope or the name of a {@link angular.Module#controller registered controller}
|
7014
7137
|
* if passed as a string.
|
7015
|
-
* - `template` – `{string=}` –
|
7016
|
-
* {@link ng.directive:ngView ngView} or
|
7138
|
+
* - `template` – `{string=|function()=}` – html template as a string or function that returns
|
7139
|
+
* an html template as a string which should be used by {@link ng.directive:ngView ngView} or
|
7017
7140
|
* {@link ng.directive:ngInclude ngInclude} directives.
|
7018
|
-
*
|
7019
|
-
*
|
7020
|
-
*
|
7141
|
+
* This property takes precedence over `templateUrl`.
|
7142
|
+
*
|
7143
|
+
* If `template` is a function, it will be called with the following parameters:
|
7144
|
+
*
|
7145
|
+
* - `{Array.<Object>}` - route parameters extracted from the current
|
7146
|
+
* `$location.path()` by applying the current route
|
7147
|
+
*
|
7148
|
+
* - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html
|
7149
|
+
* template that should be used by {@link ng.directive:ngView ngView}.
|
7150
|
+
*
|
7151
|
+
* If `templateUrl` is a function, it will be called with the following parameters:
|
7152
|
+
*
|
7153
|
+
* - `{Array.<Object>}` - route parameters extracted from the current
|
7154
|
+
* `$location.path()` by applying the current route
|
7155
|
+
*
|
7021
7156
|
* - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
|
7022
7157
|
* be injected into the controller. If any of these dependencies are promises, they will be
|
7023
7158
|
* resolved and converted to a value before the controller is instantiated and the
|
@@ -7306,12 +7441,12 @@ function $RouteProvider(){
|
|
7306
7441
|
// regex only once and then reuse it
|
7307
7442
|
|
7308
7443
|
// Escape regexp special characters.
|
7309
|
-
when = '^' + when.replace(/[
|
7444
|
+
when = '^' + when.replace(/[-\/\\^$:*+?.()|[\]{}]/g, "\\$&") + '$';
|
7310
7445
|
var regex = '',
|
7311
7446
|
params = [],
|
7312
7447
|
dst = {};
|
7313
7448
|
|
7314
|
-
var re =
|
7449
|
+
var re = /\\([:*])(\w+)/g,
|
7315
7450
|
paramMatch,
|
7316
7451
|
lastMatchedIndex = 0;
|
7317
7452
|
|
@@ -7319,8 +7454,15 @@ function $RouteProvider(){
|
|
7319
7454
|
// Find each :param in `when` and replace it with a capturing group.
|
7320
7455
|
// Append all other sections of when unchanged.
|
7321
7456
|
regex += when.slice(lastMatchedIndex, paramMatch.index);
|
7322
|
-
|
7323
|
-
|
7457
|
+
switch(paramMatch[1]) {
|
7458
|
+
case ':':
|
7459
|
+
regex += '([^\\/]*)';
|
7460
|
+
break;
|
7461
|
+
case '*':
|
7462
|
+
regex += '(.*)';
|
7463
|
+
break;
|
7464
|
+
}
|
7465
|
+
params.push(paramMatch[2]);
|
7324
7466
|
lastMatchedIndex = re.lastIndex;
|
7325
7467
|
}
|
7326
7468
|
// Append trailing path part.
|
@@ -7372,9 +7514,18 @@ function $RouteProvider(){
|
|
7372
7514
|
values.push(isString(value) ? $injector.get(value) : $injector.invoke(value));
|
7373
7515
|
});
|
7374
7516
|
if (isDefined(template = next.template)) {
|
7517
|
+
if (isFunction(template)) {
|
7518
|
+
template = template(next.params);
|
7519
|
+
}
|
7375
7520
|
} else if (isDefined(template = next.templateUrl)) {
|
7376
|
-
|
7377
|
-
|
7521
|
+
if (isFunction(template)) {
|
7522
|
+
template = template(next.params);
|
7523
|
+
}
|
7524
|
+
if (isDefined(template)) {
|
7525
|
+
next.loadedTemplateUrl = template;
|
7526
|
+
template = $http.get(template, {cache: $templateCache}).
|
7527
|
+
then(function(response) { return response.data; });
|
7528
|
+
}
|
7378
7529
|
}
|
7379
7530
|
if (isDefined(template)) {
|
7380
7531
|
keys.push('$template');
|
@@ -7672,7 +7823,6 @@ function $RootScopeProvider(){
|
|
7672
7823
|
child['this'] = child;
|
7673
7824
|
child.$$listeners = {};
|
7674
7825
|
child.$parent = this;
|
7675
|
-
child.$$asyncQueue = [];
|
7676
7826
|
child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null;
|
7677
7827
|
child.$$prevSibling = this.$$childTail;
|
7678
7828
|
if (this.$$childHead) {
|
@@ -7776,6 +7926,14 @@ function $RootScopeProvider(){
|
|
7776
7926
|
watcher.fn = function(newVal, oldVal, scope) {listenFn(scope);};
|
7777
7927
|
}
|
7778
7928
|
|
7929
|
+
if (typeof watchExp == 'string' && get.constant) {
|
7930
|
+
var originalFn = watcher.fn;
|
7931
|
+
watcher.fn = function(newVal, oldVal, scope) {
|
7932
|
+
originalFn.call(this, newVal, oldVal, scope);
|
7933
|
+
arrayRemove(array, watcher);
|
7934
|
+
};
|
7935
|
+
}
|
7936
|
+
|
7779
7937
|
if (!array) {
|
7780
7938
|
array = scope.$$watchers = [];
|
7781
7939
|
}
|
@@ -7839,7 +7997,7 @@ function $RootScopeProvider(){
|
|
7839
7997
|
$digest: function() {
|
7840
7998
|
var watch, value, last,
|
7841
7999
|
watchers,
|
7842
|
-
asyncQueue,
|
8000
|
+
asyncQueue = this.$$asyncQueue,
|
7843
8001
|
length,
|
7844
8002
|
dirty, ttl = TTL,
|
7845
8003
|
next, current, target = this,
|
@@ -7848,18 +8006,19 @@ function $RootScopeProvider(){
|
|
7848
8006
|
|
7849
8007
|
beginPhase('$digest');
|
7850
8008
|
|
7851
|
-
do {
|
8009
|
+
do { // "while dirty" loop
|
7852
8010
|
dirty = false;
|
7853
8011
|
current = target;
|
7854
|
-
|
7855
|
-
|
7856
|
-
|
7857
|
-
|
7858
|
-
|
7859
|
-
|
7860
|
-
$exceptionHandler(e);
|
7861
|
-
}
|
8012
|
+
|
8013
|
+
while(asyncQueue.length) {
|
8014
|
+
try {
|
8015
|
+
current.$eval(asyncQueue.shift());
|
8016
|
+
} catch (e) {
|
8017
|
+
$exceptionHandler(e);
|
7862
8018
|
}
|
8019
|
+
}
|
8020
|
+
|
8021
|
+
do { // "traverse the scopes" loop
|
7863
8022
|
if ((watchers = current.$$watchers)) {
|
7864
8023
|
// process our watches
|
7865
8024
|
length = watchers.length;
|
@@ -8296,6 +8455,7 @@ function $RootScopeProvider(){
|
|
8296
8455
|
*
|
8297
8456
|
* @name ng.$sniffer
|
8298
8457
|
* @requires $window
|
8458
|
+
* @requires $document
|
8299
8459
|
*
|
8300
8460
|
* @property {boolean} history Does the browser support html5 history api ?
|
8301
8461
|
* @property {boolean} hashchange Does the browser support hashchange event ?
|
@@ -8304,9 +8464,10 @@ function $RootScopeProvider(){
|
|
8304
8464
|
* This is very simple implementation of testing browser's features.
|
8305
8465
|
*/
|
8306
8466
|
function $SnifferProvider() {
|
8307
|
-
this.$get = ['$window', function($window) {
|
8467
|
+
this.$get = ['$window', '$document', function($window, $document) {
|
8308
8468
|
var eventSupport = {},
|
8309
|
-
android = int((/android (\d+)/.exec(lowercase($window.navigator.userAgent)) || [])[1])
|
8469
|
+
android = int((/android (\d+)/.exec(lowercase($window.navigator.userAgent)) || [])[1]),
|
8470
|
+
document = $document[0];
|
8310
8471
|
|
8311
8472
|
return {
|
8312
8473
|
// Android has history.pushState, but it does not update location correctly
|
@@ -8316,7 +8477,7 @@ function $SnifferProvider() {
|
|
8316
8477
|
history: !!($window.history && $window.history.pushState && !(android < 4)),
|
8317
8478
|
hashchange: 'onhashchange' in $window &&
|
8318
8479
|
// IE8 compatible mode lies
|
8319
|
-
(
|
8480
|
+
(!document.documentMode || document.documentMode > 7),
|
8320
8481
|
hasEvent: function(event) {
|
8321
8482
|
// IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have
|
8322
8483
|
// it. In particular the event is not fired when backspace or delete key are pressed or
|
@@ -8324,14 +8485,13 @@ function $SnifferProvider() {
|
|
8324
8485
|
if (event == 'input' && msie == 9) return false;
|
8325
8486
|
|
8326
8487
|
if (isUndefined(eventSupport[event])) {
|
8327
|
-
var divElm =
|
8488
|
+
var divElm = document.createElement('div');
|
8328
8489
|
eventSupport[event] = 'on' + event in divElm;
|
8329
8490
|
}
|
8330
8491
|
|
8331
8492
|
return eventSupport[event];
|
8332
8493
|
},
|
8333
|
-
|
8334
|
-
csp: false
|
8494
|
+
csp: document.securityPolicy ? document.securityPolicy.isActive : false
|
8335
8495
|
};
|
8336
8496
|
}];
|
8337
8497
|
}
|
@@ -8392,6 +8552,43 @@ function parseHeaders(headers) {
|
|
8392
8552
|
}
|
8393
8553
|
|
8394
8554
|
|
8555
|
+
var IS_SAME_DOMAIN_URL_MATCH = /^(([^:]+):)?\/\/(\w+:{0,1}\w*@)?([\w\.-]*)?(:([0-9]+))?(.*)$/;
|
8556
|
+
|
8557
|
+
|
8558
|
+
/**
|
8559
|
+
* Parse a request and location URL and determine whether this is a same-domain request.
|
8560
|
+
*
|
8561
|
+
* @param {string} requestUrl The url of the request.
|
8562
|
+
* @param {string} locationUrl The current browser location url.
|
8563
|
+
* @returns {boolean} Whether the request is for the same domain.
|
8564
|
+
*/
|
8565
|
+
function isSameDomain(requestUrl, locationUrl) {
|
8566
|
+
var match = IS_SAME_DOMAIN_URL_MATCH.exec(requestUrl);
|
8567
|
+
// if requestUrl is relative, the regex does not match.
|
8568
|
+
if (match == null) return true;
|
8569
|
+
|
8570
|
+
var domain1 = {
|
8571
|
+
protocol: match[2],
|
8572
|
+
host: match[4],
|
8573
|
+
port: int(match[6]) || DEFAULT_PORTS[match[2]] || null,
|
8574
|
+
// IE8 sets unmatched groups to '' instead of undefined.
|
8575
|
+
relativeProtocol: match[2] === undefined || match[2] === ''
|
8576
|
+
};
|
8577
|
+
|
8578
|
+
match = URL_MATCH.exec(locationUrl);
|
8579
|
+
var domain2 = {
|
8580
|
+
protocol: match[1],
|
8581
|
+
host: match[3],
|
8582
|
+
port: int(match[5]) || DEFAULT_PORTS[match[1]] || null
|
8583
|
+
};
|
8584
|
+
|
8585
|
+
return (domain1.protocol == domain2.protocol || domain1.relativeProtocol) &&
|
8586
|
+
domain1.host == domain2.host &&
|
8587
|
+
(domain1.port == domain2.port || (domain1.relativeProtocol &&
|
8588
|
+
domain2.port == DEFAULT_PORTS[domain2.protocol]));
|
8589
|
+
}
|
8590
|
+
|
8591
|
+
|
8395
8592
|
/**
|
8396
8593
|
* Returns a function that provides access to parsed headers.
|
8397
8594
|
*
|
@@ -8451,7 +8648,7 @@ function $HttpProvider() {
|
|
8451
8648
|
JSON_END = /[\}\]]\s*$/,
|
8452
8649
|
PROTECTION_PREFIX = /^\)\]\}',?\n/;
|
8453
8650
|
|
8454
|
-
var
|
8651
|
+
var defaults = this.defaults = {
|
8455
8652
|
// transform incoming response data
|
8456
8653
|
transformResponse: [function(data) {
|
8457
8654
|
if (isString(data)) {
|
@@ -8471,12 +8668,14 @@ function $HttpProvider() {
|
|
8471
8668
|
// default headers
|
8472
8669
|
headers: {
|
8473
8670
|
common: {
|
8474
|
-
'Accept': 'application/json, text/plain, */*'
|
8475
|
-
'X-Requested-With': 'XMLHttpRequest'
|
8671
|
+
'Accept': 'application/json, text/plain, */*'
|
8476
8672
|
},
|
8477
8673
|
post: {'Content-Type': 'application/json;charset=utf-8'},
|
8478
8674
|
put: {'Content-Type': 'application/json;charset=utf-8'}
|
8479
|
-
}
|
8675
|
+
},
|
8676
|
+
|
8677
|
+
xsrfCookieName: 'XSRF-TOKEN',
|
8678
|
+
xsrfHeaderName: 'X-XSRF-TOKEN'
|
8480
8679
|
};
|
8481
8680
|
|
8482
8681
|
var providerResponseInterceptors = this.responseInterceptors = [];
|
@@ -8578,7 +8777,6 @@ function $HttpProvider() {
|
|
8578
8777
|
*
|
8579
8778
|
* - `$httpProvider.defaults.headers.common` (headers that are common for all requests):
|
8580
8779
|
* - `Accept: application/json, text/plain, * / *`
|
8581
|
-
* - `X-Requested-With: XMLHttpRequest`
|
8582
8780
|
* - `$httpProvider.defaults.headers.post`: (header defaults for HTTP POST requests)
|
8583
8781
|
* - `Content-Type: application/json`
|
8584
8782
|
* - `$httpProvider.defaults.headers.put` (header defaults for HTTP PUT requests)
|
@@ -8711,9 +8909,10 @@ function $HttpProvider() {
|
|
8711
8909
|
* {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF} is a technique by which
|
8712
8910
|
* an unauthorized site can gain your user's private data. Angular provides following mechanism
|
8713
8911
|
* to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie
|
8714
|
-
*
|
8715
|
-
* runs on your domain could read the cookie, your server can be assured that
|
8716
|
-
* JavaScript running on your domain.
|
8912
|
+
* (by default, `XSRF-TOKEN`) and sets it as an HTTP header (`X-XSRF-TOKEN`). Since only
|
8913
|
+
* JavaScript that runs on your domain could read the cookie, your server can be assured that
|
8914
|
+
* the XHR came from JavaScript running on your domain. The header will not be set for
|
8915
|
+
* cross-domain requests.
|
8717
8916
|
*
|
8718
8917
|
* To take advantage of this, your server needs to set a token in a JavaScript readable session
|
8719
8918
|
* cookie called `XSRF-TOKEN` on first HTTP GET request. On subsequent non-GET requests the
|
@@ -8723,6 +8922,9 @@ function $HttpProvider() {
|
|
8723
8922
|
* up its own tokens). We recommend that the token is a digest of your site's authentication
|
8724
8923
|
* cookie with {@link http://en.wikipedia.org/wiki/Rainbow_table salt for added security}.
|
8725
8924
|
*
|
8925
|
+
* The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName
|
8926
|
+
* properties of either $httpProvider.defaults, or the per-request config object.
|
8927
|
+
*
|
8726
8928
|
*
|
8727
8929
|
* @param {object} config Object describing the request to be made and how it should be
|
8728
8930
|
* processed. The object has following properties:
|
@@ -8733,6 +8935,8 @@ function $HttpProvider() {
|
|
8733
8935
|
* `?key1=value1&key2=value2` after the url. If the value is not a string, it will be JSONified.
|
8734
8936
|
* - **data** – `{string|Object}` – Data to be sent as the request message data.
|
8735
8937
|
* - **headers** – `{Object}` – Map of strings representing HTTP headers to send to the server.
|
8938
|
+
* - **xsrfHeaderName** – `{string}` – Name of HTTP header to populate with the XSRF token.
|
8939
|
+
* - **xsrfCookieName** – `{string}` – Name of cookie containing the XSRF token.
|
8736
8940
|
* - **transformRequest** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
|
8737
8941
|
* transform function or an array of such functions. The transform function takes the http
|
8738
8942
|
* request body and headers and returns its transformed (typically serialized) version.
|
@@ -8747,6 +8951,8 @@ function $HttpProvider() {
|
|
8747
8951
|
* - **withCredentials** - `{boolean}` - whether to to set the `withCredentials` flag on the
|
8748
8952
|
* XHR object. See {@link https://developer.mozilla.org/en/http_access_control#section_5
|
8749
8953
|
* requests with credentials} for more information.
|
8954
|
+
* - **responseType** - `{string}` - see {@link
|
8955
|
+
* https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType requestType}.
|
8750
8956
|
*
|
8751
8957
|
* @returns {HttpPromise} Returns a {@link ng.$q promise} object with the
|
8752
8958
|
* standard `then` method and two http specific methods: `success` and `error`. The `then`
|
@@ -8839,10 +9045,17 @@ function $HttpProvider() {
|
|
8839
9045
|
function $http(config) {
|
8840
9046
|
config.method = uppercase(config.method);
|
8841
9047
|
|
8842
|
-
var
|
8843
|
-
|
8844
|
-
|
8845
|
-
|
9048
|
+
var xsrfHeader = {},
|
9049
|
+
xsrfCookieName = config.xsrfCookieName || defaults.xsrfCookieName,
|
9050
|
+
xsrfHeaderName = config.xsrfHeaderName || defaults.xsrfHeaderName,
|
9051
|
+
xsrfToken = isSameDomain(config.url, $browser.url()) ?
|
9052
|
+
$browser.cookies()[xsrfCookieName] : undefined;
|
9053
|
+
xsrfHeader[xsrfHeaderName] = xsrfToken;
|
9054
|
+
|
9055
|
+
var reqTransformFn = config.transformRequest || defaults.transformRequest,
|
9056
|
+
respTransformFn = config.transformResponse || defaults.transformResponse,
|
9057
|
+
defHeaders = defaults.headers,
|
9058
|
+
reqHeaders = extend(xsrfHeader,
|
8846
9059
|
defHeaders.common, defHeaders[lowercase(config.method)], config.headers),
|
8847
9060
|
reqData = transformData(config.data, headersGetter(reqHeaders), reqTransformFn),
|
8848
9061
|
promise;
|
@@ -8852,6 +9065,10 @@ function $HttpProvider() {
|
|
8852
9065
|
delete reqHeaders['Content-Type'];
|
8853
9066
|
}
|
8854
9067
|
|
9068
|
+
if (isUndefined(config.withCredentials) && !isUndefined(defaults.withCredentials)) {
|
9069
|
+
config.withCredentials = defaults.withCredentials;
|
9070
|
+
}
|
9071
|
+
|
8855
9072
|
// send request
|
8856
9073
|
promise = sendReq(config, reqData, reqHeaders);
|
8857
9074
|
|
@@ -8983,11 +9200,11 @@ function $HttpProvider() {
|
|
8983
9200
|
*
|
8984
9201
|
* @description
|
8985
9202
|
* Runtime equivalent of the `$httpProvider.defaults` property. Allows configuration of
|
8986
|
-
* default headers as well as request and response transformations.
|
9203
|
+
* default headers, withCredentials as well as request and response transformations.
|
8987
9204
|
*
|
8988
9205
|
* See "Setting HTTP Headers" and "Transforming Requests and Responses" sections above.
|
8989
9206
|
*/
|
8990
|
-
$http.defaults =
|
9207
|
+
$http.defaults = defaults;
|
8991
9208
|
|
8992
9209
|
|
8993
9210
|
return $http;
|
@@ -9022,7 +9239,7 @@ function $HttpProvider() {
|
|
9022
9239
|
* Makes the request
|
9023
9240
|
*
|
9024
9241
|
* !!! ACCESSES CLOSURE VARS:
|
9025
|
-
* $httpBackend,
|
9242
|
+
* $httpBackend, defaults, $log, $rootScope, defaultCache, $http.pendingRequests
|
9026
9243
|
*/
|
9027
9244
|
function sendReq(config, reqData, reqHeaders) {
|
9028
9245
|
var deferred = $q.defer(),
|
@@ -9063,7 +9280,7 @@ function $HttpProvider() {
|
|
9063
9280
|
// if we won't have the response in cache, send the request to the backend
|
9064
9281
|
if (!cachedResp) {
|
9065
9282
|
$httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout,
|
9066
|
-
config.withCredentials);
|
9283
|
+
config.withCredentials, config.responseType);
|
9067
9284
|
}
|
9068
9285
|
|
9069
9286
|
return promise;
|
@@ -9118,10 +9335,15 @@ function $HttpProvider() {
|
|
9118
9335
|
var parts = [];
|
9119
9336
|
forEachSorted(params, function(value, key) {
|
9120
9337
|
if (value == null || value == undefined) return;
|
9121
|
-
if (
|
9122
|
-
|
9123
|
-
|
9124
|
-
|
9338
|
+
if (!isArray(value)) value = [value];
|
9339
|
+
|
9340
|
+
forEach(value, function(v) {
|
9341
|
+
if (isObject(v)) {
|
9342
|
+
v = toJson(v);
|
9343
|
+
}
|
9344
|
+
parts.push(encodeUriQuery(key) + '=' +
|
9345
|
+
encodeUriQuery(v));
|
9346
|
+
});
|
9125
9347
|
});
|
9126
9348
|
return url + ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&');
|
9127
9349
|
}
|
@@ -9163,7 +9385,7 @@ function $HttpBackendProvider() {
|
|
9163
9385
|
|
9164
9386
|
function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument, locationProtocol) {
|
9165
9387
|
// TODO(vojta): fix the signature
|
9166
|
-
return function(method, url, post, callback, headers, timeout, withCredentials) {
|
9388
|
+
return function(method, url, post, callback, headers, timeout, withCredentials, responseType) {
|
9167
9389
|
$browser.$$incOutstandingRequestCount();
|
9168
9390
|
url = url || $browser.url();
|
9169
9391
|
|
@@ -9218,7 +9440,7 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
|
|
9218
9440
|
}
|
9219
9441
|
// end of the workaround.
|
9220
9442
|
|
9221
|
-
completeRequest(callback, status || xhr.status, xhr.responseText,
|
9443
|
+
completeRequest(callback, status || xhr.status, xhr.response || xhr.responseText,
|
9222
9444
|
responseHeaders);
|
9223
9445
|
}
|
9224
9446
|
};
|
@@ -9227,6 +9449,10 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
|
|
9227
9449
|
xhr.withCredentials = true;
|
9228
9450
|
}
|
9229
9451
|
|
9452
|
+
if (responseType) {
|
9453
|
+
xhr.responseType = responseType;
|
9454
|
+
}
|
9455
|
+
|
9230
9456
|
xhr.send(post || '');
|
9231
9457
|
|
9232
9458
|
if (timeout > 0) {
|
@@ -9568,6 +9794,22 @@ function $FilterProvider($provide) {
|
|
9568
9794
|
* called for each element of `array`. The final result is an array of those elements that
|
9569
9795
|
* the predicate returned true for.
|
9570
9796
|
*
|
9797
|
+
* @param {function(expected, actual)|true|undefined} comparator Comparator which is used in
|
9798
|
+
* determining if the expected value (from the filter expression) and actual value (from
|
9799
|
+
* the object in the array) should be considered a match.
|
9800
|
+
*
|
9801
|
+
* Can be one of:
|
9802
|
+
*
|
9803
|
+
* - `function(expected, actual)`:
|
9804
|
+
* The function will be given the object value and the predicate value to compare and
|
9805
|
+
* should return true if the item should be included in filtered result.
|
9806
|
+
*
|
9807
|
+
* - `true`: A shorthand for `function(expected, actual) { return angular.equals(expected, actual)}`.
|
9808
|
+
* this is essentially strict comparison of expected and actual.
|
9809
|
+
*
|
9810
|
+
* - `false|undefined`: A short hand for a function which will look for a substring match in case
|
9811
|
+
* insensitive way.
|
9812
|
+
*
|
9571
9813
|
* @example
|
9572
9814
|
<doc:example>
|
9573
9815
|
<doc:source>
|
@@ -9575,7 +9817,8 @@ function $FilterProvider($provide) {
|
|
9575
9817
|
{name:'Mary', phone:'800-BIG-MARY'},
|
9576
9818
|
{name:'Mike', phone:'555-4321'},
|
9577
9819
|
{name:'Adam', phone:'555-5678'},
|
9578
|
-
{name:'Julie', phone:'555-8765'}
|
9820
|
+
{name:'Julie', phone:'555-8765'},
|
9821
|
+
{name:'Juliette', phone:'555-5678'}]"></div>
|
9579
9822
|
|
9580
9823
|
Search: <input ng-model="searchText">
|
9581
9824
|
<table id="searchTextResults">
|
@@ -9589,9 +9832,10 @@ function $FilterProvider($provide) {
|
|
9589
9832
|
Any: <input ng-model="search.$"> <br>
|
9590
9833
|
Name only <input ng-model="search.name"><br>
|
9591
9834
|
Phone only <input ng-model="search.phone"å><br>
|
9835
|
+
Equality <input type="checkbox" ng-model="strict"><br>
|
9592
9836
|
<table id="searchObjResults">
|
9593
9837
|
<tr><th>Name</th><th>Phone</th><tr>
|
9594
|
-
<tr ng-repeat="friend in friends | filter:search">
|
9838
|
+
<tr ng-repeat="friend in friends | filter:search:strict">
|
9595
9839
|
<td>{{friend.name}}</td>
|
9596
9840
|
<td>{{friend.phone}}</td>
|
9597
9841
|
<tr>
|
@@ -9611,13 +9855,19 @@ function $FilterProvider($provide) {
|
|
9611
9855
|
it('should search in specific fields when filtering with a predicate object', function() {
|
9612
9856
|
input('search.$').enter('i');
|
9613
9857
|
expect(repeater('#searchObjResults tr', 'friend in friends').column('friend.name')).
|
9614
|
-
toEqual(['Mary', 'Mike', 'Julie']);
|
9858
|
+
toEqual(['Mary', 'Mike', 'Julie', 'Juliette']);
|
9859
|
+
});
|
9860
|
+
it('should use a equal comparison when comparator is true', function() {
|
9861
|
+
input('search.name').enter('Julie');
|
9862
|
+
input('strict').check();
|
9863
|
+
expect(repeater('#searchObjResults tr', 'friend in friends').column('friend.name')).
|
9864
|
+
toEqual(['Julie']);
|
9615
9865
|
});
|
9616
9866
|
</doc:scenario>
|
9617
9867
|
</doc:example>
|
9618
9868
|
*/
|
9619
9869
|
function filterFilter() {
|
9620
|
-
return function(array, expression) {
|
9870
|
+
return function(array, expression, comperator) {
|
9621
9871
|
if (!isArray(array)) return array;
|
9622
9872
|
var predicates = [];
|
9623
9873
|
predicates.check = function(value) {
|
@@ -9628,20 +9878,43 @@ function filterFilter() {
|
|
9628
9878
|
}
|
9629
9879
|
return true;
|
9630
9880
|
};
|
9881
|
+
switch(typeof comperator) {
|
9882
|
+
case "function":
|
9883
|
+
break;
|
9884
|
+
case "boolean":
|
9885
|
+
if(comperator == true) {
|
9886
|
+
comperator = function(obj, text) {
|
9887
|
+
return angular.equals(obj, text);
|
9888
|
+
}
|
9889
|
+
break;
|
9890
|
+
}
|
9891
|
+
default:
|
9892
|
+
comperator = function(obj, text) {
|
9893
|
+
text = (''+text).toLowerCase();
|
9894
|
+
return (''+obj).toLowerCase().indexOf(text) > -1
|
9895
|
+
};
|
9896
|
+
}
|
9631
9897
|
var search = function(obj, text){
|
9632
|
-
if (text.charAt(0) === '!') {
|
9898
|
+
if (typeof text == 'string' && text.charAt(0) === '!') {
|
9633
9899
|
return !search(obj, text.substr(1));
|
9634
9900
|
}
|
9635
9901
|
switch (typeof obj) {
|
9636
9902
|
case "boolean":
|
9637
9903
|
case "number":
|
9638
9904
|
case "string":
|
9639
|
-
return (
|
9905
|
+
return comperator(obj, text);
|
9640
9906
|
case "object":
|
9641
|
-
|
9642
|
-
|
9643
|
-
return
|
9644
|
-
|
9907
|
+
switch (typeof text) {
|
9908
|
+
case "object":
|
9909
|
+
return comperator(obj, text);
|
9910
|
+
break;
|
9911
|
+
default:
|
9912
|
+
for ( var objKey in obj) {
|
9913
|
+
if (objKey.charAt(0) !== '$' && search(obj[objKey], text)) {
|
9914
|
+
return true;
|
9915
|
+
}
|
9916
|
+
}
|
9917
|
+
break;
|
9645
9918
|
}
|
9646
9919
|
return false;
|
9647
9920
|
case "array":
|
@@ -9664,19 +9937,18 @@ function filterFilter() {
|
|
9664
9937
|
for (var key in expression) {
|
9665
9938
|
if (key == '$') {
|
9666
9939
|
(function() {
|
9667
|
-
|
9668
|
-
|
9940
|
+
if (!expression[key]) return;
|
9941
|
+
var path = key
|
9669
9942
|
predicates.push(function(value) {
|
9670
|
-
return search(value,
|
9943
|
+
return search(value, expression[path]);
|
9671
9944
|
});
|
9672
9945
|
})();
|
9673
9946
|
} else {
|
9674
9947
|
(function() {
|
9948
|
+
if (!expression[key]) return;
|
9675
9949
|
var path = key;
|
9676
|
-
var text = (''+expression[key]).toLowerCase();
|
9677
|
-
if (!text) return;
|
9678
9950
|
predicates.push(function(value) {
|
9679
|
-
return search(getter(value,
|
9951
|
+
return search(getter(value,path), expression[path]);
|
9680
9952
|
});
|
9681
9953
|
})();
|
9682
9954
|
}
|
@@ -9940,6 +10212,9 @@ var DATE_FORMATS = {
|
|
9940
10212
|
m: dateGetter('Minutes', 1),
|
9941
10213
|
ss: dateGetter('Seconds', 2),
|
9942
10214
|
s: dateGetter('Seconds', 1),
|
10215
|
+
// while ISO 8601 requires fractions to be prefixed with `.` or `,`
|
10216
|
+
// we can be just safely rely on using `sss` since we currently don't support single or two digit fractions
|
10217
|
+
sss: dateGetter('Milliseconds', 3),
|
9943
10218
|
EEEE: dateStrGetter('Day'),
|
9944
10219
|
EEE: dateStrGetter('Day', true),
|
9945
10220
|
a: ampmGetter,
|
@@ -9978,6 +10253,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
|
|
9978
10253
|
* * `'m'`: Minute in hour (0-59)
|
9979
10254
|
* * `'ss'`: Second in minute, padded (00-59)
|
9980
10255
|
* * `'s'`: Second in minute (0-59)
|
10256
|
+
* * `'.sss' or ',sss'`: Millisecond in second, padded (000-999)
|
9981
10257
|
* * `'a'`: am/pm marker
|
9982
10258
|
* * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-1200)
|
9983
10259
|
*
|
@@ -10034,18 +10310,22 @@ function dateFilter($locale) {
|
|
10034
10310
|
|
10035
10311
|
|
10036
10312
|
var R_ISO8601_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;
|
10037
|
-
|
10313
|
+
// 1 2 3 4 5 6 7 8 9 10 11
|
10314
|
+
function jsonStringToDate(string) {
|
10038
10315
|
var match;
|
10039
10316
|
if (match = string.match(R_ISO8601_STR)) {
|
10040
10317
|
var date = new Date(0),
|
10041
10318
|
tzHour = 0,
|
10042
|
-
tzMin = 0
|
10319
|
+
tzMin = 0,
|
10320
|
+
dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear,
|
10321
|
+
timeSetter = match[8] ? date.setUTCHours : date.setHours;
|
10322
|
+
|
10043
10323
|
if (match[9]) {
|
10044
10324
|
tzHour = int(match[9] + match[10]);
|
10045
10325
|
tzMin = int(match[9] + match[11]);
|
10046
10326
|
}
|
10047
|
-
|
10048
|
-
|
10327
|
+
dateSetter.call(date, int(match[1]), int(match[2]) - 1, int(match[3]));
|
10328
|
+
timeSetter.call(date, int(match[4]||0) - tzHour, int(match[5]||0) - tzMin, int(match[6]||0), int(match[7]||0));
|
10049
10329
|
return date;
|
10050
10330
|
}
|
10051
10331
|
return string;
|
@@ -10159,20 +10439,20 @@ var uppercaseFilter = valueFn(uppercase);
|
|
10159
10439
|
* @function
|
10160
10440
|
*
|
10161
10441
|
* @description
|
10162
|
-
* Creates a new array containing only a specified number of elements
|
10163
|
-
* are taken from either the beginning or the end of the source array, as specified by
|
10164
|
-
* value and sign (positive or negative) of `limit`.
|
10442
|
+
* Creates a new array or string containing only a specified number of elements. The elements
|
10443
|
+
* are taken from either the beginning or the end of the source array or string, as specified by
|
10444
|
+
* the value and sign (positive or negative) of `limit`.
|
10165
10445
|
*
|
10166
10446
|
* Note: This function is used to augment the `Array` type in Angular expressions. See
|
10167
10447
|
* {@link ng.$filter} for more information about Angular arrays.
|
10168
10448
|
*
|
10169
|
-
* @param {Array}
|
10170
|
-
* @param {string|
|
10171
|
-
* positive, `limit` number of items from the beginning of the source array are copied.
|
10172
|
-
* If the number is negative, `limit` number of items from the end of the source array
|
10173
|
-
* copied. The `limit` will be trimmed if it exceeds `array.length`
|
10174
|
-
* @returns {Array} A new sub-array of length `limit` or less if input array
|
10175
|
-
* elements.
|
10449
|
+
* @param {Array|string} input Source array or string to be limited.
|
10450
|
+
* @param {string|number} limit The length of the returned array or string. If the `limit` number
|
10451
|
+
* is positive, `limit` number of items from the beginning of the source array/string are copied.
|
10452
|
+
* If the number is negative, `limit` number of items from the end of the source array/string
|
10453
|
+
* are copied. The `limit` will be trimmed if it exceeds `array.length`
|
10454
|
+
* @returns {Array|string} A new sub-array or substring of length `limit` or less if input array
|
10455
|
+
* had less than `limit` elements.
|
10176
10456
|
*
|
10177
10457
|
* @example
|
10178
10458
|
<doc:example>
|
@@ -10180,59 +10460,76 @@ var uppercaseFilter = valueFn(uppercase);
|
|
10180
10460
|
<script>
|
10181
10461
|
function Ctrl($scope) {
|
10182
10462
|
$scope.numbers = [1,2,3,4,5,6,7,8,9];
|
10183
|
-
$scope.
|
10463
|
+
$scope.letters = "abcdefghi";
|
10464
|
+
$scope.numLimit = 3;
|
10465
|
+
$scope.letterLimit = 3;
|
10184
10466
|
}
|
10185
10467
|
</script>
|
10186
10468
|
<div ng-controller="Ctrl">
|
10187
|
-
Limit {{numbers}} to: <input type="integer" ng-model="
|
10188
|
-
<p>Output: {{ numbers | limitTo:
|
10469
|
+
Limit {{numbers}} to: <input type="integer" ng-model="numLimit">
|
10470
|
+
<p>Output numbers: {{ numbers | limitTo:numLimit }}</p>
|
10471
|
+
Limit {{letters}} to: <input type="integer" ng-model="letterLimit">
|
10472
|
+
<p>Output letters: {{ letters | limitTo:letterLimit }}</p>
|
10189
10473
|
</div>
|
10190
10474
|
</doc:source>
|
10191
10475
|
<doc:scenario>
|
10192
|
-
it('should limit the
|
10193
|
-
expect(element('.doc-example-live input[ng-model=
|
10194
|
-
expect(
|
10476
|
+
it('should limit the number array to first three items', function() {
|
10477
|
+
expect(element('.doc-example-live input[ng-model=numLimit]').val()).toBe('3');
|
10478
|
+
expect(element('.doc-example-live input[ng-model=letterLimit]').val()).toBe('3');
|
10479
|
+
expect(binding('numbers | limitTo:numLimit')).toEqual('[1,2,3]');
|
10480
|
+
expect(binding('letters | limitTo:letterLimit')).toEqual('abc');
|
10195
10481
|
});
|
10196
10482
|
|
10197
10483
|
it('should update the output when -3 is entered', function() {
|
10198
|
-
input('
|
10199
|
-
|
10484
|
+
input('numLimit').enter(-3);
|
10485
|
+
input('letterLimit').enter(-3);
|
10486
|
+
expect(binding('numbers | limitTo:numLimit')).toEqual('[7,8,9]');
|
10487
|
+
expect(binding('letters | limitTo:letterLimit')).toEqual('ghi');
|
10200
10488
|
});
|
10201
10489
|
|
10202
10490
|
it('should not exceed the maximum size of input array', function() {
|
10203
|
-
input('
|
10204
|
-
|
10491
|
+
input('numLimit').enter(100);
|
10492
|
+
input('letterLimit').enter(100);
|
10493
|
+
expect(binding('numbers | limitTo:numLimit')).toEqual('[1,2,3,4,5,6,7,8,9]');
|
10494
|
+
expect(binding('letters | limitTo:letterLimit')).toEqual('abcdefghi');
|
10205
10495
|
});
|
10206
10496
|
</doc:scenario>
|
10207
10497
|
</doc:example>
|
10208
10498
|
*/
|
10209
10499
|
function limitToFilter(){
|
10210
|
-
return function(
|
10211
|
-
if (!(
|
10500
|
+
return function(input, limit) {
|
10501
|
+
if (!isArray(input) && !isString(input)) return input;
|
10502
|
+
|
10212
10503
|
limit = int(limit);
|
10504
|
+
|
10505
|
+
if (isString(input)) {
|
10506
|
+
//NaN check on limit
|
10507
|
+
if (limit) {
|
10508
|
+
return limit >= 0 ? input.slice(0, limit) : input.slice(limit, input.length);
|
10509
|
+
} else {
|
10510
|
+
return "";
|
10511
|
+
}
|
10512
|
+
}
|
10513
|
+
|
10213
10514
|
var out = [],
|
10214
10515
|
i, n;
|
10215
10516
|
|
10216
|
-
// check that array is iterable
|
10217
|
-
if (!array || !(array instanceof Array))
|
10218
|
-
return out;
|
10219
|
-
|
10220
10517
|
// if abs(limit) exceeds maximum length, trim it
|
10221
|
-
if (limit >
|
10222
|
-
limit =
|
10223
|
-
else if (limit < -
|
10224
|
-
limit = -
|
10518
|
+
if (limit > input.length)
|
10519
|
+
limit = input.length;
|
10520
|
+
else if (limit < -input.length)
|
10521
|
+
limit = -input.length;
|
10225
10522
|
|
10226
10523
|
if (limit > 0) {
|
10227
10524
|
i = 0;
|
10228
10525
|
n = limit;
|
10229
10526
|
} else {
|
10230
|
-
i =
|
10231
|
-
n =
|
10527
|
+
i = input.length + limit;
|
10528
|
+
n = input.length;
|
10232
10529
|
}
|
10233
10530
|
|
10234
10531
|
for (; i<n; i++) {
|
10235
|
-
out.push(
|
10532
|
+
out.push(input[i]);
|
10236
10533
|
}
|
10237
10534
|
|
10238
10535
|
return out;
|
@@ -10700,6 +10997,37 @@ var htmlAnchorDirective = valueFn({
|
|
10700
10997
|
* @param {string} expression Angular expression that will be evaluated.
|
10701
10998
|
*/
|
10702
10999
|
|
11000
|
+
/**
|
11001
|
+
* @ngdoc directive
|
11002
|
+
* @name ng.directive:ngOpen
|
11003
|
+
* @restrict A
|
11004
|
+
*
|
11005
|
+
* @description
|
11006
|
+
* The HTML specs do not require browsers to preserve the special attributes such as open.
|
11007
|
+
* (The presence of them means true and absence means false)
|
11008
|
+
* This prevents the angular compiler from correctly retrieving the binding expression.
|
11009
|
+
* To solve this problem, we introduce the `ngOpen` directive.
|
11010
|
+
*
|
11011
|
+
* @example
|
11012
|
+
<doc:example>
|
11013
|
+
<doc:source>
|
11014
|
+
Check me check multiple: <input type="checkbox" ng-model="open"><br/>
|
11015
|
+
<details id="details" ng-open="open">
|
11016
|
+
<summary>Show/Hide me</summary>
|
11017
|
+
</details>
|
11018
|
+
</doc:source>
|
11019
|
+
<doc:scenario>
|
11020
|
+
it('should toggle open', function() {
|
11021
|
+
expect(element('#details').prop('open')).toBeFalsy();
|
11022
|
+
input('open').check();
|
11023
|
+
expect(element('#details').prop('open')).toBeTruthy();
|
11024
|
+
});
|
11025
|
+
</doc:scenario>
|
11026
|
+
</doc:example>
|
11027
|
+
*
|
11028
|
+
* @element DETAILS
|
11029
|
+
* @param {string} expression Angular expression that will be evaluated.
|
11030
|
+
*/
|
10703
11031
|
|
10704
11032
|
var ngAttributeAliasDirectives = {};
|
10705
11033
|
|
@@ -10750,7 +11078,8 @@ var nullFormCtrl = {
|
|
10750
11078
|
$addControl: noop,
|
10751
11079
|
$removeControl: noop,
|
10752
11080
|
$setValidity: noop,
|
10753
|
-
$setDirty: noop
|
11081
|
+
$setDirty: noop,
|
11082
|
+
$setPristine: noop
|
10754
11083
|
};
|
10755
11084
|
|
10756
11085
|
/**
|
@@ -10782,7 +11111,8 @@ function FormController(element, attrs) {
|
|
10782
11111
|
var form = this,
|
10783
11112
|
parentForm = element.parent().controller('form') || nullFormCtrl,
|
10784
11113
|
invalidCount = 0, // used to easily determine if we are valid
|
10785
|
-
errors = form.$error = {}
|
11114
|
+
errors = form.$error = {},
|
11115
|
+
controls = [];
|
10786
11116
|
|
10787
11117
|
// init state
|
10788
11118
|
form.$name = attrs.name;
|
@@ -10806,6 +11136,8 @@ function FormController(element, attrs) {
|
|
10806
11136
|
}
|
10807
11137
|
|
10808
11138
|
form.$addControl = function(control) {
|
11139
|
+
controls.push(control);
|
11140
|
+
|
10809
11141
|
if (control.$name && !form.hasOwnProperty(control.$name)) {
|
10810
11142
|
form[control.$name] = control;
|
10811
11143
|
}
|
@@ -10818,6 +11150,8 @@ function FormController(element, attrs) {
|
|
10818
11150
|
forEach(errors, function(queue, validationToken) {
|
10819
11151
|
form.$setValidity(validationToken, true, control);
|
10820
11152
|
});
|
11153
|
+
|
11154
|
+
arrayRemove(controls, control);
|
10821
11155
|
};
|
10822
11156
|
|
10823
11157
|
form.$setValidity = function(validationToken, isValid, control) {
|
@@ -10865,6 +11199,29 @@ function FormController(element, attrs) {
|
|
10865
11199
|
parentForm.$setDirty();
|
10866
11200
|
};
|
10867
11201
|
|
11202
|
+
/**
|
11203
|
+
* @ngdoc function
|
11204
|
+
* @name ng.directive:form.FormController#$setPristine
|
11205
|
+
* @methodOf ng.directive:form.FormController
|
11206
|
+
*
|
11207
|
+
* @description
|
11208
|
+
* Sets the form to its pristine state.
|
11209
|
+
*
|
11210
|
+
* This method can be called to remove the 'ng-dirty' class and set the form to its pristine
|
11211
|
+
* state (ng-pristine class). This method will also propagate to all the controls contained
|
11212
|
+
* in this form.
|
11213
|
+
*
|
11214
|
+
* Setting a form back to a pristine state is often useful when we want to 'reuse' a form after
|
11215
|
+
* saving or resetting it.
|
11216
|
+
*/
|
11217
|
+
form.$setPristine = function () {
|
11218
|
+
element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS);
|
11219
|
+
form.$dirty = false;
|
11220
|
+
form.$pristine = true;
|
11221
|
+
forEach(controls, function(control) {
|
11222
|
+
control.$setPristine();
|
11223
|
+
});
|
11224
|
+
};
|
10868
11225
|
}
|
10869
11226
|
|
10870
11227
|
|
@@ -11061,6 +11418,8 @@ var inputType = {
|
|
11061
11418
|
* patterns defined as scope expressions.
|
11062
11419
|
* @param {string=} ngChange Angular expression to be executed when input changes due to user
|
11063
11420
|
* interaction with the input element.
|
11421
|
+
* @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trimming the
|
11422
|
+
* input.
|
11064
11423
|
*
|
11065
11424
|
* @example
|
11066
11425
|
<doc:example>
|
@@ -11068,12 +11427,12 @@ var inputType = {
|
|
11068
11427
|
<script>
|
11069
11428
|
function Ctrl($scope) {
|
11070
11429
|
$scope.text = 'guest';
|
11071
|
-
$scope.word = /^\w*$/;
|
11430
|
+
$scope.word = /^\s*\w*\s*$/;
|
11072
11431
|
}
|
11073
11432
|
</script>
|
11074
11433
|
<form name="myForm" ng-controller="Ctrl">
|
11075
11434
|
Single word: <input type="text" name="input" ng-model="text"
|
11076
|
-
ng-pattern="word" required>
|
11435
|
+
ng-pattern="word" required ng-trim="false">
|
11077
11436
|
<span class="error" ng-show="myForm.input.$error.required">
|
11078
11437
|
Required!</span>
|
11079
11438
|
<span class="error" ng-show="myForm.input.$error.pattern">
|
@@ -11102,6 +11461,12 @@ var inputType = {
|
|
11102
11461
|
input('text').enter('hello world');
|
11103
11462
|
expect(binding('myForm.input.$valid')).toEqual('false');
|
11104
11463
|
});
|
11464
|
+
|
11465
|
+
it('should not be trimmed', function() {
|
11466
|
+
input('text').enter('untrimmed ');
|
11467
|
+
expect(binding('text')).toEqual('untrimmed ');
|
11468
|
+
expect(binding('myForm.input.$valid')).toEqual('true');
|
11469
|
+
});
|
11105
11470
|
</doc:scenario>
|
11106
11471
|
</doc:example>
|
11107
11472
|
*/
|
@@ -11415,7 +11780,14 @@ function isEmpty(value) {
|
|
11415
11780
|
function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
11416
11781
|
|
11417
11782
|
var listener = function() {
|
11418
|
-
var value =
|
11783
|
+
var value = element.val();
|
11784
|
+
|
11785
|
+
// By default we will trim the value
|
11786
|
+
// If the attribute ng-trim exists we will avoid trimming
|
11787
|
+
// e.g. <input ng-model="foo" ng-trim="false">
|
11788
|
+
if (toBoolean(attr.ngTrim || 'T')) {
|
11789
|
+
value = trim(value);
|
11790
|
+
}
|
11419
11791
|
|
11420
11792
|
if (ctrl.$viewValue !== value) {
|
11421
11793
|
scope.$apply(function() {
|
@@ -11996,6 +12368,22 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
11996
12368
|
parentForm.$setValidity(validationErrorKey, isValid, this);
|
11997
12369
|
};
|
11998
12370
|
|
12371
|
+
/**
|
12372
|
+
* @ngdoc function
|
12373
|
+
* @name ng.directive:ngModel.NgModelController#$setPristine
|
12374
|
+
* @methodOf ng.directive:ngModel.NgModelController
|
12375
|
+
*
|
12376
|
+
* @description
|
12377
|
+
* Sets the control to its pristine state.
|
12378
|
+
*
|
12379
|
+
* This method can be called to remove the 'ng-dirty' class and set the control to its pristine
|
12380
|
+
* state (ng-pristine class).
|
12381
|
+
*/
|
12382
|
+
this.$setPristine = function () {
|
12383
|
+
this.$dirty = false;
|
12384
|
+
this.$pristine = true;
|
12385
|
+
$element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS);
|
12386
|
+
};
|
11999
12387
|
|
12000
12388
|
/**
|
12001
12389
|
* @ngdoc function
|
@@ -12868,7 +13256,7 @@ var ngCspDirective = ['$sniffer', function($sniffer) {
|
|
12868
13256
|
*/
|
12869
13257
|
var ngEventDirectives = {};
|
12870
13258
|
forEach(
|
12871
|
-
'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave'.split(' '),
|
13259
|
+
'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup'.split(' '),
|
12872
13260
|
function(name) {
|
12873
13261
|
var directiveName = directiveNormalize('ng-' + name);
|
12874
13262
|
ngEventDirectives[directiveName] = ['$parse', function($parse) {
|
@@ -12995,6 +13383,38 @@ forEach(
|
|
12995
13383
|
*/
|
12996
13384
|
|
12997
13385
|
|
13386
|
+
/**
|
13387
|
+
* @ngdoc directive
|
13388
|
+
* @name ng.directive:ngKeydown
|
13389
|
+
*
|
13390
|
+
* @description
|
13391
|
+
* Specify custom behavior on keydown event.
|
13392
|
+
*
|
13393
|
+
* @element ANY
|
13394
|
+
* @param {expression} ngKeydown {@link guide/expression Expression} to evaluate upon
|
13395
|
+
* keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
|
13396
|
+
*
|
13397
|
+
* @example
|
13398
|
+
* See {@link ng.directive:ngClick ngClick}
|
13399
|
+
*/
|
13400
|
+
|
13401
|
+
|
13402
|
+
/**
|
13403
|
+
* @ngdoc directive
|
13404
|
+
* @name ng.directive:ngKeyup
|
13405
|
+
*
|
13406
|
+
* @description
|
13407
|
+
* Specify custom behavior on keyup event.
|
13408
|
+
*
|
13409
|
+
* @element ANY
|
13410
|
+
* @param {expression} ngKeyup {@link guide/expression Expression} to evaluate upon
|
13411
|
+
* keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
|
13412
|
+
*
|
13413
|
+
* @example
|
13414
|
+
* See {@link ng.directive:ngClick ngClick}
|
13415
|
+
*/
|
13416
|
+
|
13417
|
+
|
12998
13418
|
/**
|
12999
13419
|
* @ngdoc directive
|
13000
13420
|
* @name ng.directive:ngSubmit
|
@@ -13789,8 +14209,11 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
|
|
13789
14209
|
* On child elments add:
|
13790
14210
|
*
|
13791
14211
|
* * `ngSwitchWhen`: the case statement to match against. If match then this
|
13792
|
-
* case will be displayed.
|
13793
|
-
*
|
14212
|
+
* case will be displayed. If the same match appears multiple times, all the
|
14213
|
+
* elements will be displayed.
|
14214
|
+
* * `ngSwitchDefault`: the default case when no other case match. If there
|
14215
|
+
* are multiple default cases, all of them will be displayed when no other
|
14216
|
+
* case match.
|
13794
14217
|
*
|
13795
14218
|
* @example
|
13796
14219
|
<doc:example>
|
@@ -13838,22 +14261,28 @@ var ngSwitchDirective = valueFn({
|
|
13838
14261
|
}],
|
13839
14262
|
link: function(scope, element, attr, ctrl) {
|
13840
14263
|
var watchExpr = attr.ngSwitch || attr.on,
|
13841
|
-
|
13842
|
-
|
13843
|
-
|
14264
|
+
selectedTranscludes,
|
14265
|
+
selectedElements,
|
14266
|
+
selectedScopes = [];
|
13844
14267
|
|
13845
14268
|
scope.$watch(watchExpr, function ngSwitchWatchAction(value) {
|
13846
|
-
|
13847
|
-
|
13848
|
-
|
13849
|
-
selectedElement = selectedScope = null;
|
14269
|
+
for (var i= 0, ii=selectedScopes.length; i<ii; i++) {
|
14270
|
+
selectedScopes[i].$destroy();
|
14271
|
+
selectedElements[i].remove();
|
13850
14272
|
}
|
13851
|
-
|
14273
|
+
|
14274
|
+
selectedElements = [];
|
14275
|
+
selectedScopes = [];
|
14276
|
+
|
14277
|
+
if ((selectedTranscludes = ctrl.cases['!' + value] || ctrl.cases['?'])) {
|
13852
14278
|
scope.$eval(attr.change);
|
13853
|
-
|
13854
|
-
|
13855
|
-
|
13856
|
-
|
14279
|
+
forEach(selectedTranscludes, function(selectedTransclude) {
|
14280
|
+
var selectedScope = scope.$new();
|
14281
|
+
selectedScopes.push(selectedScope);
|
14282
|
+
selectedTransclude(selectedScope, function(caseElement) {
|
14283
|
+
selectedElements.push(caseElement);
|
14284
|
+
element.append(caseElement);
|
14285
|
+
});
|
13857
14286
|
});
|
13858
14287
|
}
|
13859
14288
|
});
|
@@ -13866,7 +14295,8 @@ var ngSwitchWhenDirective = ngDirective({
|
|
13866
14295
|
require: '^ngSwitch',
|
13867
14296
|
compile: function(element, attrs, transclude) {
|
13868
14297
|
return function(scope, element, attr, ctrl) {
|
13869
|
-
ctrl.cases['!' + attrs.ngSwitchWhen] =
|
14298
|
+
ctrl.cases['!' + attrs.ngSwitchWhen] = (ctrl.cases['!' + attrs.ngSwitchWhen] || []);
|
14299
|
+
ctrl.cases['!' + attrs.ngSwitchWhen].push(transclude);
|
13870
14300
|
};
|
13871
14301
|
}
|
13872
14302
|
});
|
@@ -13877,7 +14307,8 @@ var ngSwitchDefaultDirective = ngDirective({
|
|
13877
14307
|
require: '^ngSwitch',
|
13878
14308
|
compile: function(element, attrs, transclude) {
|
13879
14309
|
return function(scope, element, attr, ctrl) {
|
13880
|
-
ctrl.cases['?'] =
|
14310
|
+
ctrl.cases['?'] = (ctrl.cases['?'] || []);
|
14311
|
+
ctrl.cases['?'].push(transclude);
|
13881
14312
|
};
|
13882
14313
|
}
|
13883
14314
|
});
|