angularjs-rails 1.2.26 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/angularjs-rails/version.rb +2 -2
- data/vendor/assets/javascripts/angular-animate.js +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) {
|