angularjs-rails 1.2.26 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/angularjs-rails/version.rb +2 -2
- data/vendor/assets/javascripts/angular-animate.js +879 -456
- data/vendor/assets/javascripts/angular-aria.js +250 -0
- data/vendor/assets/javascripts/angular-cookies.js +1 -1
- data/vendor/assets/javascripts/angular-loader.js +17 -10
- data/vendor/assets/javascripts/angular-messages.js +400 -0
- data/vendor/assets/javascripts/angular-mocks.js +220 -110
- data/vendor/assets/javascripts/angular-resource.js +287 -247
- data/vendor/assets/javascripts/angular-route.js +111 -54
- data/vendor/assets/javascripts/angular-sanitize.js +1 -1
- data/vendor/assets/javascripts/angular-scenario.js +11579 -8665
- data/vendor/assets/javascripts/angular-touch.js +49 -11
- data/vendor/assets/javascripts/angular.js +6660 -3106
- data/vendor/assets/javascripts/unstable/angular-animate.js +240 -71
- data/vendor/assets/javascripts/unstable/angular-aria.js +12 -12
- data/vendor/assets/javascripts/unstable/angular-cookies.js +1 -1
- data/vendor/assets/javascripts/unstable/angular-loader.js +4 -4
- data/vendor/assets/javascripts/unstable/angular-messages.js +1 -1
- data/vendor/assets/javascripts/unstable/angular-mocks.js +21 -14
- data/vendor/assets/javascripts/unstable/angular-resource.js +2 -2
- data/vendor/assets/javascripts/unstable/angular-route.js +1 -1
- data/vendor/assets/javascripts/unstable/angular-sanitize.js +1 -1
- data/vendor/assets/javascripts/unstable/angular-scenario.js +562 -262
- data/vendor/assets/javascripts/unstable/angular-touch.js +1 -1
- data/vendor/assets/javascripts/unstable/angular.js +562 -262
- metadata +16 -14
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.3.0
|
2
|
+
* @license AngularJS v1.3.0
|
3
3
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -71,7 +71,7 @@ function minErr(module, ErrorConstructor) {
|
|
71
71
|
return match;
|
72
72
|
});
|
73
73
|
|
74
|
-
message = message + '\nhttp://errors.angularjs.org/1.3.0
|
74
|
+
message = message + '\nhttp://errors.angularjs.org/1.3.0/' +
|
75
75
|
(module ? module + '/' : '') + code;
|
76
76
|
for (i = 2; i < arguments.length; i++) {
|
77
77
|
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
|
@@ -413,7 +413,8 @@ function setHashKey(obj, h) {
|
|
413
413
|
*
|
414
414
|
* @description
|
415
415
|
* Extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
|
416
|
-
* to `dst`. You can specify multiple `src` objects.
|
416
|
+
* to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
|
417
|
+
* by passing an empty object as the target: `var object = angular.extend({}, object1, object2)`.
|
417
418
|
*
|
418
419
|
* @param {Object} dst Destination object.
|
419
420
|
* @param {...Object} src Source object(s).
|
@@ -1924,7 +1925,7 @@ function setupModuleLoader(window) {
|
|
1924
1925
|
* })
|
1925
1926
|
* ```
|
1926
1927
|
*
|
1927
|
-
* See {@link
|
1928
|
+
* See {@link ng.$animateProvider#register $animateProvider.register()} and
|
1928
1929
|
* {@link ngAnimate ngAnimate module} for more information.
|
1929
1930
|
*/
|
1930
1931
|
animation: invokeLater('$animateProvider', 'register'),
|
@@ -1974,7 +1975,7 @@ function setupModuleLoader(window) {
|
|
1974
1975
|
* @description
|
1975
1976
|
* Use this method to register work which needs to be performed on module loading.
|
1976
1977
|
* For more about how to configure services, see
|
1977
|
-
* {@link providers#
|
1978
|
+
* {@link providers#provider-recipe Provider Recipe}.
|
1978
1979
|
*/
|
1979
1980
|
config: config,
|
1980
1981
|
|
@@ -2121,11 +2122,11 @@ function setupModuleLoader(window) {
|
|
2121
2122
|
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
|
2122
2123
|
*/
|
2123
2124
|
var version = {
|
2124
|
-
full: '1.3.0
|
2125
|
+
full: '1.3.0', // all of these placeholder strings will be replaced by grunt's
|
2125
2126
|
major: 1, // package task
|
2126
2127
|
minor: 3,
|
2127
2128
|
dot: 0,
|
2128
|
-
codeName: '
|
2129
|
+
codeName: 'superluminal-nudge'
|
2129
2130
|
};
|
2130
2131
|
|
2131
2132
|
|
@@ -2300,7 +2301,7 @@ function publishExternalAPI(angular){
|
|
2300
2301
|
* - [`addClass()`](http://api.jquery.com/addClass/)
|
2301
2302
|
* - [`after()`](http://api.jquery.com/after/)
|
2302
2303
|
* - [`append()`](http://api.jquery.com/append/)
|
2303
|
-
* - [`attr()`](http://api.jquery.com/attr/)
|
2304
|
+
* - [`attr()`](http://api.jquery.com/attr/) - Does not support functions as parameters
|
2304
2305
|
* - [`bind()`](http://api.jquery.com/bind/) - Does not support namespaces, selectors or eventData
|
2305
2306
|
* - [`children()`](http://api.jquery.com/children/) - Does not support selectors
|
2306
2307
|
* - [`clone()`](http://api.jquery.com/clone/)
|
@@ -2535,18 +2536,22 @@ function jqLiteOff(element, type, fn, unsupported) {
|
|
2535
2536
|
if (!type) {
|
2536
2537
|
for (type in events) {
|
2537
2538
|
if (type !== '$destroy') {
|
2538
|
-
removeEventListenerFn(element, type,
|
2539
|
+
removeEventListenerFn(element, type, handle);
|
2539
2540
|
}
|
2540
2541
|
delete events[type];
|
2541
2542
|
}
|
2542
2543
|
} else {
|
2543
2544
|
forEach(type.split(' '), function(type) {
|
2544
|
-
if (
|
2545
|
-
|
2546
|
-
|
2547
|
-
|
2548
|
-
|
2545
|
+
if (isDefined(fn)) {
|
2546
|
+
var listenerFns = events[type];
|
2547
|
+
arrayRemove(listenerFns || [], fn);
|
2548
|
+
if (listenerFns && listenerFns.length > 0) {
|
2549
|
+
return;
|
2550
|
+
}
|
2549
2551
|
}
|
2552
|
+
|
2553
|
+
removeEventListenerFn(element, type, handle);
|
2554
|
+
delete events[type];
|
2550
2555
|
});
|
2551
2556
|
}
|
2552
2557
|
}
|
@@ -2710,6 +2715,20 @@ function jqLiteRemove(element, keepData) {
|
|
2710
2715
|
if (parent) parent.removeChild(element);
|
2711
2716
|
}
|
2712
2717
|
|
2718
|
+
|
2719
|
+
function jqLiteDocumentLoaded(action, win) {
|
2720
|
+
win = win || window;
|
2721
|
+
if (win.document.readyState === 'complete') {
|
2722
|
+
// Force the action to be run async for consistent behaviour
|
2723
|
+
// from the action's point of view
|
2724
|
+
// i.e. it will definitely not be in a $apply
|
2725
|
+
win.setTimeout(action);
|
2726
|
+
} else {
|
2727
|
+
// No need to unbind this handler as load is only ever called once
|
2728
|
+
jqLite(win).on('load', action);
|
2729
|
+
}
|
2730
|
+
}
|
2731
|
+
|
2713
2732
|
//////////////////////////////////////////
|
2714
2733
|
// Functions which are declared directly.
|
2715
2734
|
//////////////////////////////////////////
|
@@ -3332,7 +3351,7 @@ HashMap.prototype = {
|
|
3332
3351
|
|
3333
3352
|
* @param {Array.<string|Function>} modules A list of module functions or their aliases. See
|
3334
3353
|
* {@link angular.module}. The `ng` module must be explicitly added.
|
3335
|
-
* @returns {
|
3354
|
+
* @returns {injector} Injector object. See {@link auto.$injector $injector}.
|
3336
3355
|
*
|
3337
3356
|
* @example
|
3338
3357
|
* Typical usage
|
@@ -3983,7 +4002,7 @@ function createInjector(modulesToLoad, strictDi) {
|
|
3983
4002
|
|
3984
4003
|
function enforceReturnValue(name, factory) {
|
3985
4004
|
return function enforcedReturnValue() {
|
3986
|
-
var result = instanceInjector.invoke(factory);
|
4005
|
+
var result = instanceInjector.invoke(factory, this, undefined, name);
|
3987
4006
|
if (isUndefined(result)) {
|
3988
4007
|
throw $injectorMinErr('undef', "Provider '{0}' must return a value from $get factory method.", name);
|
3989
4008
|
}
|
@@ -4161,93 +4180,252 @@ function createInjector(modulesToLoad, strictDi) {
|
|
4161
4180
|
createInjector.$$annotate = annotate;
|
4162
4181
|
|
4163
4182
|
/**
|
4164
|
-
* @ngdoc
|
4165
|
-
* @name $
|
4166
|
-
* @kind function
|
4167
|
-
* @requires $window
|
4168
|
-
* @requires $location
|
4169
|
-
* @requires $rootScope
|
4183
|
+
* @ngdoc provider
|
4184
|
+
* @name $anchorScrollProvider
|
4170
4185
|
*
|
4171
4186
|
* @description
|
4172
|
-
*
|
4173
|
-
*
|
4174
|
-
* [Html5 spec](http://dev.w3.org/html5/spec/Overview.html#the-indicated-part-of-the-document).
|
4175
|
-
*
|
4176
|
-
* It also watches the `$location.hash()` and scrolls whenever it changes to match any anchor.
|
4177
|
-
* This can be disabled by calling `$anchorScrollProvider.disableAutoScrolling()`.
|
4178
|
-
*
|
4179
|
-
* @example
|
4180
|
-
<example module="anchorScrollExample">
|
4181
|
-
<file name="index.html">
|
4182
|
-
<div id="scrollArea" ng-controller="ScrollController">
|
4183
|
-
<a ng-click="gotoBottom()">Go to bottom</a>
|
4184
|
-
<a id="bottom"></a> You're at the bottom!
|
4185
|
-
</div>
|
4186
|
-
</file>
|
4187
|
-
<file name="script.js">
|
4188
|
-
angular.module('anchorScrollExample', [])
|
4189
|
-
.controller('ScrollController', ['$scope', '$location', '$anchorScroll',
|
4190
|
-
function ($scope, $location, $anchorScroll) {
|
4191
|
-
$scope.gotoBottom = function() {
|
4192
|
-
// set the location.hash to the id of
|
4193
|
-
// the element you wish to scroll to.
|
4194
|
-
$location.hash('bottom');
|
4195
|
-
|
4196
|
-
// call $anchorScroll()
|
4197
|
-
$anchorScroll();
|
4198
|
-
};
|
4199
|
-
}]);
|
4200
|
-
</file>
|
4201
|
-
<file name="style.css">
|
4202
|
-
#scrollArea {
|
4203
|
-
height: 350px;
|
4204
|
-
overflow: auto;
|
4205
|
-
}
|
4206
|
-
|
4207
|
-
#bottom {
|
4208
|
-
display: block;
|
4209
|
-
margin-top: 2000px;
|
4210
|
-
}
|
4211
|
-
</file>
|
4212
|
-
</example>
|
4187
|
+
* Use `$anchorScrollProvider` to disable automatic scrolling whenever
|
4188
|
+
* {@link ng.$location#hash $location.hash()} changes.
|
4213
4189
|
*/
|
4214
4190
|
function $AnchorScrollProvider() {
|
4215
4191
|
|
4216
4192
|
var autoScrollingEnabled = true;
|
4217
4193
|
|
4194
|
+
/**
|
4195
|
+
* @ngdoc method
|
4196
|
+
* @name $anchorScrollProvider#disableAutoScrolling
|
4197
|
+
*
|
4198
|
+
* @description
|
4199
|
+
* By default, {@link ng.$anchorScroll $anchorScroll()} will automatically will detect changes to
|
4200
|
+
* {@link ng.$location#hash $location.hash()} and scroll to the element matching the new hash.<br />
|
4201
|
+
* Use this method to disable automatic scrolling.
|
4202
|
+
*
|
4203
|
+
* If automatic scrolling is disabled, one must explicitly call
|
4204
|
+
* {@link ng.$anchorScroll $anchorScroll()} in order to scroll to the element related to the
|
4205
|
+
* current hash.
|
4206
|
+
*/
|
4218
4207
|
this.disableAutoScrolling = function() {
|
4219
4208
|
autoScrollingEnabled = false;
|
4220
4209
|
};
|
4221
4210
|
|
4211
|
+
/**
|
4212
|
+
* @ngdoc service
|
4213
|
+
* @name $anchorScroll
|
4214
|
+
* @kind function
|
4215
|
+
* @requires $window
|
4216
|
+
* @requires $location
|
4217
|
+
* @requires $rootScope
|
4218
|
+
*
|
4219
|
+
* @description
|
4220
|
+
* When called, it checks the current value of {@link ng.$location#hash $location.hash()} and
|
4221
|
+
* scrolls to the related element, according to the rules specified in the
|
4222
|
+
* [Html5 spec](http://dev.w3.org/html5/spec/Overview.html#the-indicated-part-of-the-document).
|
4223
|
+
*
|
4224
|
+
* It also watches the {@link ng.$location#hash $location.hash()} and automatically scrolls to
|
4225
|
+
* match any anchor whenever it changes. This can be disabled by calling
|
4226
|
+
* {@link ng.$anchorScrollProvider#disableAutoScrolling $anchorScrollProvider.disableAutoScrolling()}.
|
4227
|
+
*
|
4228
|
+
* Additionally, you can use its {@link ng.$anchorScroll#yOffset yOffset} property to specify a
|
4229
|
+
* vertical scroll-offset (either fixed or dynamic).
|
4230
|
+
*
|
4231
|
+
* @property {(number|function|jqLite)} yOffset
|
4232
|
+
* If set, specifies a vertical scroll-offset. This is often useful when there are fixed
|
4233
|
+
* positioned elements at the top of the page, such as navbars, headers etc.
|
4234
|
+
*
|
4235
|
+
* `yOffset` can be specified in various ways:
|
4236
|
+
* - **number**: A fixed number of pixels to be used as offset.<br /><br />
|
4237
|
+
* - **function**: A getter function called everytime `$anchorScroll()` is executed. Must return
|
4238
|
+
* a number representing the offset (in pixels).<br /><br />
|
4239
|
+
* - **jqLite**: A jqLite/jQuery element to be used for specifying the offset. The distance from
|
4240
|
+
* the top of the page to the element's bottom will be used as offset.<br />
|
4241
|
+
* **Note**: The element will be taken into account only as long as its `position` is set to
|
4242
|
+
* `fixed`. This option is useful, when dealing with responsive navbars/headers that adjust
|
4243
|
+
* their height and/or positioning according to the viewport's size.
|
4244
|
+
*
|
4245
|
+
* <br />
|
4246
|
+
* <div class="alert alert-warning">
|
4247
|
+
* In order for `yOffset` to work properly, scrolling should take place on the document's root and
|
4248
|
+
* not some child element.
|
4249
|
+
* </div>
|
4250
|
+
*
|
4251
|
+
* @example
|
4252
|
+
<example module="anchorScrollExample">
|
4253
|
+
<file name="index.html">
|
4254
|
+
<div id="scrollArea" ng-controller="ScrollController">
|
4255
|
+
<a ng-click="gotoBottom()">Go to bottom</a>
|
4256
|
+
<a id="bottom"></a> You're at the bottom!
|
4257
|
+
</div>
|
4258
|
+
</file>
|
4259
|
+
<file name="script.js">
|
4260
|
+
angular.module('anchorScrollExample', [])
|
4261
|
+
.controller('ScrollController', ['$scope', '$location', '$anchorScroll',
|
4262
|
+
function ($scope, $location, $anchorScroll) {
|
4263
|
+
$scope.gotoBottom = function() {
|
4264
|
+
// set the location.hash to the id of
|
4265
|
+
// the element you wish to scroll to.
|
4266
|
+
$location.hash('bottom');
|
4267
|
+
|
4268
|
+
// call $anchorScroll()
|
4269
|
+
$anchorScroll();
|
4270
|
+
};
|
4271
|
+
}]);
|
4272
|
+
</file>
|
4273
|
+
<file name="style.css">
|
4274
|
+
#scrollArea {
|
4275
|
+
height: 280px;
|
4276
|
+
overflow: auto;
|
4277
|
+
}
|
4278
|
+
|
4279
|
+
#bottom {
|
4280
|
+
display: block;
|
4281
|
+
margin-top: 2000px;
|
4282
|
+
}
|
4283
|
+
</file>
|
4284
|
+
</example>
|
4285
|
+
*
|
4286
|
+
* <hr />
|
4287
|
+
* The example below illustrates the use of a vertical scroll-offset (specified as a fixed value).
|
4288
|
+
* See {@link ng.$anchorScroll#yOffset $anchorScroll.yOffset} for more details.
|
4289
|
+
*
|
4290
|
+
* @example
|
4291
|
+
<example module="anchorScrollOffsetExample">
|
4292
|
+
<file name="index.html">
|
4293
|
+
<div class="fixed-header" ng-controller="headerCtrl">
|
4294
|
+
<a href="" ng-click="gotoAnchor(x)" ng-repeat="x in [1,2,3,4,5]">
|
4295
|
+
Go to anchor {{x}}
|
4296
|
+
</a>
|
4297
|
+
</div>
|
4298
|
+
<div id="anchor{{x}}" class="anchor" ng-repeat="x in [1,2,3,4,5]">
|
4299
|
+
Anchor {{x}} of 5
|
4300
|
+
</div>
|
4301
|
+
</file>
|
4302
|
+
<file name="script.js">
|
4303
|
+
angular.module('anchorScrollOffsetExample', [])
|
4304
|
+
.run(['$anchorScroll', function($anchorScroll) {
|
4305
|
+
$anchorScroll.yOffset = 50; // always scroll by 50 extra pixels
|
4306
|
+
}])
|
4307
|
+
.controller('headerCtrl', ['$anchorScroll', '$location', '$scope',
|
4308
|
+
function ($anchorScroll, $location, $scope) {
|
4309
|
+
$scope.gotoAnchor = function(x) {
|
4310
|
+
var newHash = 'anchor' + x;
|
4311
|
+
if ($location.hash() !== newHash) {
|
4312
|
+
// set the $location.hash to `newHash` and
|
4313
|
+
// $anchorScroll will automatically scroll to it
|
4314
|
+
$location.hash('anchor' + x);
|
4315
|
+
} else {
|
4316
|
+
// call $anchorScroll() explicitly,
|
4317
|
+
// since $location.hash hasn't changed
|
4318
|
+
$anchorScroll();
|
4319
|
+
}
|
4320
|
+
};
|
4321
|
+
}
|
4322
|
+
]);
|
4323
|
+
</file>
|
4324
|
+
<file name="style.css">
|
4325
|
+
body {
|
4326
|
+
padding-top: 50px;
|
4327
|
+
}
|
4328
|
+
|
4329
|
+
.anchor {
|
4330
|
+
border: 2px dashed DarkOrchid;
|
4331
|
+
padding: 10px 10px 200px 10px;
|
4332
|
+
}
|
4333
|
+
|
4334
|
+
.fixed-header {
|
4335
|
+
background-color: rgba(0, 0, 0, 0.2);
|
4336
|
+
height: 50px;
|
4337
|
+
position: fixed;
|
4338
|
+
top: 0; left: 0; right: 0;
|
4339
|
+
}
|
4340
|
+
|
4341
|
+
.fixed-header > a {
|
4342
|
+
display: inline-block;
|
4343
|
+
margin: 5px 15px;
|
4344
|
+
}
|
4345
|
+
</file>
|
4346
|
+
</example>
|
4347
|
+
*/
|
4222
4348
|
this.$get = ['$window', '$location', '$rootScope', function($window, $location, $rootScope) {
|
4223
4349
|
var document = $window.document;
|
4350
|
+
var scrollScheduled = false;
|
4224
4351
|
|
4225
|
-
//
|
4226
|
-
//
|
4227
|
-
//
|
4228
|
-
// TODO(vojta): use filter if we change it to accept lists as well
|
4352
|
+
// Helper function to get first anchor from a NodeList
|
4353
|
+
// (using `Array#some()` instead of `angular#forEach()` since it's more performant
|
4354
|
+
// and working in all supported browsers.)
|
4229
4355
|
function getFirstAnchor(list) {
|
4230
4356
|
var result = null;
|
4231
|
-
|
4232
|
-
if (
|
4357
|
+
Array.prototype.some.call(list, function(element) {
|
4358
|
+
if (nodeName_(element) === 'a') {
|
4359
|
+
result = element;
|
4360
|
+
return true;
|
4361
|
+
}
|
4233
4362
|
});
|
4234
4363
|
return result;
|
4235
4364
|
}
|
4236
4365
|
|
4366
|
+
function getYOffset() {
|
4367
|
+
|
4368
|
+
var offset = scroll.yOffset;
|
4369
|
+
|
4370
|
+
if (isFunction(offset)) {
|
4371
|
+
offset = offset();
|
4372
|
+
} else if (isElement(offset)) {
|
4373
|
+
var elem = offset[0];
|
4374
|
+
var style = $window.getComputedStyle(elem);
|
4375
|
+
if (style.position !== 'fixed') {
|
4376
|
+
offset = 0;
|
4377
|
+
} else {
|
4378
|
+
offset = elem.getBoundingClientRect().bottom;
|
4379
|
+
}
|
4380
|
+
} else if (!isNumber(offset)) {
|
4381
|
+
offset = 0;
|
4382
|
+
}
|
4383
|
+
|
4384
|
+
return offset;
|
4385
|
+
}
|
4386
|
+
|
4387
|
+
function scrollTo(elem) {
|
4388
|
+
if (elem) {
|
4389
|
+
elem.scrollIntoView();
|
4390
|
+
|
4391
|
+
var offset = getYOffset();
|
4392
|
+
|
4393
|
+
if (offset) {
|
4394
|
+
// `offset` is the number of pixels we should scroll UP in order to align `elem` properly.
|
4395
|
+
// This is true ONLY if the call to `elem.scrollIntoView()` initially aligns `elem` at the
|
4396
|
+
// top of the viewport.
|
4397
|
+
//
|
4398
|
+
// IF the number of pixels from the top of `elem` to the end of the page's content is less
|
4399
|
+
// than the height of the viewport, then `elem.scrollIntoView()` will align the `elem` some
|
4400
|
+
// way down the page.
|
4401
|
+
//
|
4402
|
+
// This is often the case for elements near the bottom of the page.
|
4403
|
+
//
|
4404
|
+
// In such cases we do not need to scroll the whole `offset` up, just the difference between
|
4405
|
+
// the top of the element and the offset, which is enough to align the top of `elem` at the
|
4406
|
+
// desired position.
|
4407
|
+
var elemTop = elem.getBoundingClientRect().top;
|
4408
|
+
$window.scrollBy(0, elemTop - offset);
|
4409
|
+
}
|
4410
|
+
} else {
|
4411
|
+
$window.scrollTo(0, 0);
|
4412
|
+
}
|
4413
|
+
}
|
4414
|
+
|
4237
4415
|
function scroll() {
|
4238
4416
|
var hash = $location.hash(), elm;
|
4239
4417
|
|
4240
4418
|
// empty hash, scroll to the top of the page
|
4241
|
-
if (!hash)
|
4419
|
+
if (!hash) scrollTo(null);
|
4242
4420
|
|
4243
4421
|
// element with given id
|
4244
|
-
else if ((elm = document.getElementById(hash))) elm
|
4422
|
+
else if ((elm = document.getElementById(hash))) scrollTo(elm);
|
4245
4423
|
|
4246
4424
|
// first anchor with given name :-D
|
4247
|
-
else if ((elm = getFirstAnchor(document.getElementsByName(hash)))) elm
|
4425
|
+
else if ((elm = getFirstAnchor(document.getElementsByName(hash)))) scrollTo(elm);
|
4248
4426
|
|
4249
4427
|
// no element and hash == 'top', scroll to the top of the page
|
4250
|
-
else if (hash === 'top')
|
4428
|
+
else if (hash === 'top') scrollTo(null);
|
4251
4429
|
}
|
4252
4430
|
|
4253
4431
|
// does not scroll when user clicks on anchor link that is currently on
|
@@ -4258,7 +4436,9 @@ function $AnchorScrollProvider() {
|
|
4258
4436
|
// skip the initial scroll if $location.hash is empty
|
4259
4437
|
if (newVal === oldVal && newVal === '') return;
|
4260
4438
|
|
4261
|
-
|
4439
|
+
jqLiteDocumentLoaded(function() {
|
4440
|
+
$rootScope.$evalAsync(scroll);
|
4441
|
+
});
|
4262
4442
|
});
|
4263
4443
|
}
|
4264
4444
|
|
@@ -4366,7 +4546,7 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4366
4546
|
return defer.promise;
|
4367
4547
|
}
|
4368
4548
|
|
4369
|
-
function resolveElementClasses(element,
|
4549
|
+
function resolveElementClasses(element, classes) {
|
4370
4550
|
var toAdd = [], toRemove = [];
|
4371
4551
|
|
4372
4552
|
var hasClasses = createMap();
|
@@ -4374,7 +4554,7 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4374
4554
|
hasClasses[className] = true;
|
4375
4555
|
});
|
4376
4556
|
|
4377
|
-
forEach(
|
4557
|
+
forEach(classes, function(status, className) {
|
4378
4558
|
var hasClass = hasClasses[className];
|
4379
4559
|
|
4380
4560
|
// If the most recent class manipulation (via $animate) was to remove the class, and the
|
@@ -4388,7 +4568,8 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4388
4568
|
}
|
4389
4569
|
});
|
4390
4570
|
|
4391
|
-
return (toAdd.length + toRemove.length) > 0 &&
|
4571
|
+
return (toAdd.length + toRemove.length) > 0 &&
|
4572
|
+
[toAdd.length ? toAdd : null, toRemove.length ? toRemove : null];
|
4392
4573
|
}
|
4393
4574
|
|
4394
4575
|
function cachedClassManipulation(cache, classes, op) {
|
@@ -4410,6 +4591,13 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4410
4591
|
return currentDefer.promise;
|
4411
4592
|
}
|
4412
4593
|
|
4594
|
+
function applyStyles(element, options) {
|
4595
|
+
if (angular.isObject(options)) {
|
4596
|
+
var styles = extend(options.from || {}, options.to || {});
|
4597
|
+
element.css(styles);
|
4598
|
+
}
|
4599
|
+
}
|
4600
|
+
|
4413
4601
|
/**
|
4414
4602
|
*
|
4415
4603
|
* @ngdoc service
|
@@ -4428,6 +4616,10 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4428
4616
|
* page}.
|
4429
4617
|
*/
|
4430
4618
|
return {
|
4619
|
+
animate : function(element, from, to) {
|
4620
|
+
applyStyles(element, { from: from, to: to });
|
4621
|
+
return asyncPromise();
|
4622
|
+
},
|
4431
4623
|
|
4432
4624
|
/**
|
4433
4625
|
*
|
@@ -4442,9 +4634,11 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4442
4634
|
* a child (if the after element is not present)
|
4443
4635
|
* @param {DOMElement} after the sibling element which will append the element
|
4444
4636
|
* after itself
|
4637
|
+
* @param {object=} options an optional collection of styles that will be applied to the element.
|
4445
4638
|
* @return {Promise} the animation callback promise
|
4446
4639
|
*/
|
4447
|
-
enter : function(element, parent, after) {
|
4640
|
+
enter : function(element, parent, after, options) {
|
4641
|
+
applyStyles(element, options);
|
4448
4642
|
after ? after.after(element)
|
4449
4643
|
: parent.prepend(element);
|
4450
4644
|
return asyncPromise();
|
@@ -4458,9 +4652,10 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4458
4652
|
* @description Removes the element from the DOM. When the function is called a promise
|
4459
4653
|
* is returned that will be resolved at a later time.
|
4460
4654
|
* @param {DOMElement} element the element which will be removed from the DOM
|
4655
|
+
* @param {object=} options an optional collection of options that will be applied to the element.
|
4461
4656
|
* @return {Promise} the animation callback promise
|
4462
4657
|
*/
|
4463
|
-
leave : function(element) {
|
4658
|
+
leave : function(element, options) {
|
4464
4659
|
element.remove();
|
4465
4660
|
return asyncPromise();
|
4466
4661
|
},
|
@@ -4480,12 +4675,13 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4480
4675
|
* inserted into (if the after element is not present)
|
4481
4676
|
* @param {DOMElement} after the sibling element where the element will be
|
4482
4677
|
* positioned next to
|
4678
|
+
* @param {object=} options an optional collection of options that will be applied to the element.
|
4483
4679
|
* @return {Promise} the animation callback promise
|
4484
4680
|
*/
|
4485
|
-
move : function(element, parent, after) {
|
4681
|
+
move : function(element, parent, after, options) {
|
4486
4682
|
// Do not remove element before insert. Removing will cause data associated with the
|
4487
4683
|
// element to be dropped. Insert will implicitly do the remove.
|
4488
|
-
return this.enter(element, parent, after);
|
4684
|
+
return this.enter(element, parent, after, options);
|
4489
4685
|
},
|
4490
4686
|
|
4491
4687
|
/**
|
@@ -4498,13 +4694,14 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4498
4694
|
* @param {DOMElement} element the element which will have the className value
|
4499
4695
|
* added to it
|
4500
4696
|
* @param {string} className the CSS class which will be added to the element
|
4697
|
+
* @param {object=} options an optional collection of options that will be applied to the element.
|
4501
4698
|
* @return {Promise} the animation callback promise
|
4502
4699
|
*/
|
4503
|
-
addClass : function(element, className) {
|
4504
|
-
return this.setClass(element, className, []);
|
4700
|
+
addClass : function(element, className, options) {
|
4701
|
+
return this.setClass(element, className, [], options);
|
4505
4702
|
},
|
4506
4703
|
|
4507
|
-
$$addClassImmediately : function
|
4704
|
+
$$addClassImmediately : function(element, className, options) {
|
4508
4705
|
element = jqLite(element);
|
4509
4706
|
className = !isString(className)
|
4510
4707
|
? (isArray(className) ? className.join(' ') : '')
|
@@ -4512,6 +4709,8 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4512
4709
|
forEach(element, function (element) {
|
4513
4710
|
jqLiteAddClass(element, className);
|
4514
4711
|
});
|
4712
|
+
applyStyles(element, options);
|
4713
|
+
return asyncPromise();
|
4515
4714
|
},
|
4516
4715
|
|
4517
4716
|
/**
|
@@ -4524,13 +4723,14 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4524
4723
|
* @param {DOMElement} element the element which will have the className value
|
4525
4724
|
* removed from it
|
4526
4725
|
* @param {string} className the CSS class which will be removed from the element
|
4726
|
+
* @param {object=} options an optional collection of options that will be applied to the element.
|
4527
4727
|
* @return {Promise} the animation callback promise
|
4528
4728
|
*/
|
4529
|
-
removeClass : function(element, className) {
|
4530
|
-
return this.setClass(element, [], className);
|
4729
|
+
removeClass : function(element, className, options) {
|
4730
|
+
return this.setClass(element, [], className, options);
|
4531
4731
|
},
|
4532
4732
|
|
4533
|
-
$$removeClassImmediately : function
|
4733
|
+
$$removeClassImmediately : function(element, className, options) {
|
4534
4734
|
element = jqLite(element);
|
4535
4735
|
className = !isString(className)
|
4536
4736
|
? (isArray(className) ? className.join(' ') : '')
|
@@ -4538,6 +4738,7 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4538
4738
|
forEach(element, function (element) {
|
4539
4739
|
jqLiteRemoveClass(element, className);
|
4540
4740
|
});
|
4741
|
+
applyStyles(element, options);
|
4541
4742
|
return asyncPromise();
|
4542
4743
|
},
|
4543
4744
|
|
@@ -4552,28 +4753,24 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4552
4753
|
* removed from it
|
4553
4754
|
* @param {string} add the CSS classes which will be added to the element
|
4554
4755
|
* @param {string} remove the CSS class which will be removed from the element
|
4756
|
+
* @param {object=} options an optional collection of options that will be applied to the element.
|
4555
4757
|
* @return {Promise} the animation callback promise
|
4556
4758
|
*/
|
4557
|
-
setClass : function(element, add, remove,
|
4759
|
+
setClass : function(element, add, remove, options) {
|
4558
4760
|
var self = this;
|
4559
4761
|
var STORAGE_KEY = '$$animateClasses';
|
4560
4762
|
var createdCache = false;
|
4561
4763
|
element = jqLite(element);
|
4562
4764
|
|
4563
|
-
if (runSynchronously) {
|
4564
|
-
// TODO(@caitp/@matsko): Remove undocumented `runSynchronously` parameter, and always
|
4565
|
-
// perform DOM manipulation asynchronously or in postDigest.
|
4566
|
-
self.$$addClassImmediately(element, add);
|
4567
|
-
self.$$removeClassImmediately(element, remove);
|
4568
|
-
return asyncPromise();
|
4569
|
-
}
|
4570
|
-
|
4571
4765
|
var cache = element.data(STORAGE_KEY);
|
4572
4766
|
if (!cache) {
|
4573
4767
|
cache = {
|
4574
|
-
classes: {}
|
4768
|
+
classes: {},
|
4769
|
+
options : options
|
4575
4770
|
};
|
4576
4771
|
createdCache = true;
|
4772
|
+
} else if (options && cache.options) {
|
4773
|
+
cache.options = angular.extend(cache.options || {}, options);
|
4577
4774
|
}
|
4578
4775
|
|
4579
4776
|
var classes = cache.classes;
|
@@ -4588,11 +4785,14 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4588
4785
|
var cache = element.data(STORAGE_KEY);
|
4589
4786
|
element.removeData(STORAGE_KEY);
|
4590
4787
|
|
4591
|
-
|
4592
|
-
|
4593
|
-
|
4594
|
-
|
4595
|
-
|
4788
|
+
// in the event that the element is removed before postDigest
|
4789
|
+
// is run then the cache will be undefined and there will be
|
4790
|
+
// no need anymore to add or remove and of the element classes
|
4791
|
+
if (cache) {
|
4792
|
+
var classes = resolveElementClasses(element, cache.classes);
|
4793
|
+
if (classes) {
|
4794
|
+
self.$$setClassImmediately(element, classes[0], classes[1], cache.options);
|
4795
|
+
}
|
4596
4796
|
}
|
4597
4797
|
|
4598
4798
|
done();
|
@@ -4603,6 +4803,13 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4603
4803
|
return cache.promise;
|
4604
4804
|
},
|
4605
4805
|
|
4806
|
+
$$setClassImmediately : function(element, add, remove, options) {
|
4807
|
+
add && this.$$addClassImmediately(element, add);
|
4808
|
+
remove && this.$$removeClassImmediately(element, remove);
|
4809
|
+
applyStyles(element, options);
|
4810
|
+
return asyncPromise();
|
4811
|
+
},
|
4812
|
+
|
4606
4813
|
enabled : noop,
|
4607
4814
|
cancel : noop
|
4608
4815
|
};
|
@@ -4743,11 +4950,14 @@ function Browser(window, document, $log, $sniffer) {
|
|
4743
4950
|
// URL API
|
4744
4951
|
//////////////////////////////////////////////////////////////
|
4745
4952
|
|
4746
|
-
var
|
4747
|
-
|
4953
|
+
var cachedState, lastHistoryState,
|
4954
|
+
lastBrowserUrl = location.href,
|
4748
4955
|
baseElement = document.find('base'),
|
4749
4956
|
reloadLocation = null;
|
4750
4957
|
|
4958
|
+
cacheState();
|
4959
|
+
lastHistoryState = cachedState;
|
4960
|
+
|
4751
4961
|
/**
|
4752
4962
|
* @name $browser#url
|
4753
4963
|
*
|
@@ -4782,21 +4992,26 @@ function Browser(window, document, $log, $sniffer) {
|
|
4782
4992
|
|
4783
4993
|
// setter
|
4784
4994
|
if (url) {
|
4995
|
+
var sameState = lastHistoryState === state;
|
4996
|
+
|
4785
4997
|
// Don't change anything if previous and current URLs and states match. This also prevents
|
4786
4998
|
// IE<10 from getting into redirect loop when in LocationHashbangInHtml5Url mode.
|
4787
4999
|
// See https://github.com/angular/angular.js/commit/ffb2701
|
4788
|
-
if (lastBrowserUrl === url && (!$sniffer.history ||
|
5000
|
+
if (lastBrowserUrl === url && (!$sniffer.history || sameState)) {
|
4789
5001
|
return;
|
4790
5002
|
}
|
4791
5003
|
var sameBase = lastBrowserUrl && stripHash(lastBrowserUrl) === stripHash(url);
|
4792
5004
|
lastBrowserUrl = url;
|
5005
|
+
lastHistoryState = state;
|
4793
5006
|
// Don't use history API if only the hash changed
|
4794
5007
|
// due to a bug in IE10/IE11 which leads
|
4795
5008
|
// to not firing a `hashchange` nor `popstate` event
|
4796
5009
|
// in some cases (see #9143).
|
4797
|
-
if ($sniffer.history && (!sameBase ||
|
5010
|
+
if ($sniffer.history && (!sameBase || !sameState)) {
|
4798
5011
|
history[replace ? 'replaceState' : 'pushState'](state, '', url);
|
4799
|
-
|
5012
|
+
cacheState();
|
5013
|
+
// Do the assignment again so that those two variables are referentially identical.
|
5014
|
+
lastHistoryState = cachedState;
|
4800
5015
|
} else {
|
4801
5016
|
if (!sameBase) {
|
4802
5017
|
reloadLocation = url;
|
@@ -4828,20 +5043,40 @@ function Browser(window, document, $log, $sniffer) {
|
|
4828
5043
|
* @returns {object} state
|
4829
5044
|
*/
|
4830
5045
|
self.state = function() {
|
4831
|
-
return
|
5046
|
+
return cachedState;
|
4832
5047
|
};
|
4833
5048
|
|
4834
5049
|
var urlChangeListeners = [],
|
4835
5050
|
urlChangeInit = false;
|
4836
5051
|
|
5052
|
+
function cacheStateAndFireUrlChange() {
|
5053
|
+
cacheState();
|
5054
|
+
fireUrlChange();
|
5055
|
+
}
|
5056
|
+
|
5057
|
+
// This variable should be used *only* inside the cacheState function.
|
5058
|
+
var lastCachedState = null;
|
5059
|
+
function cacheState() {
|
5060
|
+
// This should be the only place in $browser where `history.state` is read.
|
5061
|
+
cachedState = window.history.state;
|
5062
|
+
cachedState = isUndefined(cachedState) ? null : cachedState;
|
5063
|
+
|
5064
|
+
// Prevent callbacks fo fire twice if both hashchange & popstate were fired.
|
5065
|
+
if (equals(cachedState, lastCachedState)) {
|
5066
|
+
cachedState = lastCachedState;
|
5067
|
+
}
|
5068
|
+
lastCachedState = cachedState;
|
5069
|
+
}
|
5070
|
+
|
4837
5071
|
function fireUrlChange() {
|
4838
|
-
if (lastBrowserUrl === self.url() && lastHistoryState ===
|
5072
|
+
if (lastBrowserUrl === self.url() && lastHistoryState === cachedState) {
|
4839
5073
|
return;
|
4840
5074
|
}
|
4841
5075
|
|
4842
5076
|
lastBrowserUrl = self.url();
|
5077
|
+
lastHistoryState = cachedState;
|
4843
5078
|
forEach(urlChangeListeners, function(listener) {
|
4844
|
-
listener(self.url(),
|
5079
|
+
listener(self.url(), cachedState);
|
4845
5080
|
});
|
4846
5081
|
}
|
4847
5082
|
|
@@ -4874,9 +5109,9 @@ function Browser(window, document, $log, $sniffer) {
|
|
4874
5109
|
// changed by push/replaceState
|
4875
5110
|
|
4876
5111
|
// html5 history api - popstate event
|
4877
|
-
if ($sniffer.history) jqLite(window).on('popstate',
|
5112
|
+
if ($sniffer.history) jqLite(window).on('popstate', cacheStateAndFireUrlChange);
|
4878
5113
|
// hashchange event
|
4879
|
-
jqLite(window).on('hashchange',
|
5114
|
+
jqLite(window).on('hashchange', cacheStateAndFireUrlChange);
|
4880
5115
|
|
4881
5116
|
urlChangeInit = true;
|
4882
5117
|
}
|
@@ -4917,6 +5152,14 @@ function Browser(window, document, $log, $sniffer) {
|
|
4917
5152
|
var lastCookieString = '';
|
4918
5153
|
var cookiePath = self.baseHref();
|
4919
5154
|
|
5155
|
+
function safeDecodeURIComponent(str) {
|
5156
|
+
try {
|
5157
|
+
return decodeURIComponent(str);
|
5158
|
+
} catch (e) {
|
5159
|
+
return str;
|
5160
|
+
}
|
5161
|
+
}
|
5162
|
+
|
4920
5163
|
/**
|
4921
5164
|
* @name $browser#cookies
|
4922
5165
|
*
|
@@ -4970,12 +5213,12 @@ function Browser(window, document, $log, $sniffer) {
|
|
4970
5213
|
cookie = cookieArray[i];
|
4971
5214
|
index = cookie.indexOf('=');
|
4972
5215
|
if (index > 0) { //ignore nameless cookies
|
4973
|
-
name =
|
5216
|
+
name = safeDecodeURIComponent(cookie.substring(0, index));
|
4974
5217
|
// the first value that is seen for a cookie is the most
|
4975
5218
|
// specific one. values for the same cookie name that
|
4976
5219
|
// follow are for less specific paths.
|
4977
5220
|
if (lastCookies[name] === undefined) {
|
4978
|
-
lastCookies[name] =
|
5221
|
+
lastCookies[name] = safeDecodeURIComponent(cookie.substring(index + 1));
|
4979
5222
|
}
|
4980
5223
|
}
|
4981
5224
|
}
|
@@ -5500,6 +5743,7 @@ function $TemplateCacheProvider() {
|
|
5500
5743
|
* // templateUrl: 'directive.html', // or // function(tElement, tAttrs) { ... },
|
5501
5744
|
* transclude: false,
|
5502
5745
|
* restrict: 'A',
|
5746
|
+
* templateNamespace: 'html',
|
5503
5747
|
* scope: false,
|
5504
5748
|
* controller: function($scope, $element, $attrs, $transclude, otherInjectables) { ... },
|
5505
5749
|
* controllerAs: 'stringAlias',
|
@@ -5554,8 +5798,8 @@ function $TemplateCacheProvider() {
|
|
5554
5798
|
* When this property is set to true, the HTML compiler will collect DOM nodes between
|
5555
5799
|
* nodes with the attributes `directive-name-start` and `directive-name-end`, and group them
|
5556
5800
|
* together as the directive elements. It is recomended that this feature be used on directives
|
5557
|
-
* which are not strictly behavioural (such as {@link
|
5558
|
-
* do not manipulate or replace child nodes (such as {@link
|
5801
|
+
* which are not strictly behavioural (such as {@link ngClick}), and which
|
5802
|
+
* do not manipulate or replace child nodes (such as {@link ngInclude}).
|
5559
5803
|
*
|
5560
5804
|
* #### `priority`
|
5561
5805
|
* When there are multiple directives defined on a single DOM element, sometimes it
|
@@ -5568,7 +5812,8 @@ function $TemplateCacheProvider() {
|
|
5568
5812
|
* #### `terminal`
|
5569
5813
|
* If set to true then the current `priority` will be the last set of directives
|
5570
5814
|
* which will execute (any directives at the current priority will still execute
|
5571
|
-
* as the order of execution on same `priority` is undefined).
|
5815
|
+
* as the order of execution on same `priority` is undefined). Note that expressions
|
5816
|
+
* and other directives used in the directive's template will also be excluded from execution.
|
5572
5817
|
*
|
5573
5818
|
* #### `scope`
|
5574
5819
|
* **If set to `true`,** then a new scope will be created for this directive. If multiple directives on the
|
@@ -5715,7 +5960,7 @@ function $TemplateCacheProvider() {
|
|
5715
5960
|
* You can specify `templateUrl` as a string representing the URL or as a function which takes two
|
5716
5961
|
* arguments `tElement` and `tAttrs` (described in the `compile` function api below) and returns
|
5717
5962
|
* a string value representing the url. In either case, the template URL is passed through {@link
|
5718
|
-
*
|
5963
|
+
* $sce#getTrustedResourceUrl $sce.getTrustedResourceUrl}.
|
5719
5964
|
*
|
5720
5965
|
*
|
5721
5966
|
* #### `replace` ([*DEPRECATED*!], will be removed in next major release - i.e. v2.0)
|
@@ -5725,7 +5970,7 @@ function $TemplateCacheProvider() {
|
|
5725
5970
|
* * `false` - the template will replace the contents of the directive's element.
|
5726
5971
|
*
|
5727
5972
|
* The replacement process migrates all of the attributes / classes from the old element to the new
|
5728
|
-
* one. See the {@link guide/directive#
|
5973
|
+
* one. See the {@link guide/directive#template-expanding-directive
|
5729
5974
|
* Directives Guide} for an example.
|
5730
5975
|
*
|
5731
5976
|
* There are very few scenarios where element replacement is required for the application function,
|
@@ -5880,7 +6125,7 @@ function $TemplateCacheProvider() {
|
|
5880
6125
|
* then you must use this transclude function. When you call a transclude function it returns a a jqLite/JQuery
|
5881
6126
|
* object that contains the compiled DOM, which is linked to the correct transclusion scope.
|
5882
6127
|
*
|
5883
|
-
* When you call a transclusion function you can pass in a **clone attach function**. This function
|
6128
|
+
* When you call a transclusion function you can pass in a **clone attach function**. This function accepts
|
5884
6129
|
* two parameters, `function(clone, scope) { ... }`, where the `clone` is a fresh compiled copy of your transcluded
|
5885
6130
|
* content and the `scope` is the newly created transclusion scope, to which the clone is bound.
|
5886
6131
|
*
|
@@ -6500,12 +6745,12 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6500
6745
|
* @param {string} key Normalized key. (ie ngAttribute) .
|
6501
6746
|
* @param {function(interpolatedValue)} fn Function that will be called whenever
|
6502
6747
|
the interpolated value of the attribute changes.
|
6503
|
-
* See {@link
|
6748
|
+
* See the {@link guide/directive#text-and-attribute-bindings Directives} guide for more info.
|
6504
6749
|
* @returns {function()} Returns a deregistration function for this observer.
|
6505
6750
|
*/
|
6506
6751
|
$observe: function(key, fn) {
|
6507
6752
|
var attrs = this,
|
6508
|
-
$$observers = (attrs.$$observers || (attrs.$$observers =
|
6753
|
+
$$observers = (attrs.$$observers || (attrs.$$observers = createMap())),
|
6509
6754
|
listeners = ($$observers[key] || ($$observers[key] = []));
|
6510
6755
|
|
6511
6756
|
listeners.push(fn);
|
@@ -8181,6 +8426,14 @@ function $DocumentProvider(){
|
|
8181
8426
|
* This example will override the normal action of `$exceptionHandler`, to make angular
|
8182
8427
|
* exceptions fail hard when they happen, instead of just logging to the console.
|
8183
8428
|
*
|
8429
|
+
* <hr />
|
8430
|
+
* Note, that code executed in event-listeners (even those registered using jqLite's `on`/`bind`
|
8431
|
+
* methods) does not delegate exceptions to the {@link ng.$exceptionHandler $exceptionHandler}
|
8432
|
+
* (unless executed during a digest).
|
8433
|
+
*
|
8434
|
+
* If you wish, you can manually delegate exceptions, e.g.
|
8435
|
+
* `try { ... } catch(e) { $exceptionHandler(e); }`
|
8436
|
+
*
|
8184
8437
|
* @param {Error} exception Exception associated with the error.
|
8185
8438
|
* @param {string=} cause optional information about the context in which
|
8186
8439
|
* the error was thrown.
|
@@ -8348,7 +8601,7 @@ function $HttpProvider() {
|
|
8348
8601
|
* @description
|
8349
8602
|
*
|
8350
8603
|
* Configure $http service to combine processing of multiple http responses received at around
|
8351
|
-
* the same time via {@link ng.$rootScope
|
8604
|
+
* the same time via {@link ng.$rootScope.Scope#$applyAsync $rootScope.$applyAsync}. This can result in
|
8352
8605
|
* significant performance improvement for bigger applications that make many HTTP requests
|
8353
8606
|
* concurrently (common during application bootstrap).
|
8354
8607
|
*
|
@@ -8424,7 +8677,21 @@ function $HttpProvider() {
|
|
8424
8677
|
* with two $http specific methods: `success` and `error`.
|
8425
8678
|
*
|
8426
8679
|
* ```js
|
8427
|
-
*
|
8680
|
+
* // Simple GET request example :
|
8681
|
+
* $http.get('/someUrl').
|
8682
|
+
* success(function(data, status, headers, config) {
|
8683
|
+
* // this callback will be called asynchronously
|
8684
|
+
* // when the response is available
|
8685
|
+
* }).
|
8686
|
+
* error(function(data, status, headers, config) {
|
8687
|
+
* // called asynchronously if an error occurs
|
8688
|
+
* // or server returns response with an error status.
|
8689
|
+
* });
|
8690
|
+
* ```
|
8691
|
+
*
|
8692
|
+
* ```js
|
8693
|
+
* // Simple POST request example (passing data) :
|
8694
|
+
* $http.post('/someUrl', {msg:'hello word!'}).
|
8428
8695
|
* success(function(data, status, headers, config) {
|
8429
8696
|
* // this callback will be called asynchronously
|
8430
8697
|
* // when the response is available
|
@@ -8435,6 +8702,7 @@ function $HttpProvider() {
|
|
8435
8702
|
* });
|
8436
8703
|
* ```
|
8437
8704
|
*
|
8705
|
+
*
|
8438
8706
|
* Since the returned value of calling the $http function is a `promise`, you can also use
|
8439
8707
|
* the `then` method to register callbacks, and these callbacks will receive a single argument –
|
8440
8708
|
* an object representing the response. See the API signature and type info below for more
|
@@ -8587,7 +8855,7 @@ function $HttpProvider() {
|
|
8587
8855
|
*
|
8588
8856
|
* You can change the default cache to a new object (built with
|
8589
8857
|
* {@link ng.$cacheFactory `$cacheFactory`}) by updating the
|
8590
|
-
* {@link ng.$http#
|
8858
|
+
* {@link ng.$http#defaults `$http.defaults.cache`} property. All requests who set
|
8591
8859
|
* their `cache` property to `true` will now use this cache object.
|
8592
8860
|
*
|
8593
8861
|
* If you set the default cache to `false` then only requests that specify their own custom
|
@@ -8949,9 +9217,12 @@ function $HttpProvider() {
|
|
8949
9217
|
|
8950
9218
|
function transformResponse(response) {
|
8951
9219
|
// make a copy since the response must be cacheable
|
8952
|
-
var resp = extend({}, response
|
8953
|
-
|
8954
|
-
|
9220
|
+
var resp = extend({}, response);
|
9221
|
+
if (!response.data) {
|
9222
|
+
resp.data = response.data;
|
9223
|
+
} else {
|
9224
|
+
resp.data = transformData(response.data, response.headers, config.transformResponse);
|
9225
|
+
}
|
8955
9226
|
return (isSuccess(response.status))
|
8956
9227
|
? resp
|
8957
9228
|
: $q.reject(resp);
|
@@ -9694,16 +9965,13 @@ function $InterpolateProvider() {
|
|
9694
9965
|
return '';
|
9695
9966
|
}
|
9696
9967
|
switch (typeof value) {
|
9697
|
-
case 'string':
|
9968
|
+
case 'string':
|
9698
9969
|
break;
|
9699
|
-
|
9700
|
-
case 'number': {
|
9970
|
+
case 'number':
|
9701
9971
|
value = '' + value;
|
9702
9972
|
break;
|
9703
|
-
|
9704
|
-
default: {
|
9973
|
+
default:
|
9705
9974
|
value = toJson(value);
|
9706
|
-
}
|
9707
9975
|
}
|
9708
9976
|
|
9709
9977
|
return value;
|
@@ -10525,6 +10793,7 @@ var locationPrototype = {
|
|
10525
10793
|
search = search.toString();
|
10526
10794
|
this.$$search = parseKeyValue(search);
|
10527
10795
|
} else if (isObject(search)) {
|
10796
|
+
search = copy(search, {});
|
10528
10797
|
// remove object undefined or null properties
|
10529
10798
|
forEach(search, function(value, key) {
|
10530
10799
|
if (value == null) delete search[key];
|
@@ -10710,8 +10979,8 @@ function $LocationProvider(){
|
|
10710
10979
|
* whether or not a <base> tag is required to be present. If `enabled` and `requireBase` are
|
10711
10980
|
* true, and a base tag is not present, an error will be thrown when `$location` is injected.
|
10712
10981
|
* See the {@link guide/$location $location guide for more information}
|
10713
|
-
* - **rewriteLinks** - `{boolean}` - (default: `
|
10714
|
-
*
|
10982
|
+
* - **rewriteLinks** - `{boolean}` - (default: `true`) When html5Mode is enabled,
|
10983
|
+
* enables/disables url rewriting for relative links.
|
10715
10984
|
*
|
10716
10985
|
* @returns {Object} html5Mode object if used as getter or itself (chaining) if used as setter
|
10717
10986
|
*/
|
@@ -10722,7 +10991,7 @@ function $LocationProvider(){
|
|
10722
10991
|
} else if (isObject(mode)) {
|
10723
10992
|
|
10724
10993
|
if (isBoolean(mode.enabled)) {
|
10725
|
-
html5Mode.enabled =
|
10994
|
+
html5Mode.enabled = mode.enabled;
|
10726
10995
|
}
|
10727
10996
|
|
10728
10997
|
if (isBoolean(mode.requireBase)) {
|
@@ -10730,7 +10999,7 @@ function $LocationProvider(){
|
|
10730
10999
|
}
|
10731
11000
|
|
10732
11001
|
if (isBoolean(mode.rewriteLinks)) {
|
10733
|
-
html5Mode.rewriteLinks =
|
11002
|
+
html5Mode.rewriteLinks = mode.rewriteLinks;
|
10734
11003
|
}
|
10735
11004
|
|
10736
11005
|
return this;
|
@@ -10749,7 +11018,7 @@ function $LocationProvider(){
|
|
10749
11018
|
* This change can be prevented by calling
|
10750
11019
|
* `preventDefault` method of the event. See {@link ng.$rootScope.Scope#$on} for more
|
10751
11020
|
* details about event object. Upon successful change
|
10752
|
-
* {@link ng.$location
|
11021
|
+
* {@link ng.$location#$locationChangeSuccess $locationChangeSuccess} is fired.
|
10753
11022
|
*
|
10754
11023
|
* The `newState` and `oldState` parameters may be defined only in HTML5 mode and when
|
10755
11024
|
* the browser supports the HTML5 History API.
|
@@ -10901,9 +11170,10 @@ function $LocationProvider(){
|
|
10901
11170
|
var oldUrl = $browser.url();
|
10902
11171
|
var oldState = $browser.state();
|
10903
11172
|
var currentReplace = $location.$$replace;
|
11173
|
+
var urlOrStateChanged = oldUrl !== $location.absUrl() ||
|
11174
|
+
($location.$$html5 && $sniffer.history && oldState !== $location.$$state);
|
10904
11175
|
|
10905
|
-
if (initializing ||
|
10906
|
-
($location.$$html5 && $sniffer.history && oldState !== $location.$$state)) {
|
11176
|
+
if (initializing || urlOrStateChanged) {
|
10907
11177
|
initializing = false;
|
10908
11178
|
|
10909
11179
|
$rootScope.$evalAsync(function() {
|
@@ -10912,8 +11182,10 @@ function $LocationProvider(){
|
|
10912
11182
|
$location.$$parse(oldUrl);
|
10913
11183
|
$location.$$state = oldState;
|
10914
11184
|
} else {
|
10915
|
-
|
10916
|
-
|
11185
|
+
if (urlOrStateChanged) {
|
11186
|
+
setBrowserUrlWithFallback($location.absUrl(), currentReplace,
|
11187
|
+
oldState === $location.$$state ? null : $location.$$state);
|
11188
|
+
}
|
10917
11189
|
afterLocationChange(oldUrl, oldState);
|
10918
11190
|
}
|
10919
11191
|
});
|
@@ -11195,7 +11467,6 @@ CONSTANTS['this'].sharedGetter = true;
|
|
11195
11467
|
|
11196
11468
|
//Operators - will be wrapped by binaryFn/unaryFn/assignment/filter
|
11197
11469
|
var OPERATORS = extend(createMap(), {
|
11198
|
-
/* jshint bitwise : false */
|
11199
11470
|
'+':function(self, locals, a,b){
|
11200
11471
|
a=a(self, locals); b=b(self, locals);
|
11201
11472
|
if (isDefined(a)) {
|
@@ -11212,7 +11483,6 @@ var OPERATORS = extend(createMap(), {
|
|
11212
11483
|
'*':function(self, locals, a,b){return a(self, locals)*b(self, locals);},
|
11213
11484
|
'/':function(self, locals, a,b){return a(self, locals)/b(self, locals);},
|
11214
11485
|
'%':function(self, locals, a,b){return a(self, locals)%b(self, locals);},
|
11215
|
-
'^':function(self, locals, a,b){return a(self, locals)^b(self, locals);},
|
11216
11486
|
'===':function(self, locals, a, b){return a(self, locals)===b(self, locals);},
|
11217
11487
|
'!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);},
|
11218
11488
|
'==':function(self, locals, a,b){return a(self, locals)==b(self, locals);},
|
@@ -11223,14 +11493,12 @@ var OPERATORS = extend(createMap(), {
|
|
11223
11493
|
'>=':function(self, locals, a,b){return a(self, locals)>=b(self, locals);},
|
11224
11494
|
'&&':function(self, locals, a,b){return a(self, locals)&&b(self, locals);},
|
11225
11495
|
'||':function(self, locals, a,b){return a(self, locals)||b(self, locals);},
|
11226
|
-
'&':function(self, locals, a,b){return a(self, locals)&b(self, locals);},
|
11227
11496
|
'!':function(self, locals, a){return !a(self, locals);},
|
11228
11497
|
|
11229
11498
|
//Tokenized as operators but parsed as assignment/filters
|
11230
11499
|
'=':true,
|
11231
11500
|
'|':true
|
11232
11501
|
});
|
11233
|
-
/* jshint bitwise: true */
|
11234
11502
|
var ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'};
|
11235
11503
|
|
11236
11504
|
|
@@ -12268,16 +12536,17 @@ function $ParseProvider() {
|
|
12268
12536
|
}
|
12269
12537
|
|
12270
12538
|
function oneTimeLiteralWatchDelegate(scope, listener, objectEquality, parsedExpression) {
|
12271
|
-
var unwatch;
|
12539
|
+
var unwatch, lastValue;
|
12272
12540
|
return unwatch = scope.$watch(function oneTimeWatch(scope) {
|
12273
12541
|
return parsedExpression(scope);
|
12274
12542
|
}, function oneTimeListener(value, old, scope) {
|
12543
|
+
lastValue = value;
|
12275
12544
|
if (isFunction(listener)) {
|
12276
12545
|
listener.call(this, value, old, scope);
|
12277
12546
|
}
|
12278
12547
|
if (isAllDefined(value)) {
|
12279
12548
|
scope.$$postDigest(function () {
|
12280
|
-
if(isAllDefined(
|
12549
|
+
if(isAllDefined(lastValue)) unwatch();
|
12281
12550
|
});
|
12282
12551
|
}
|
12283
12552
|
}, objectEquality);
|
@@ -12353,24 +12622,27 @@ function $ParseProvider() {
|
|
12353
12622
|
* It can be used like so:
|
12354
12623
|
*
|
12355
12624
|
* ```js
|
12356
|
-
*
|
12357
|
-
* //
|
12358
|
-
*
|
12359
|
-
*
|
12360
|
-
*
|
12361
|
-
*
|
12362
|
-
*
|
12363
|
-
*
|
12364
|
-
*
|
12365
|
-
*
|
12366
|
-
*
|
12367
|
-
*
|
12368
|
-
*
|
12369
|
-
*
|
12370
|
-
*
|
12371
|
-
*
|
12625
|
+
* // for the purpose of this example let's assume that variables `$q` and `okToGreet`
|
12626
|
+
* // are available in the current lexical scope (they could have been injected or passed in).
|
12627
|
+
*
|
12628
|
+
* function asyncGreet(name) {
|
12629
|
+
* // perform some asynchronous operation, resolve or reject the promise when appropriate.
|
12630
|
+
* return $q(function(resolve, reject) {
|
12631
|
+
* setTimeout(function() {
|
12632
|
+
* if (okToGreet(name)) {
|
12633
|
+
* resolve('Hello, ' + name + '!');
|
12634
|
+
* } else {
|
12635
|
+
* reject('Greeting ' + name + ' is not allowed.');
|
12636
|
+
* }
|
12637
|
+
* }, 1000);
|
12638
|
+
* });
|
12639
|
+
* }
|
12640
|
+
*
|
12641
|
+
* var promise = asyncGreet('Robin Hood');
|
12642
|
+
* promise.then(function(greeting) {
|
12643
|
+
* alert('Success: ' + greeting);
|
12372
12644
|
* }, function(reason) {
|
12373
|
-
*
|
12645
|
+
* alert('Failed: ' + reason);
|
12374
12646
|
* });
|
12375
12647
|
* ```
|
12376
12648
|
*
|
@@ -12386,7 +12658,7 @@ function $ParseProvider() {
|
|
12386
12658
|
* asynchronous programming what `try`, `catch` and `throw` keywords are to synchronous programming.
|
12387
12659
|
*
|
12388
12660
|
* ```js
|
12389
|
-
* // for the purpose of this example let's assume that variables `$q
|
12661
|
+
* // for the purpose of this example let's assume that variables `$q` and `okToGreet`
|
12390
12662
|
* // are available in the current lexical scope (they could have been injected or passed in).
|
12391
12663
|
*
|
12392
12664
|
* function asyncGreet(name) {
|
@@ -14726,7 +14998,7 @@ function $SceDelegateProvider() {
|
|
14726
14998
|
*
|
14727
14999
|
* As of version 1.2, Angular ships with SCE enabled by default.
|
14728
15000
|
*
|
14729
|
-
* Note: When enabled (the default),
|
15001
|
+
* Note: When enabled (the default), IE<11 in quirks mode is not supported. In this mode, IE<11 allow
|
14730
15002
|
* one to execute arbitrary javascript by the use of the expression() syntax. Refer
|
14731
15003
|
* <http://blogs.msdn.com/b/ie/archive/2008/10/16/ending-expressions.aspx> to learn more about them.
|
14732
15004
|
* You can ensure your document is in standards mode and not quirks mode by adding `<!doctype html>`
|
@@ -14773,7 +15045,7 @@ function $SceDelegateProvider() {
|
|
14773
15045
|
*
|
14774
15046
|
* In privileged contexts, directives and code will bind to the result of {@link ng.$sce#getTrusted
|
14775
15047
|
* $sce.getTrusted(context, value)} rather than to the value directly. Directives use {@link
|
14776
|
-
* ng.$sce#
|
15048
|
+
* ng.$sce#parseAs $sce.parseAs} rather than `$parse` to watch attribute bindings, which performs the
|
14777
15049
|
* {@link ng.$sce#getTrusted $sce.getTrusted} behind the scenes on non-constant literals.
|
14778
15050
|
*
|
14779
15051
|
* As an example, {@link ng.directive:ngBindHtml ngBindHtml} uses {@link
|
@@ -15043,13 +15315,13 @@ function $SceProvider() {
|
|
15043
15315
|
* sce.js and sceSpecs.js would need to be aware of this detail.
|
15044
15316
|
*/
|
15045
15317
|
|
15046
|
-
this.$get = ['$
|
15047
|
-
$
|
15048
|
-
// Prereq: Ensure that we're not running in
|
15318
|
+
this.$get = ['$document', '$parse', '$sceDelegate', function(
|
15319
|
+
$document, $parse, $sceDelegate) {
|
15320
|
+
// Prereq: Ensure that we're not running in IE<11 quirks mode. In that mode, IE < 11 allow
|
15049
15321
|
// the "expression(javascript expression)" syntax which is insecure.
|
15050
|
-
if (enabled && $
|
15322
|
+
if (enabled && $document[0].documentMode < 8) {
|
15051
15323
|
throw $sceMinErr('iequirks',
|
15052
|
-
'Strict Contextual Escaping does not support Internet Explorer version <
|
15324
|
+
'Strict Contextual Escaping does not support Internet Explorer version < 11 in quirks ' +
|
15053
15325
|
'mode. You can fix this by adding the text <!doctype html> to the top of your HTML ' +
|
15054
15326
|
'document. See http://docs.angularjs.org/api/ng.$sce for more information.');
|
15055
15327
|
}
|
@@ -15272,7 +15544,7 @@ function $SceProvider() {
|
|
15272
15544
|
*
|
15273
15545
|
* @description
|
15274
15546
|
* Shorthand method. `$sce.parseAsHtml(expression string)` →
|
15275
|
-
* {@link ng.$sce#
|
15547
|
+
* {@link ng.$sce#parseAs `$sce.parseAs($sce.HTML, value)`}
|
15276
15548
|
*
|
15277
15549
|
* @param {string} expression String expression to compile.
|
15278
15550
|
* @returns {function(context, locals)} a function which represents the compiled expression:
|
@@ -15289,7 +15561,7 @@ function $SceProvider() {
|
|
15289
15561
|
*
|
15290
15562
|
* @description
|
15291
15563
|
* Shorthand method. `$sce.parseAsCss(value)` →
|
15292
|
-
* {@link ng.$sce#
|
15564
|
+
* {@link ng.$sce#parseAs `$sce.parseAs($sce.CSS, value)`}
|
15293
15565
|
*
|
15294
15566
|
* @param {string} expression String expression to compile.
|
15295
15567
|
* @returns {function(context, locals)} a function which represents the compiled expression:
|
@@ -15306,7 +15578,7 @@ function $SceProvider() {
|
|
15306
15578
|
*
|
15307
15579
|
* @description
|
15308
15580
|
* Shorthand method. `$sce.parseAsUrl(value)` →
|
15309
|
-
* {@link ng.$sce#
|
15581
|
+
* {@link ng.$sce#parseAs `$sce.parseAs($sce.URL, value)`}
|
15310
15582
|
*
|
15311
15583
|
* @param {string} expression String expression to compile.
|
15312
15584
|
* @returns {function(context, locals)} a function which represents the compiled expression:
|
@@ -15323,7 +15595,7 @@ function $SceProvider() {
|
|
15323
15595
|
*
|
15324
15596
|
* @description
|
15325
15597
|
* Shorthand method. `$sce.parseAsResourceUrl(value)` →
|
15326
|
-
* {@link ng.$sce#
|
15598
|
+
* {@link ng.$sce#parseAs `$sce.parseAs($sce.RESOURCE_URL, value)`}
|
15327
15599
|
*
|
15328
15600
|
* @param {string} expression String expression to compile.
|
15329
15601
|
* @returns {function(context, locals)} a function which represents the compiled expression:
|
@@ -15340,7 +15612,7 @@ function $SceProvider() {
|
|
15340
15612
|
*
|
15341
15613
|
* @description
|
15342
15614
|
* Shorthand method. `$sce.parseAsJs(value)` →
|
15343
|
-
* {@link ng.$sce#
|
15615
|
+
* {@link ng.$sce#parseAs `$sce.parseAs($sce.JS, value)`}
|
15344
15616
|
*
|
15345
15617
|
* @param {string} expression String expression to compile.
|
15346
15618
|
* @returns {function(context, locals)} a function which represents the compiled expression:
|
@@ -15394,7 +15666,6 @@ function $SnifferProvider() {
|
|
15394
15666
|
int((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]),
|
15395
15667
|
boxee = /Boxee/i.test(($window.navigator || {}).userAgent),
|
15396
15668
|
document = $document[0] || {},
|
15397
|
-
documentMode = document.documentMode,
|
15398
15669
|
vendorPrefix,
|
15399
15670
|
vendorRegex = /^(Moz|webkit|O|ms)(?=[A-Z])/,
|
15400
15671
|
bodyStyle = document.body && document.body.style,
|
@@ -15454,9 +15725,7 @@ function $SnifferProvider() {
|
|
15454
15725
|
vendorPrefix: vendorPrefix,
|
15455
15726
|
transitions : transitions,
|
15456
15727
|
animations : animations,
|
15457
|
-
android: android
|
15458
|
-
msie : msie,
|
15459
|
-
msieDocumentMode: documentMode
|
15728
|
+
android: android
|
15460
15729
|
};
|
15461
15730
|
}];
|
15462
15731
|
}
|
@@ -16161,17 +16430,17 @@ function filterFilter() {
|
|
16161
16430
|
}
|
16162
16431
|
|
16163
16432
|
var search = function(obj, text){
|
16164
|
-
if (typeof text
|
16433
|
+
if (typeof text === 'string' && text.charAt(0) === '!') {
|
16165
16434
|
return !search(obj, text.substr(1));
|
16166
16435
|
}
|
16167
16436
|
switch (typeof obj) {
|
16168
|
-
case
|
16169
|
-
case
|
16170
|
-
case
|
16437
|
+
case 'boolean':
|
16438
|
+
case 'number':
|
16439
|
+
case 'string':
|
16171
16440
|
return comparator(obj, text);
|
16172
|
-
case
|
16441
|
+
case 'object':
|
16173
16442
|
switch (typeof text) {
|
16174
|
-
case
|
16443
|
+
case 'object':
|
16175
16444
|
return comparator(obj, text);
|
16176
16445
|
default:
|
16177
16446
|
for ( var objKey in obj) {
|
@@ -16182,7 +16451,7 @@ function filterFilter() {
|
|
16182
16451
|
break;
|
16183
16452
|
}
|
16184
16453
|
return false;
|
16185
|
-
case
|
16454
|
+
case 'array':
|
16186
16455
|
for ( var i = 0; i < obj.length; i++) {
|
16187
16456
|
if (search(obj[i], text)) {
|
16188
16457
|
return true;
|
@@ -16194,13 +16463,13 @@ function filterFilter() {
|
|
16194
16463
|
}
|
16195
16464
|
};
|
16196
16465
|
switch (typeof expression) {
|
16197
|
-
case
|
16198
|
-
case
|
16199
|
-
case
|
16466
|
+
case 'boolean':
|
16467
|
+
case 'number':
|
16468
|
+
case 'string':
|
16200
16469
|
// Set up expression object and fall through
|
16201
16470
|
expression = {$:expression};
|
16202
16471
|
// jshint -W086
|
16203
|
-
case
|
16472
|
+
case 'object':
|
16204
16473
|
// jshint +W086
|
16205
16474
|
for (var key in expression) {
|
16206
16475
|
(function(path) {
|
@@ -16239,6 +16508,7 @@ function filterFilter() {
|
|
16239
16508
|
*
|
16240
16509
|
* @param {number} amount Input to filter.
|
16241
16510
|
* @param {string=} symbol Currency symbol or identifier to be displayed.
|
16511
|
+
* @param {number=} fractionSize Number of decimal places to round the amount to.
|
16242
16512
|
* @returns {string} Formatted number.
|
16243
16513
|
*
|
16244
16514
|
*
|
@@ -16254,13 +16524,15 @@ function filterFilter() {
|
|
16254
16524
|
<div ng-controller="ExampleController">
|
16255
16525
|
<input type="number" ng-model="amount"> <br>
|
16256
16526
|
default currency symbol ($): <span id="currency-default">{{amount | currency}}</span><br>
|
16257
|
-
custom currency identifier (USD$): <span>{{amount | currency:"USD$"}}</span>
|
16527
|
+
custom currency identifier (USD$): <span id="currency-custom">{{amount | currency:"USD$"}}</span>
|
16528
|
+
no fractions (0): <span id="currency-no-fractions">{{amount | currency:"USD$":0}}</span>
|
16258
16529
|
</div>
|
16259
16530
|
</file>
|
16260
16531
|
<file name="protractor.js" type="protractor">
|
16261
16532
|
it('should init with 1234.56', function() {
|
16262
16533
|
expect(element(by.id('currency-default')).getText()).toBe('$1,234.56');
|
16263
|
-
expect(element(by.
|
16534
|
+
expect(element(by.id('currency-custom')).getText()).toBe('USD$1,234.56');
|
16535
|
+
expect(element(by.id('currency-no-fractions')).getText()).toBe('USD$1,235');
|
16264
16536
|
});
|
16265
16537
|
it('should update', function() {
|
16266
16538
|
if (browser.params.browser == 'safari') {
|
@@ -16271,7 +16543,8 @@ function filterFilter() {
|
|
16271
16543
|
element(by.model('amount')).clear();
|
16272
16544
|
element(by.model('amount')).sendKeys('-1234');
|
16273
16545
|
expect(element(by.id('currency-default')).getText()).toBe('($1,234.00)');
|
16274
|
-
expect(element(by.
|
16546
|
+
expect(element(by.id('currency-custom')).getText()).toBe('(USD$1,234.00)');
|
16547
|
+
expect(element(by.id('currency-no-fractions')).getText()).toBe('(USD$1,234)');
|
16275
16548
|
});
|
16276
16549
|
</file>
|
16277
16550
|
</example>
|
@@ -16279,13 +16552,20 @@ function filterFilter() {
|
|
16279
16552
|
currencyFilter.$inject = ['$locale'];
|
16280
16553
|
function currencyFilter($locale) {
|
16281
16554
|
var formats = $locale.NUMBER_FORMATS;
|
16282
|
-
return function(amount, currencySymbol){
|
16283
|
-
if (isUndefined(currencySymbol))
|
16555
|
+
return function(amount, currencySymbol, fractionSize){
|
16556
|
+
if (isUndefined(currencySymbol)) {
|
16557
|
+
currencySymbol = formats.CURRENCY_SYM;
|
16558
|
+
}
|
16559
|
+
|
16560
|
+
if (isUndefined(fractionSize)) {
|
16561
|
+
// TODO: read the default value from the locale file
|
16562
|
+
fractionSize = 2;
|
16563
|
+
}
|
16284
16564
|
|
16285
16565
|
// if null or undefined pass it through
|
16286
16566
|
return (amount == null)
|
16287
16567
|
? amount
|
16288
|
-
: formatNumber(amount, formats.PATTERNS[1], formats.GROUP_SEP, formats.DECIMAL_SEP,
|
16568
|
+
: formatNumber(amount, formats.PATTERNS[1], formats.GROUP_SEP, formats.DECIMAL_SEP, fractionSize).
|
16289
16569
|
replace(/\u00A4/g, currencySymbol);
|
16290
16570
|
};
|
16291
16571
|
}
|
@@ -16802,7 +17082,7 @@ var uppercaseFilter = valueFn(uppercase);
|
|
16802
17082
|
<p>Output numbers: {{ numbers | limitTo:numLimit }}</p>
|
16803
17083
|
Limit {{letters}} to: <input type="number" step="1" ng-model="letterLimit">
|
16804
17084
|
<p>Output letters: {{ letters | limitTo:letterLimit }}</p>
|
16805
|
-
Limit {{longNumber}} to: <input type="
|
17085
|
+
Limit {{longNumber}} to: <input type="number" step="1" ng-model="longNumberLimit">
|
16806
17086
|
<p>Output long number: {{ longNumber | limitTo:longNumberLimit }}</p>
|
16807
17087
|
</div>
|
16808
17088
|
</file>
|
@@ -18039,15 +18319,13 @@ var formDirectiveFactory = function(isNgForm) {
|
|
18039
18319
|
parentFormCtrl.$$renameControl(controller, alias);
|
18040
18320
|
});
|
18041
18321
|
}
|
18042
|
-
|
18043
|
-
|
18044
|
-
|
18045
|
-
|
18046
|
-
|
18047
|
-
|
18048
|
-
|
18049
|
-
});
|
18050
|
-
}
|
18322
|
+
formElement.on('$destroy', function() {
|
18323
|
+
parentFormCtrl.$removeControl(controller);
|
18324
|
+
if (alias) {
|
18325
|
+
setter(scope, alias, undefined, alias);
|
18326
|
+
}
|
18327
|
+
extend(controller, nullFormCtrl); //stop propagating child destruction handlers upwards
|
18328
|
+
});
|
18051
18329
|
}
|
18052
18330
|
};
|
18053
18331
|
}
|
@@ -21294,7 +21572,7 @@ var ngBindTemplateDirective = ['$interpolate', '$compile', function($interpolate
|
|
21294
21572
|
*
|
21295
21573
|
* You may also bypass sanitization for values you know are safe. To do so, bind to
|
21296
21574
|
* an explicitly trusted value via {@link ng.$sce#trustAsHtml $sce.trustAsHtml}. See the example
|
21297
|
-
* under {@link ng.$sce#
|
21575
|
+
* under {@link ng.$sce#show-me-an-example-using-sce- Strict Contextual Escaping (SCE)}.
|
21298
21576
|
*
|
21299
21577
|
* Note: If a `$sanitize` service is unavailable and the bound value isn't explicitly trusted, you
|
21300
21578
|
* will have an exception (instead of an exploit.)
|
@@ -21606,8 +21884,8 @@ function classDirective(name, selector) {
|
|
21606
21884
|
The ngClass directive still supports CSS3 Transitions/Animations even if they do not follow the ngAnimate CSS naming structure.
|
21607
21885
|
Upon animation ngAnimate will apply supplementary CSS classes to track the start and end of an animation, but this will not hinder
|
21608
21886
|
any pre-existing CSS transitions already on the element. To get an idea of what happens during a class-based animation, be sure
|
21609
|
-
to view the step by step details of {@link
|
21610
|
-
{@link
|
21887
|
+
to view the step by step details of {@link ng.$animate#addClass $animate.addClass} and
|
21888
|
+
{@link ng.$animate#removeClass $animate.removeClass}.
|
21611
21889
|
*/
|
21612
21890
|
var ngClassDirective = classDirective('', true);
|
21613
21891
|
|
@@ -22013,7 +22291,7 @@ var ngControllerDirective = [function() {
|
|
22013
22291
|
* @description
|
22014
22292
|
* Enables [CSP (Content Security Policy)](https://developer.mozilla.org/en/Security/CSP) support.
|
22015
22293
|
*
|
22016
|
-
* This is necessary when developing things like Google Chrome Extensions.
|
22294
|
+
* This is necessary when developing things like Google Chrome Extensions or Universal Windows Apps.
|
22017
22295
|
*
|
22018
22296
|
* CSP forbids apps to use `eval` or `Function(string)` generated functions (among other things).
|
22019
22297
|
* For Angular to be CSP compatible there are only two things that we need to do differently:
|
@@ -22709,7 +22987,7 @@ forEach(
|
|
22709
22987
|
Click me: <input type="checkbox" ng-model="checked" ng-init="checked=true" /><br/>
|
22710
22988
|
Show when checked:
|
22711
22989
|
<span ng-if="checked" class="animate-if">
|
22712
|
-
|
22990
|
+
This is removed when the checkbox is unchecked.
|
22713
22991
|
</span>
|
22714
22992
|
</file>
|
22715
22993
|
<file name="animations.css">
|
@@ -22763,15 +23041,15 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
22763
23041
|
});
|
22764
23042
|
}
|
22765
23043
|
} else {
|
22766
|
-
if(previousElements) {
|
23044
|
+
if (previousElements) {
|
22767
23045
|
previousElements.remove();
|
22768
23046
|
previousElements = null;
|
22769
23047
|
}
|
22770
|
-
if(childScope) {
|
23048
|
+
if (childScope) {
|
22771
23049
|
childScope.$destroy();
|
22772
23050
|
childScope = null;
|
22773
23051
|
}
|
22774
|
-
if(block) {
|
23052
|
+
if (block) {
|
22775
23053
|
previousElements = getBlockNodes(block.clone);
|
22776
23054
|
$animate.leave(previousElements).then(function() {
|
22777
23055
|
previousElements = null;
|
@@ -22793,10 +23071,10 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
22793
23071
|
* Fetches, compiles and includes an external HTML fragment.
|
22794
23072
|
*
|
22795
23073
|
* By default, the template URL is restricted to the same domain and protocol as the
|
22796
|
-
* application document. This is done by calling {@link
|
23074
|
+
* application document. This is done by calling {@link $sce#getTrustedResourceUrl
|
22797
23075
|
* $sce.getTrustedResourceUrl} on it. To load templates from other domains or protocols
|
22798
23076
|
* you may either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist them} or
|
22799
|
-
*
|
23077
|
+
* {@link $sce#trustAsResourceUrl wrap them} as trusted values. Refer to Angular's {@link
|
22800
23078
|
* ng.$sce Strict Contextual Escaping}.
|
22801
23079
|
*
|
22802
23080
|
* In addition, the browser's
|
@@ -23495,13 +23773,6 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
|
|
23495
23773
|
* For example: `item in items` is equivalent to `item in items track by $id(item)`. This implies that the DOM elements
|
23496
23774
|
* will be associated by item identity in the array.
|
23497
23775
|
*
|
23498
|
-
* * `variable in expression as alias_expression` – You can also provide an optional alias expression which will then store the
|
23499
|
-
* intermediate results of the repeater after the filters have been applied. Typically this is used to render a special message
|
23500
|
-
* when a filter is active on the repeater, but the filtered result set is empty.
|
23501
|
-
*
|
23502
|
-
* For example: `item in items | filter:x as results` will store the fragment of the repeated items as `results`, but only after
|
23503
|
-
* the items have been processed through the filter.
|
23504
|
-
*
|
23505
23776
|
* For example: `item in items track by $id(item)`. A built in `$id()` function can be used to assign a unique
|
23506
23777
|
* `$$hashKey` property to each item in the array. This property is then used as a key to associated DOM elements
|
23507
23778
|
* with the corresponding item in the array by identity. Moving the same object in array would move the DOM
|
@@ -23514,6 +23785,13 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
|
|
23514
23785
|
* For example: `item in items | filter:searchText track by item.id` is a pattern that might be used to apply a filter
|
23515
23786
|
* to items in conjunction with a tracking expression.
|
23516
23787
|
*
|
23788
|
+
* * `variable in expression as alias_expression` – You can also provide an optional alias expression which will then store the
|
23789
|
+
* intermediate results of the repeater after the filters have been applied. Typically this is used to render a special message
|
23790
|
+
* when a filter is active on the repeater, but the filtered result set is empty.
|
23791
|
+
*
|
23792
|
+
* For example: `item in items | filter:x as results` will store the fragment of the repeated items as `results`, but only after
|
23793
|
+
* the items have been processed through the filter.
|
23794
|
+
*
|
23517
23795
|
* @example
|
23518
23796
|
* This example initializes the scope to a list of names and
|
23519
23797
|
* then uses `ngRepeat` to display every person:
|
@@ -24001,7 +24279,9 @@ var ngShowDirective = ['$animate', function($animate) {
|
|
24001
24279
|
// we can control when the element is actually displayed on screen without having
|
24002
24280
|
// to have a global/greedy CSS selector that breaks when other animations are run.
|
24003
24281
|
// Read: https://github.com/angular/angular.js/issues/9103#issuecomment-58335845
|
24004
|
-
$animate[value ? 'removeClass' : 'addClass'](element, NG_HIDE_CLASS,
|
24282
|
+
$animate[value ? 'removeClass' : 'addClass'](element, NG_HIDE_CLASS, {
|
24283
|
+
tempClasses : NG_HIDE_IN_PROGRESS_CLASS
|
24284
|
+
});
|
24005
24285
|
});
|
24006
24286
|
}
|
24007
24287
|
};
|
@@ -24158,7 +24438,9 @@ var ngHideDirective = ['$animate', function($animate) {
|
|
24158
24438
|
scope.$watch(attr.ngHide, function ngHideWatchAction(value){
|
24159
24439
|
// The comment inside of the ngShowDirective explains why we add and
|
24160
24440
|
// remove a temporary class for the show/hide animation
|
24161
|
-
$animate[value ? 'addClass' : 'removeClass'](element,NG_HIDE_CLASS,
|
24441
|
+
$animate[value ? 'addClass' : 'removeClass'](element,NG_HIDE_CLASS, {
|
24442
|
+
tempClasses : NG_HIDE_IN_PROGRESS_CLASS
|
24443
|
+
});
|
24162
24444
|
});
|
24163
24445
|
}
|
24164
24446
|
};
|
@@ -24583,9 +24865,23 @@ var ngOptionsMinErr = minErr('ngOptions');
|
|
24583
24865
|
* <div class="alert alert-info">
|
24584
24866
|
* **Note:** Using `select as` will bind the result of the `select as` expression to the model, but
|
24585
24867
|
* the value of the `<select>` and `<option>` html elements will be either the index (for array data sources)
|
24586
|
-
* or property name (for object data sources) of the value
|
24868
|
+
* or property name (for object data sources) of the value within the collection.
|
24587
24869
|
* </div>
|
24588
24870
|
*
|
24871
|
+
* **Note:** Using `select as` together with `trackexpr` is not recommended.
|
24872
|
+
* Reasoning:
|
24873
|
+
* - Example: <select ng-options="item.subItem as item.label for item in values track by item.id" ng-model="selected">
|
24874
|
+
* values: [{id: 1, label: 'aLabel', subItem: {name: 'aSubItem'}}, {id: 2, label: 'bLabel', subItem: {name: 'bSubItem'}}],
|
24875
|
+
* $scope.selected = {name: 'aSubItem'};
|
24876
|
+
* - track by is always applied to `value`, with the purpose of preserving the selection,
|
24877
|
+
* (to `item` in this case)
|
24878
|
+
* - to calculate whether an item is selected we do the following:
|
24879
|
+
* 1. apply `track by` to the values in the array, e.g.
|
24880
|
+
* In the example: [1,2]
|
24881
|
+
* 2. apply `track by` to the already selected value in `ngModel`:
|
24882
|
+
* In the example: this is not possible, as `track by` refers to `item.id`, but the selected
|
24883
|
+
* value from `ngModel` is `{name: aSubItem}`.
|
24884
|
+
*
|
24589
24885
|
* @param {string} ngModel Assignable angular expression to data-bind to.
|
24590
24886
|
* @param {string=} name Property name of the form under which the control is published.
|
24591
24887
|
* @param {string=} required The control is considered valid only if value is entered.
|
@@ -24622,23 +24918,6 @@ var ngOptionsMinErr = minErr('ngOptions');
|
|
24622
24918
|
* used to identify the objects in the array. The `trackexpr` will most likely refer to the
|
24623
24919
|
* `value` variable (e.g. `value.propertyName`). With this the selection is preserved
|
24624
24920
|
* even when the options are recreated (e.g. reloaded from the server).
|
24625
|
-
|
24626
|
-
* <div class="alert alert-info">
|
24627
|
-
* **Note:** Using `select as` together with `trackexpr` is not possible (and will throw).
|
24628
|
-
* Reasoning:
|
24629
|
-
* - Example: <select ng-options="item.subItem as item.label for item in values track by item.id" ng-model="selected">
|
24630
|
-
* values: [{id: 1, label: 'aLabel', subItem: {name: 'aSubItem'}}, {id: 2, label: 'bLabel', subItem: {name: 'bSubItemß'}}],
|
24631
|
-
* $scope.selected = {name: 'aSubItem'};
|
24632
|
-
* - track by is always applied to `value`, with purpose to preserve the selection,
|
24633
|
-
* (to `item` in this case)
|
24634
|
-
* - to calculate whether an item is selected we do the following:
|
24635
|
-
* 1. apply `track by` to the values in the array, e.g.
|
24636
|
-
* In the example: [1,2]
|
24637
|
-
* 2. apply `track by` to the already selected value in `ngModel`:
|
24638
|
-
* In the example: this is not possible, as `track by` refers to `item.id`, but the selected
|
24639
|
-
* value from `ngModel` is `{name: aSubItem}`.
|
24640
|
-
*
|
24641
|
-
* </div>
|
24642
24921
|
*
|
24643
24922
|
* @example
|
24644
24923
|
<example module="selectExample">
|
@@ -24748,7 +25027,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
24748
25027
|
// Workaround for https://code.google.com/p/chromium/issues/detail?id=381459
|
24749
25028
|
// Adding an <option selected="selected"> element to a <select required="required"> should
|
24750
25029
|
// automatically select the new element
|
24751
|
-
if (element[0].hasAttribute('selected')) {
|
25030
|
+
if (element && element[0].hasAttribute('selected')) {
|
24752
25031
|
element[0].selected = true;
|
24753
25032
|
}
|
24754
25033
|
};
|
@@ -24911,13 +25190,6 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
24911
25190
|
//re-usable object to represent option's locals
|
24912
25191
|
locals = {};
|
24913
25192
|
|
24914
|
-
if (trackFn && selectAsFn) {
|
24915
|
-
throw ngOptionsMinErr('trkslct',
|
24916
|
-
"Comprehension expression cannot contain both selectAs '{0}' " +
|
24917
|
-
"and trackBy '{1}' expressions.",
|
24918
|
-
selectAs, track);
|
24919
|
-
}
|
24920
|
-
|
24921
25193
|
if (nullOption) {
|
24922
25194
|
// compile the element since there might be bindings in it
|
24923
25195
|
$compile(nullOption)(scope);
|
@@ -25008,7 +25280,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
25008
25280
|
function createIsSelectedFn(viewValue) {
|
25009
25281
|
var selectedSet;
|
25010
25282
|
if (multiple) {
|
25011
|
-
if (
|
25283
|
+
if (trackFn && isArray(viewValue)) {
|
25012
25284
|
|
25013
25285
|
selectedSet = new HashMap([]);
|
25014
25286
|
for (var trackIndex = 0; trackIndex < viewValue.length; trackIndex++) {
|
@@ -25018,15 +25290,16 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
25018
25290
|
} else {
|
25019
25291
|
selectedSet = new HashMap(viewValue);
|
25020
25292
|
}
|
25021
|
-
} else if (
|
25293
|
+
} else if (trackFn) {
|
25022
25294
|
viewValue = callExpression(trackFn, null, viewValue);
|
25023
25295
|
}
|
25296
|
+
|
25024
25297
|
return function isSelected(key, value) {
|
25025
25298
|
var compareValueFn;
|
25026
|
-
if (
|
25027
|
-
compareValueFn = selectAsFn;
|
25028
|
-
} else if (trackFn) {
|
25299
|
+
if (trackFn) {
|
25029
25300
|
compareValueFn = trackFn;
|
25301
|
+
} else if (selectAsFn) {
|
25302
|
+
compareValueFn = selectAsFn;
|
25030
25303
|
} else {
|
25031
25304
|
compareValueFn = valueFn;
|
25032
25305
|
}
|
@@ -25046,6 +25319,23 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
25046
25319
|
}
|
25047
25320
|
}
|
25048
25321
|
|
25322
|
+
/**
|
25323
|
+
* A new labelMap is created with each render.
|
25324
|
+
* This function is called for each existing option with added=false,
|
25325
|
+
* and each new option with added=true.
|
25326
|
+
* - Labels that are passed to this method twice,
|
25327
|
+
* (once with added=true and once with added=false) will end up with a value of 0, and
|
25328
|
+
* will cause no change to happen to the corresponding option.
|
25329
|
+
* - Labels that are passed to this method only once with added=false will end up with a
|
25330
|
+
* value of -1 and will eventually be passed to selectCtrl.removeOption()
|
25331
|
+
* - Labels that are passed to this method only once with added=true will end up with a
|
25332
|
+
* value of 1 and will eventually be passed to selectCtrl.addOption()
|
25333
|
+
*/
|
25334
|
+
function updateLabelMap(labelMap, label, added) {
|
25335
|
+
labelMap[label] = labelMap[label] || 0;
|
25336
|
+
labelMap[label] += (added ? 1 : -1);
|
25337
|
+
}
|
25338
|
+
|
25049
25339
|
function render() {
|
25050
25340
|
renderScheduled = false;
|
25051
25341
|
|
@@ -25063,6 +25353,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
25063
25353
|
value,
|
25064
25354
|
groupLength, length,
|
25065
25355
|
groupIndex, index,
|
25356
|
+
labelMap = {},
|
25066
25357
|
selected,
|
25067
25358
|
isSelected = createIsSelectedFn(viewValue),
|
25068
25359
|
anySelected = false,
|
@@ -25145,6 +25436,8 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
25145
25436
|
// reuse elements
|
25146
25437
|
lastElement = existingOption.element;
|
25147
25438
|
if (existingOption.label !== option.label) {
|
25439
|
+
updateLabelMap(labelMap, existingOption.label, false);
|
25440
|
+
updateLabelMap(labelMap, option.label, true);
|
25148
25441
|
lastElement.text(existingOption.label = option.label);
|
25149
25442
|
}
|
25150
25443
|
if (existingOption.id !== option.id) {
|
@@ -25184,7 +25477,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
25184
25477
|
id: option.id,
|
25185
25478
|
selected: option.selected
|
25186
25479
|
});
|
25187
|
-
|
25480
|
+
updateLabelMap(labelMap, option.label, true);
|
25188
25481
|
if (lastElement) {
|
25189
25482
|
lastElement.after(element);
|
25190
25483
|
} else {
|
@@ -25197,9 +25490,16 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
25197
25490
|
index++; // increment since the existingOptions[0] is parent element not OPTION
|
25198
25491
|
while(existingOptions.length > index) {
|
25199
25492
|
option = existingOptions.pop();
|
25200
|
-
|
25493
|
+
updateLabelMap(labelMap, option.label, false);
|
25201
25494
|
option.element.remove();
|
25202
25495
|
}
|
25496
|
+
forEach(labelMap, function (count, label) {
|
25497
|
+
if (count > 0) {
|
25498
|
+
selectCtrl.addOption(label);
|
25499
|
+
} else if (count < 0) {
|
25500
|
+
selectCtrl.removeOption(label);
|
25501
|
+
}
|
25502
|
+
});
|
25203
25503
|
}
|
25204
25504
|
// remove any excessive OPTGROUPs from select
|
25205
25505
|
while(optionGroupsCache.length > groupIndex) {
|