angularjs-rails 1.0.4 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/angularjs-rails/version.rb +1 -1
- data/vendor/assets/javascripts/angular-bootstrap-prettify.js +5 -5
- data/vendor/assets/javascripts/angular-bootstrap.js +1 -1
- data/vendor/assets/javascripts/angular-cookies.js +13 -1
- data/vendor/assets/javascripts/angular-loader.js +1 -1
- data/vendor/assets/javascripts/angular-mocks.js +1 -1
- data/vendor/assets/javascripts/angular-resource.js +8 -8
- data/vendor/assets/javascripts/angular-sanitize.js +1 -1
- data/vendor/assets/javascripts/angular-scenario.js +194 -65
- data/vendor/assets/javascripts/angular.js +193 -64
- metadata +1 -1
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.0.
|
2
|
+
* @license AngularJS v1.0.5
|
3
3
|
* (c) 2010-2012 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -55,8 +55,7 @@ if ('i' !== 'I'.toLowerCase()) {
|
|
55
55
|
function fromCharCode(code) {return String.fromCharCode(code);}
|
56
56
|
|
57
57
|
|
58
|
-
var
|
59
|
-
/** holds major version number for IE or NaN for real browsers */
|
58
|
+
var /** holds major version number for IE or NaN for real browsers */
|
60
59
|
msie = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]),
|
61
60
|
jqLite, // delay binding since jQuery could be loaded after us.
|
62
61
|
jQuery, // delay binding
|
@@ -97,6 +96,30 @@ var Error = window.Error,
|
|
97
96
|
* @param {Object=} context Object to become context (`this`) for the iterator function.
|
98
97
|
* @returns {Object|Array} Reference to `obj`.
|
99
98
|
*/
|
99
|
+
|
100
|
+
|
101
|
+
/**
|
102
|
+
* @private
|
103
|
+
* @param {*} obj
|
104
|
+
* @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, ...)
|
105
|
+
*/
|
106
|
+
function isArrayLike(obj) {
|
107
|
+
if (!obj || (typeof obj.length !== 'number')) return false;
|
108
|
+
|
109
|
+
// We have on object which has length property. Should we treat it as array?
|
110
|
+
if (typeof obj.hasOwnProperty != 'function' &&
|
111
|
+
typeof obj.constructor != 'function') {
|
112
|
+
// This is here for IE8: it is a bogus object treat it as array;
|
113
|
+
return true;
|
114
|
+
} else {
|
115
|
+
return obj instanceof JQLite || // JQLite
|
116
|
+
(jQuery && obj instanceof jQuery) || // jQuery
|
117
|
+
toString.call(obj) !== '[object Object]' || // some browser native object
|
118
|
+
typeof obj.callee === 'function'; // arguments (on IE8 looks like regular obj)
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
|
100
123
|
function forEach(obj, iterator, context) {
|
101
124
|
var key;
|
102
125
|
if (obj) {
|
@@ -108,7 +131,7 @@ function forEach(obj, iterator, context) {
|
|
108
131
|
}
|
109
132
|
} else if (obj.forEach && obj.forEach !== forEach) {
|
110
133
|
obj.forEach(iterator, context);
|
111
|
-
} else if (
|
134
|
+
} else if (isArrayLike(obj)) {
|
112
135
|
for (key = 0; key < obj.length; key++)
|
113
136
|
iterator.call(context, obj[key], key);
|
114
137
|
} else {
|
@@ -153,7 +176,7 @@ function reverseParams(iteratorFn) {
|
|
153
176
|
/**
|
154
177
|
* A consistent way of creating unique IDs in angular. The ID is a sequence of alpha numeric
|
155
178
|
* characters such as '012ABC'. The reason why we are not using simply a number counter is that
|
156
|
-
* the number string gets longer over time, and it can also overflow, where as the
|
179
|
+
* the number string gets longer over time, and it can also overflow, where as the nextId
|
157
180
|
* will grow much slower, it is a string, and it will never overflow.
|
158
181
|
*
|
159
182
|
* @returns an unique alpha-numeric string
|
@@ -549,9 +572,7 @@ function copy(source, destination){
|
|
549
572
|
} else {
|
550
573
|
if (source === destination) throw Error("Can't copy equivalent objects or arrays");
|
551
574
|
if (isArray(source)) {
|
552
|
-
|
553
|
-
destination.pop();
|
554
|
-
}
|
575
|
+
destination.length = 0;
|
555
576
|
for ( var i = 0; i < source.length; i++) {
|
556
577
|
destination.push(copy(source[i]));
|
557
578
|
}
|
@@ -762,9 +783,18 @@ function startingTag(element) {
|
|
762
783
|
// are not allowed to have children. So we just ignore it.
|
763
784
|
element.html('');
|
764
785
|
} catch(e) {}
|
765
|
-
|
766
|
-
|
767
|
-
|
786
|
+
// As Per DOM Standards
|
787
|
+
var TEXT_NODE = 3;
|
788
|
+
var elemHtml = jqLite('<div>').append(element).html();
|
789
|
+
try {
|
790
|
+
return element[0].nodeType === TEXT_NODE ? lowercase(elemHtml) :
|
791
|
+
elemHtml.
|
792
|
+
match(/^(<[^>]+>)/)[1].
|
793
|
+
replace(/^<([\w\-]+)/, function(match, nodeName) { return '<' + lowercase(nodeName); });
|
794
|
+
} catch(e) {
|
795
|
+
return lowercase(elemHtml);
|
796
|
+
}
|
797
|
+
|
768
798
|
}
|
769
799
|
|
770
800
|
|
@@ -848,7 +878,7 @@ function encodeUriQuery(val, pctEncodeSpaces) {
|
|
848
878
|
* Use this directive to auto-bootstrap on application. Only
|
849
879
|
* one directive can be used per HTML document. The directive
|
850
880
|
* designates the root of the application and is typically placed
|
851
|
-
*
|
881
|
+
* at the root of the page.
|
852
882
|
*
|
853
883
|
* In the example below if the `ngApp` directive would not be placed
|
854
884
|
* on the `html` element then the document would not be compiled
|
@@ -1249,11 +1279,11 @@ function setupModuleLoader(window) {
|
|
1249
1279
|
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
|
1250
1280
|
*/
|
1251
1281
|
var version = {
|
1252
|
-
full: '1.0.
|
1282
|
+
full: '1.0.5', // all of these placeholder strings will be replaced by rake's
|
1253
1283
|
major: 1, // compile task
|
1254
1284
|
minor: 0,
|
1255
|
-
dot:
|
1256
|
-
codeName: '
|
1285
|
+
dot: 5,
|
1286
|
+
codeName: 'flatulent-propulsion'
|
1257
1287
|
};
|
1258
1288
|
|
1259
1289
|
|
@@ -2430,7 +2460,7 @@ function annotate(fn) {
|
|
2430
2460
|
* This method does not work with code minfication / obfuscation. For this reason the following annotation strategies
|
2431
2461
|
* are supported.
|
2432
2462
|
*
|
2433
|
-
* # The `$
|
2463
|
+
* # The `$inject` property
|
2434
2464
|
*
|
2435
2465
|
* If a function has an `$inject` property and its value is an array of strings, then the strings represent names of
|
2436
2466
|
* services to be injected into the function.
|
@@ -3144,7 +3174,7 @@ function Browser(window, document, $log, $sniffer) {
|
|
3144
3174
|
*/
|
3145
3175
|
self.baseHref = function() {
|
3146
3176
|
var href = baseElement.attr('href');
|
3147
|
-
return href ? href.replace(/^https?\:\/\/[^\/]*/, '') :
|
3177
|
+
return href ? href.replace(/^https?\:\/\/[^\/]*/, '') : '';
|
3148
3178
|
};
|
3149
3179
|
|
3150
3180
|
//////////////////////////////////////////////////////////////
|
@@ -3594,7 +3624,8 @@ function $CompileProvider($provide) {
|
|
3594
3624
|
Suffix = 'Directive',
|
3595
3625
|
COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,
|
3596
3626
|
CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/,
|
3597
|
-
MULTI_ROOT_TEMPLATE_ERROR = 'Template must have exactly one root element. was: '
|
3627
|
+
MULTI_ROOT_TEMPLATE_ERROR = 'Template must have exactly one root element. was: ',
|
3628
|
+
urlSanitizationWhitelist = /^\s*(https?|ftp|mailto):/;
|
3598
3629
|
|
3599
3630
|
|
3600
3631
|
/**
|
@@ -3648,11 +3679,41 @@ function $CompileProvider($provide) {
|
|
3648
3679
|
};
|
3649
3680
|
|
3650
3681
|
|
3682
|
+
/**
|
3683
|
+
* @ngdoc function
|
3684
|
+
* @name ng.$compileProvider#urlSanitizationWhitelist
|
3685
|
+
* @methodOf ng.$compileProvider
|
3686
|
+
* @function
|
3687
|
+
*
|
3688
|
+
* @description
|
3689
|
+
* Retrieves or overrides the default regular expression that is used for whitelisting of safe
|
3690
|
+
* urls during a[href] sanitization.
|
3691
|
+
*
|
3692
|
+
* The sanitization is a security measure aimed at prevent XSS attacks via html links.
|
3693
|
+
*
|
3694
|
+
* Any url about to be assigned to a[href] via data-binding is first normalized and turned into an
|
3695
|
+
* absolute url. Afterwards the url is matched against the `urlSanitizationWhitelist` regular
|
3696
|
+
* expression. If a match is found the original url is written into the dom. Otherwise the
|
3697
|
+
* absolute url is prefixed with `'unsafe:'` string and only then it is written into the DOM.
|
3698
|
+
*
|
3699
|
+
* @param {RegExp=} regexp New regexp to whitelist urls with.
|
3700
|
+
* @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
|
3701
|
+
* chaining otherwise.
|
3702
|
+
*/
|
3703
|
+
this.urlSanitizationWhitelist = function(regexp) {
|
3704
|
+
if (isDefined(regexp)) {
|
3705
|
+
urlSanitizationWhitelist = regexp;
|
3706
|
+
return this;
|
3707
|
+
}
|
3708
|
+
return urlSanitizationWhitelist;
|
3709
|
+
};
|
3710
|
+
|
3711
|
+
|
3651
3712
|
this.$get = [
|
3652
3713
|
'$injector', '$interpolate', '$exceptionHandler', '$http', '$templateCache', '$parse',
|
3653
|
-
'$controller', '$rootScope',
|
3714
|
+
'$controller', '$rootScope', '$document',
|
3654
3715
|
function($injector, $interpolate, $exceptionHandler, $http, $templateCache, $parse,
|
3655
|
-
$controller, $rootScope) {
|
3716
|
+
$controller, $rootScope, $document) {
|
3656
3717
|
|
3657
3718
|
var Attributes = function(element, attr) {
|
3658
3719
|
this.$$element = element;
|
@@ -3674,7 +3735,8 @@ function $CompileProvider($provide) {
|
|
3674
3735
|
*/
|
3675
3736
|
$set: function(key, value, writeAttr, attrName) {
|
3676
3737
|
var booleanKey = getBooleanAttrName(this.$$element[0], key),
|
3677
|
-
$$observers = this.$$observers
|
3738
|
+
$$observers = this.$$observers,
|
3739
|
+
normalizedVal;
|
3678
3740
|
|
3679
3741
|
if (booleanKey) {
|
3680
3742
|
this.$$element.prop(key, value);
|
@@ -3693,6 +3755,19 @@ function $CompileProvider($provide) {
|
|
3693
3755
|
}
|
3694
3756
|
}
|
3695
3757
|
|
3758
|
+
|
3759
|
+
// sanitize a[href] values
|
3760
|
+
if (nodeName_(this.$$element[0]) === 'A' && key === 'href') {
|
3761
|
+
urlSanitizationNode.setAttribute('href', value);
|
3762
|
+
|
3763
|
+
// href property always returns normalized absolute url, so we can match against that
|
3764
|
+
normalizedVal = urlSanitizationNode.href;
|
3765
|
+
if (!normalizedVal.match(urlSanitizationWhitelist)) {
|
3766
|
+
this[key] = value = 'unsafe:' + normalizedVal;
|
3767
|
+
}
|
3768
|
+
}
|
3769
|
+
|
3770
|
+
|
3696
3771
|
if (writeAttr !== false) {
|
3697
3772
|
if (value === null || value === undefined) {
|
3698
3773
|
this.$$element.removeAttr(attrName);
|
@@ -3736,7 +3811,8 @@ function $CompileProvider($provide) {
|
|
3736
3811
|
}
|
3737
3812
|
};
|
3738
3813
|
|
3739
|
-
var
|
3814
|
+
var urlSanitizationNode = $document[0].createElement('a'),
|
3815
|
+
startSymbol = $interpolate.startSymbol(),
|
3740
3816
|
endSymbol = $interpolate.endSymbol(),
|
3741
3817
|
denormalizeTemplate = (startSymbol == '{{' || endSymbol == '}}')
|
3742
3818
|
? identity
|
@@ -3769,7 +3845,14 @@ function $CompileProvider($provide) {
|
|
3769
3845
|
var $linkNode = cloneConnectFn
|
3770
3846
|
? JQLitePrototype.clone.call($compileNodes) // IMPORTANT!!!
|
3771
3847
|
: $compileNodes;
|
3772
|
-
|
3848
|
+
|
3849
|
+
// Attach scope only to non-text nodes.
|
3850
|
+
for(var i = 0, ii = $linkNode.length; i<ii; i++) {
|
3851
|
+
var node = $linkNode[i];
|
3852
|
+
if (node.nodeType == 1 /* element */ || node.nodeType == 9 /* document */) {
|
3853
|
+
$linkNode.eq(i).data('$scope', scope);
|
3854
|
+
}
|
3855
|
+
}
|
3773
3856
|
safeAddClass($linkNode, 'ng-scope');
|
3774
3857
|
if (cloneConnectFn) cloneConnectFn($linkNode, scope);
|
3775
3858
|
if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode);
|
@@ -3859,6 +3942,7 @@ function $CompileProvider($provide) {
|
|
3859
3942
|
(function(transcludeFn) {
|
3860
3943
|
return function(cloneFn) {
|
3861
3944
|
var transcludeScope = scope.$new();
|
3945
|
+
transcludeScope.$$transcluded = true;
|
3862
3946
|
|
3863
3947
|
return transcludeFn(transcludeScope, cloneFn).
|
3864
3948
|
bind('$destroy', bind(transcludeScope, transcludeScope.$destroy));
|
@@ -4164,6 +4248,8 @@ function $CompileProvider($provide) {
|
|
4164
4248
|
lastValue,
|
4165
4249
|
parentGet, parentSet;
|
4166
4250
|
|
4251
|
+
scope.$$isolateBindings[scopeName] = mode + attrName;
|
4252
|
+
|
4167
4253
|
switch (mode) {
|
4168
4254
|
|
4169
4255
|
case '@': {
|
@@ -4374,7 +4460,7 @@ function $CompileProvider($provide) {
|
|
4374
4460
|
}
|
4375
4461
|
|
4376
4462
|
directives.unshift(derivedSyncDirective);
|
4377
|
-
afterTemplateNodeLinkFn = applyDirectivesToNode(directives,
|
4463
|
+
afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs, childTranscludeFn);
|
4378
4464
|
afterTemplateChildLinkFn = compileNodes($compileNode.contents(), childTranscludeFn);
|
4379
4465
|
|
4380
4466
|
|
@@ -4454,10 +4540,10 @@ function $CompileProvider($provide) {
|
|
4454
4540
|
function addAttrInterpolateDirective(node, directives, value, name) {
|
4455
4541
|
var interpolateFn = $interpolate(value, true);
|
4456
4542
|
|
4457
|
-
|
4458
4543
|
// no interpolation found -> ignore
|
4459
4544
|
if (!interpolateFn) return;
|
4460
4545
|
|
4546
|
+
|
4461
4547
|
directives.push({
|
4462
4548
|
priority: 100,
|
4463
4549
|
compile: valueFn(function attrInterpolateLinkFn(scope, element, attr) {
|
@@ -6451,9 +6537,10 @@ function getterFn(path, csp) {
|
|
6451
6537
|
* @param {string} expression String expression to compile.
|
6452
6538
|
* @returns {function(context, locals)} a function which represents the compiled expression:
|
6453
6539
|
*
|
6454
|
-
* * `context
|
6455
|
-
* against (
|
6456
|
-
* * `locals
|
6540
|
+
* * `context` – `{object}` – an object against which any expressions embedded in the strings
|
6541
|
+
* are evaluated against (tipically a scope object).
|
6542
|
+
* * `locals` – `{object=}` – local variables context object, useful for overriding values in
|
6543
|
+
* `context`.
|
6457
6544
|
*
|
6458
6545
|
* The return function also has an `assign` property, if the expression is assignable, which
|
6459
6546
|
* allows one to set values to expressions.
|
@@ -6489,7 +6576,7 @@ function $ParseProvider() {
|
|
6489
6576
|
* interface for interacting with an object that represents the result of an action that is
|
6490
6577
|
* performed asynchronously, and may or may not be finished at any given point in time.
|
6491
6578
|
*
|
6492
|
-
* From the perspective of dealing with error handling, deferred and promise
|
6579
|
+
* From the perspective of dealing with error handling, deferred and promise APIs are to
|
6493
6580
|
* asynchronous programming what `try`, `catch` and `throw` keywords are to synchronous programming.
|
6494
6581
|
*
|
6495
6582
|
* <pre>
|
@@ -6524,7 +6611,7 @@ function $ParseProvider() {
|
|
6524
6611
|
*
|
6525
6612
|
* At first it might not be obvious why this extra complexity is worth the trouble. The payoff
|
6526
6613
|
* comes in the way of
|
6527
|
-
* [guarantees that promise and deferred
|
6614
|
+
* [guarantees that promise and deferred APIs make](https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md).
|
6528
6615
|
*
|
6529
6616
|
* Additionally the promise api allows for composition that is very hard to do with the
|
6530
6617
|
* traditional callback ([CPS](http://en.wikipedia.org/wiki/Continuation-passing_style)) approach.
|
@@ -6536,7 +6623,7 @@ function $ParseProvider() {
|
|
6536
6623
|
*
|
6537
6624
|
* A new instance of deferred is constructed by calling `$q.defer()`.
|
6538
6625
|
*
|
6539
|
-
* The purpose of the deferred object is to expose the associated Promise instance as well as
|
6626
|
+
* The purpose of the deferred object is to expose the associated Promise instance as well as APIs
|
6540
6627
|
* that can be used for signaling the successful or unsuccessful completion of the task.
|
6541
6628
|
*
|
6542
6629
|
* **Methods**
|
@@ -6579,7 +6666,7 @@ function $ParseProvider() {
|
|
6579
6666
|
* return result + 1;
|
6580
6667
|
* });
|
6581
6668
|
*
|
6582
|
-
* // promiseB will be resolved immediately after promiseA is resolved and
|
6669
|
+
* // promiseB will be resolved immediately after promiseA is resolved and its value will be
|
6583
6670
|
* // the result of promiseA incremented by 1
|
6584
6671
|
* </pre>
|
6585
6672
|
*
|
@@ -6604,7 +6691,7 @@ function $ParseProvider() {
|
|
6604
6691
|
* # Testing
|
6605
6692
|
*
|
6606
6693
|
* <pre>
|
6607
|
-
* it('should simulate promise', inject(function($q, $
|
6694
|
+
* it('should simulate promise', inject(function($q, $rootScope) {
|
6608
6695
|
* var deferred = $q.defer();
|
6609
6696
|
* var promise = deferred.promise;
|
6610
6697
|
* var resolvedValue;
|
@@ -6613,7 +6700,7 @@ function $ParseProvider() {
|
|
6613
6700
|
* expect(resolvedValue).toBeUndefined();
|
6614
6701
|
*
|
6615
6702
|
* // Simulate resolving of promise
|
6616
|
-
*
|
6703
|
+
* deferred.resolve(123);
|
6617
6704
|
* // Note that the 'then' function does not get called synchronously.
|
6618
6705
|
* // This is because we want the promise API to always be async, whether or not
|
6619
6706
|
* // it got called synchronously or asynchronously.
|
@@ -6789,12 +6876,12 @@ function qFactory(nextTick, exceptionHandler) {
|
|
6789
6876
|
* @methodOf ng.$q
|
6790
6877
|
* @description
|
6791
6878
|
* Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise.
|
6792
|
-
* This is useful when you are dealing with
|
6879
|
+
* This is useful when you are dealing with an object that might or might not be a promise, or if
|
6793
6880
|
* the promise comes from a source that can't be trusted.
|
6794
6881
|
*
|
6795
6882
|
* @param {*} value Value or a promise
|
6796
6883
|
* @returns {Promise} Returns a single promise that will be resolved with an array of values,
|
6797
|
-
* each value
|
6884
|
+
* each value corresponding to the promise at the same index in the `promises` array. If any of
|
6798
6885
|
* the promises is resolved with a rejection, this resulting promise will be resolved with the
|
6799
6886
|
* same rejection.
|
6800
6887
|
*/
|
@@ -6856,7 +6943,7 @@ function qFactory(nextTick, exceptionHandler) {
|
|
6856
6943
|
*
|
6857
6944
|
* @param {Array.<Promise>} promises An array of promises.
|
6858
6945
|
* @returns {Promise} Returns a single promise that will be resolved with an array of values,
|
6859
|
-
* each value
|
6946
|
+
* each value corresponding to the promise at the same index in the `promises` array. If any of
|
6860
6947
|
* the promises is resolved with a rejection, this resulting promise will be resolved with the
|
6861
6948
|
* same rejection.
|
6862
6949
|
*/
|
@@ -7525,6 +7612,7 @@ function $RootScopeProvider(){
|
|
7525
7612
|
this.$$destroyed = false;
|
7526
7613
|
this.$$asyncQueue = [];
|
7527
7614
|
this.$$listeners = {};
|
7615
|
+
this.$$isolateBindings = {};
|
7528
7616
|
}
|
7529
7617
|
|
7530
7618
|
/**
|
@@ -8006,10 +8094,6 @@ function $RootScopeProvider(){
|
|
8006
8094
|
* Listens on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for discussion of
|
8007
8095
|
* event life cycle.
|
8008
8096
|
*
|
8009
|
-
* @param {string} name Event name to listen on.
|
8010
|
-
* @param {function(event)} listener Function to call when the event is emitted.
|
8011
|
-
* @returns {function()} Returns a deregistration function for this listener.
|
8012
|
-
*
|
8013
8097
|
* The event listener function format is: `function(event, args...)`. The `event` object
|
8014
8098
|
* passed into the listener has the following attributes:
|
8015
8099
|
*
|
@@ -8020,6 +8104,10 @@ function $RootScopeProvider(){
|
|
8020
8104
|
* propagation (available only for events that were `$emit`-ed).
|
8021
8105
|
* - `preventDefault` - `{function}`: calling `preventDefault` sets `defaultPrevented` flag to true.
|
8022
8106
|
* - `defaultPrevented` - `{boolean}`: true if `preventDefault` was called.
|
8107
|
+
*
|
8108
|
+
* @param {string} name Event name to listen on.
|
8109
|
+
* @param {function(event, args...)} listener Function to call when the event is emitted.
|
8110
|
+
* @returns {function()} Returns a deregistration function for this listener.
|
8023
8111
|
*/
|
8024
8112
|
$on: function(name, listener) {
|
8025
8113
|
var namedListeners = this.$$listeners[name];
|
@@ -8197,7 +8285,7 @@ function $RootScopeProvider(){
|
|
8197
8285
|
|
8198
8286
|
/**
|
8199
8287
|
* function used as an initial value for watchers.
|
8200
|
-
* because it's
|
8288
|
+
* because it's unique we can easily tell it apart from other values
|
8201
8289
|
*/
|
8202
8290
|
function initWatchVal() {}
|
8203
8291
|
}];
|
@@ -9108,8 +9196,30 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
|
|
9108
9196
|
// always async
|
9109
9197
|
xhr.onreadystatechange = function() {
|
9110
9198
|
if (xhr.readyState == 4) {
|
9111
|
-
|
9112
|
-
|
9199
|
+
var responseHeaders = xhr.getAllResponseHeaders();
|
9200
|
+
|
9201
|
+
// TODO(vojta): remove once Firefox 21 gets released.
|
9202
|
+
// begin: workaround to overcome Firefox CORS http response headers bug
|
9203
|
+
// https://bugzilla.mozilla.org/show_bug.cgi?id=608735
|
9204
|
+
// Firefox already patched in nightly. Should land in Firefox 21.
|
9205
|
+
|
9206
|
+
// CORS "simple response headers" http://www.w3.org/TR/cors/
|
9207
|
+
var value,
|
9208
|
+
simpleHeaders = ["Cache-Control", "Content-Language", "Content-Type",
|
9209
|
+
"Expires", "Last-Modified", "Pragma"];
|
9210
|
+
if (!responseHeaders) {
|
9211
|
+
responseHeaders = "";
|
9212
|
+
forEach(simpleHeaders, function (header) {
|
9213
|
+
var value = xhr.getResponseHeader(header);
|
9214
|
+
if (value) {
|
9215
|
+
responseHeaders += header + ": " + value + "\n";
|
9216
|
+
}
|
9217
|
+
});
|
9218
|
+
}
|
9219
|
+
// end of the workaround.
|
9220
|
+
|
9221
|
+
completeRequest(callback, status || xhr.status, xhr.responseText,
|
9222
|
+
responseHeaders);
|
9113
9223
|
}
|
9114
9224
|
};
|
9115
9225
|
|
@@ -9508,7 +9618,7 @@ function $FilterProvider($provide) {
|
|
9508
9618
|
*/
|
9509
9619
|
function filterFilter() {
|
9510
9620
|
return function(array, expression) {
|
9511
|
-
if (!(array
|
9621
|
+
if (!isArray(array)) return array;
|
9512
9622
|
var predicates = [];
|
9513
9623
|
predicates.check = function(value) {
|
9514
9624
|
for (var j = 0; j < predicates.length; j++) {
|
@@ -9757,7 +9867,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
|
|
9757
9867
|
fraction += '0';
|
9758
9868
|
}
|
9759
9869
|
|
9760
|
-
if (fractionSize) formatedText += decimalSep + fraction.substr(0, fractionSize);
|
9870
|
+
if (fractionSize && fractionSize !== "0") formatedText += decimalSep + fraction.substr(0, fractionSize);
|
9761
9871
|
}
|
9762
9872
|
|
9763
9873
|
parts.push(isNegative ? pattern.negPre : pattern.posPre);
|
@@ -9800,8 +9910,12 @@ function dateStrGetter(name, shortForm) {
|
|
9800
9910
|
}
|
9801
9911
|
|
9802
9912
|
function timeZoneGetter(date) {
|
9803
|
-
var
|
9804
|
-
|
9913
|
+
var zone = -1 * date.getTimezoneOffset();
|
9914
|
+
var paddedZone = (zone >= 0) ? "+" : "";
|
9915
|
+
|
9916
|
+
paddedZone += padNumber(zone / 60, 2) + padNumber(Math.abs(zone % 60), 2);
|
9917
|
+
|
9918
|
+
return paddedZone;
|
9805
9919
|
}
|
9806
9920
|
|
9807
9921
|
function ampmGetter(date, formats) {
|
@@ -9887,7 +10001,8 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
|
|
9887
10001
|
*
|
9888
10002
|
* @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or
|
9889
10003
|
* number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.SSSZ and it's
|
9890
|
-
* shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ).
|
10004
|
+
* shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is
|
10005
|
+
* specified in the string input, the time is considered to be in the local timezone.
|
9891
10006
|
* @param {string=} format Formatting rules (see Description). If not specified,
|
9892
10007
|
* `mediumDate` is used.
|
9893
10008
|
* @returns {string} Formatted string or the input if input is not recognized as date/millis.
|
@@ -9907,7 +10022,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
|
|
9907
10022
|
expect(binding("1288323623006 | date:'medium'")).
|
9908
10023
|
toMatch(/Oct 2\d, 2010 \d{1,2}:\d{2}:\d{2} (AM|PM)/);
|
9909
10024
|
expect(binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")).
|
9910
|
-
toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2}
|
10025
|
+
toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2} (\-|\+)?\d{4}/);
|
9911
10026
|
expect(binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")).
|
9912
10027
|
toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(AM|PM)/);
|
9913
10028
|
});
|
@@ -10213,7 +10328,7 @@ function limitToFilter(){
|
|
10213
10328
|
orderByFilter.$inject = ['$parse'];
|
10214
10329
|
function orderByFilter($parse){
|
10215
10330
|
return function(array, sortPredicate, reverseOrder) {
|
10216
|
-
if (!(array
|
10331
|
+
if (!isArray(array)) return array;
|
10217
10332
|
if (!sortPredicate) return array;
|
10218
10333
|
sortPredicate = isArray(sortPredicate) ? sortPredicate: [sortPredicate];
|
10219
10334
|
sortPredicate = map(sortPredicate, function(predicate){
|
@@ -10281,15 +10396,25 @@ function ngDirective(directive) {
|
|
10281
10396
|
*
|
10282
10397
|
* The reasoning for this change is to allow easy creation of action links with `ngClick` directive
|
10283
10398
|
* without changing the location or causing page reloads, e.g.:
|
10284
|
-
*
|
10399
|
+
* `<a href="" ng-click="model.$save()">Save</a>`
|
10285
10400
|
*/
|
10286
10401
|
var htmlAnchorDirective = valueFn({
|
10287
10402
|
restrict: 'E',
|
10288
10403
|
compile: function(element, attr) {
|
10289
|
-
|
10290
|
-
|
10291
|
-
|
10292
|
-
|
10404
|
+
|
10405
|
+
if (msie <= 8) {
|
10406
|
+
|
10407
|
+
// turn <a href ng-click="..">link</a> into a stylable link in IE
|
10408
|
+
// but only if it doesn't have name attribute, in which case it's an anchor
|
10409
|
+
if (!attr.href && !attr.name) {
|
10410
|
+
attr.$set('href', '');
|
10411
|
+
}
|
10412
|
+
|
10413
|
+
// add a comment node to anchors to workaround IE bug that causes element content to be reset
|
10414
|
+
// to new attribute content if attribute is updated with value containing @ and element also
|
10415
|
+
// contains value with @
|
10416
|
+
// see issue #1949
|
10417
|
+
element.append(document.createComment('IE fix'));
|
10293
10418
|
}
|
10294
10419
|
|
10295
10420
|
return function(scope, element) {
|
@@ -10369,7 +10494,7 @@ var htmlAnchorDirective = valueFn({
|
|
10369
10494
|
it('should execute ng-click but not reload when no href but name specified', function() {
|
10370
10495
|
element('#link-5').click();
|
10371
10496
|
expect(input('value').val()).toEqual('5');
|
10372
|
-
expect(element('#link-5').attr('href')).toBe(
|
10497
|
+
expect(element('#link-5').attr('href')).toBe(undefined);
|
10373
10498
|
});
|
10374
10499
|
|
10375
10500
|
it('should only change url when only ng-href', function() {
|
@@ -10612,8 +10737,9 @@ forEach(['src', 'href'], function(attrName) {
|
|
10612
10737
|
|
10613
10738
|
// on IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist
|
10614
10739
|
// then calling element.setAttribute('src', 'foo') doesn't do anything, so we need
|
10615
|
-
// to set the property as well to achieve the desired effect
|
10616
|
-
|
10740
|
+
// to set the property as well to achieve the desired effect.
|
10741
|
+
// we use attr[attrName] value since $set can sanitize the url.
|
10742
|
+
if (msie) element.prop(attrName, attr[attrName]);
|
10617
10743
|
});
|
10618
10744
|
}
|
10619
10745
|
};
|
@@ -12318,6 +12444,7 @@ var ngBindHtmlUnsafeDirective = [function() {
|
|
12318
12444
|
function classDirective(name, selector) {
|
12319
12445
|
name = 'ngClass' + name;
|
12320
12446
|
return ngDirective(function(scope, element, attr) {
|
12447
|
+
var oldVal = undefined;
|
12321
12448
|
|
12322
12449
|
scope.$watch(attr[name], ngClassWatchAction, true);
|
12323
12450
|
|
@@ -12341,13 +12468,14 @@ function classDirective(name, selector) {
|
|
12341
12468
|
}
|
12342
12469
|
|
12343
12470
|
|
12344
|
-
function ngClassWatchAction(newVal
|
12471
|
+
function ngClassWatchAction(newVal) {
|
12345
12472
|
if (selector === true || scope.$index % 2 === selector) {
|
12346
12473
|
if (oldVal && (newVal !== oldVal)) {
|
12347
12474
|
removeClass(oldVal);
|
12348
12475
|
}
|
12349
12476
|
addClass(newVal);
|
12350
12477
|
}
|
12478
|
+
oldVal = newVal;
|
12351
12479
|
}
|
12352
12480
|
|
12353
12481
|
|
@@ -12380,7 +12508,7 @@ function classDirective(name, selector) {
|
|
12380
12508
|
*
|
12381
12509
|
* The directive won't add duplicate classes if a particular class was already set.
|
12382
12510
|
*
|
12383
|
-
* When the expression changes, the previously added classes are removed and only then the
|
12511
|
+
* When the expression changes, the previously added classes are removed and only then the
|
12384
12512
|
* new classes are added.
|
12385
12513
|
*
|
12386
12514
|
* @element ANY
|
@@ -13704,9 +13832,10 @@ var NG_SWITCH = 'ng-switch';
|
|
13704
13832
|
var ngSwitchDirective = valueFn({
|
13705
13833
|
restrict: 'EA',
|
13706
13834
|
require: 'ngSwitch',
|
13707
|
-
|
13835
|
+
// asks for $scope to fool the BC controller module
|
13836
|
+
controller: ['$scope', function ngSwitchController() {
|
13708
13837
|
this.cases = {};
|
13709
|
-
},
|
13838
|
+
}],
|
13710
13839
|
link: function(scope, element, attr, ctrl) {
|
13711
13840
|
var watchExpr = attr.ngSwitch || attr.on,
|
13712
13841
|
selectedTransclude,
|
@@ -13957,7 +14086,7 @@ var ngViewDirective = ['$http', '$templateCache', '$route', '$anchorScroll', '$c
|
|
13957
14086
|
if (current.controller) {
|
13958
14087
|
locals.$scope = lastScope;
|
13959
14088
|
controller = $controller(current.controller, locals);
|
13960
|
-
element.
|
14089
|
+
element.children().data('$ngControllerController', controller);
|
13961
14090
|
}
|
13962
14091
|
|
13963
14092
|
link(lastScope);
|