@angular-wave/angular.ts 0.0.1 → 0.0.4
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.
- package/Makefile +1 -1
- package/dist/angular-ts.cjs.js +506 -1696
- package/dist/angular-ts.esm.js +506 -1696
- package/dist/angular-ts.umd.js +506 -1696
- package/package.json +1 -1
- package/public/README.md +1 -0
- package/src/animations/{animateCss.js → animate-css.js} +0 -1
- package/src/animations/animation.js +428 -431
- package/src/animations/module.js +9 -9
- package/src/core/cache.js +2 -0
- package/src/core/compile.js +6 -1102
- package/src/core/compile.md +1192 -0
- package/src/core/location.js +1 -1
- package/src/core/utils.js +1 -1
- package/src/directive/a.js +1 -1
- package/src/directive/attrs.js +1 -1
- package/src/directive/csp.md +89 -0
- package/src/directive/input.js +3 -3
- package/src/directive/{ngModel.js → model.js} +1 -1
- package/src/directive/select.js +5 -5
- package/src/jqLite.js +1 -22
- package/src/public.js +24 -24
- package/src/services/log.js +66 -116
- package/src/services/log.md +39 -0
- package/test/jqlite.spec.js +5 -35
- package/test/messages/messages.spec.js +1 -1
- package/test/ng/compile.spec.js +17 -16
- package/test/ng/directive/model-options.spec.js +1 -1
- package/test/ng/directive/model.spec.js +1 -1
- package/test/ng/directive/options.spec.js +61 -61
- package/test/ng/directive/select.spec.js +22 -22
- package/test/ng/http-backend.spec.js +1 -1
- package/test/ng/on.spec.js +1 -1
- package/test/ng/prop.spec.js +54 -62
- package/test/ng/sanitize-uri.spec.js +1 -1
- package/test/ng/scope.spec.js +1 -1
- package/test/original-test.html +1 -1
- package/types/jqlite.d.ts +1 -32
- package/dist/build/angular-mocks.js +0 -3757
- package/dist/build/angular-parse-ext.js +0 -1275
- package/dist/build/angular-resource.js +0 -911
- package/dist/build/angular-touch.js +0 -368
- package/src/core/attributes.js +0 -199
- package/src/directive/ngCsp.js +0 -82
- /package/{dist/build → legacy}/angular-animate.js +0 -0
- /package/{dist/build → legacy}/angular-aria.js +0 -0
- /package/{dist/build → legacy}/angular-message-format.js +0 -0
- /package/{dist/build → legacy}/angular-messages.js +0 -0
- /package/{dist/build → legacy}/angular-route.js +0 -0
- /package/{dist/build → legacy}/angular-sanitize.js +0 -0
- /package/{dist/build → legacy}/angular.js +0 -0
- /package/src/animations/{animateCache.js → animate-cache.js} +0 -0
- /package/src/animations/{animateChildrenDirective.js → animate-children-directive.js} +0 -0
- /package/src/animations/{animateCssDriver.js → animate-css-driver.js} +0 -0
- /package/src/animations/{animateJsDriver.js → animate-js-driver.js} +0 -0
- /package/src/animations/{animateJs.js → animate-js.js} +0 -0
- /package/src/animations/{animateQueue.js → animate-queue.js} +0 -0
- /package/src/animations/{ngAnimateSwap.js → animate-swap.js} +0 -0
- /package/src/animations/{rafScheduler.js → raf-scheduler.js} +0 -0
- /package/src/core/{animateCss.js → animate-css.js} +0 -0
- /package/src/core/{animateRunner.js → animate-runner.js} +0 -0
- /package/src/core/{exceptionHandler.js → exception-handler.js} +0 -0
- /package/src/core/{intervalFactory.js → interval-factory.js} +0 -0
- /package/src/core/{rootScope.js → root-scope.js} +0 -0
- /package/src/core/{sanitizeUri.js → sanitize-uri.js} +0 -0
- /package/src/core/{taskTrackerFactory.js → task-tracker-factory.js} +0 -0
- /package/src/directive/{ngClass.js → class.js} +0 -0
- /package/src/directive/{ngController.js → controller.js} +0 -0
- /package/src/directive/{ngIf.js → if.js} +0 -0
- /package/src/directive/{ngInclude.js → include.js} +0 -0
- /package/src/directive/{ngModelOptions.js → model-options.js} +0 -0
- /package/src/directive/{ngOptions.js → options.js} +0 -0
- /package/src/directive/{ngRef.js → ref.js} +0 -0
- /package/src/directive/{ngRepeat.js → repeat.js} +0 -0
- /package/src/directive/{ngShowHide.js → show-hide.js} +0 -0
- /package/src/directive/{ngSwitch.js → switch.js} +0 -0
- /package/src/directive/{ngTransclude.js → transclude.js} +0 -0
- /package/src/{routeToRegExp.js → route-to-reg-exp.js} +0 -0
- /package/src/services/{anchorScroll.js → anchor-scroll.js} +0 -0
- /package/src/services/{cacheFactory.js → cache-factory.js} +0 -0
- /package/src/services/{cookieReader.js → cookie-reader.js} +0 -0
- /package/src/services/{httpBackend.js → http-backend.js} +0 -0
- /package/src/services/{templateRequest.js → template-request.js} +0 -0
- /package/test/ng/{anomate.spec.js → animate.spec.js} +0 -0
package/dist/angular-ts.umd.js
CHANGED
|
@@ -607,7 +607,7 @@
|
|
|
607
607
|
return !!(
|
|
608
608
|
node &&
|
|
609
609
|
(node.nodeName || // We are a direct element.
|
|
610
|
-
(node.
|
|
610
|
+
(node.attr && node.find))
|
|
611
611
|
); // We have an on and find method part of jQuery API.
|
|
612
612
|
}
|
|
613
613
|
|
|
@@ -1354,6 +1354,8 @@
|
|
|
1354
1354
|
*
|
|
1355
1355
|
*/
|
|
1356
1356
|
|
|
1357
|
+
const EXPANDO = "ngId";
|
|
1358
|
+
|
|
1357
1359
|
/**
|
|
1358
1360
|
* Expando cache for adding properties to DOM nodes with JavaScript.
|
|
1359
1361
|
* This used to be an Object in JQLite decorator, but swapped out for a Map
|
|
@@ -1416,12 +1418,10 @@
|
|
|
1416
1418
|
* ## AngularJS's jqLite
|
|
1417
1419
|
* jqLite provides only the following jQuery methods:
|
|
1418
1420
|
*
|
|
1419
|
-
* - [`addClass()`](http://api.jquery.com/addClass/) - Does not support a function as first argument
|
|
1420
1421
|
* - [`after()`](http://api.jquery.com/after/)
|
|
1421
1422
|
* - [`append()`](http://api.jquery.com/append/) - Contrary to jQuery, this doesn't clone elements
|
|
1422
1423
|
* so will not work correctly when invoked on a jqLite object containing more than one DOM node
|
|
1423
1424
|
* - [`attr()`](http://api.jquery.com/attr/) - Does not support functions as parameters
|
|
1424
|
-
* - [`bind()`](http://api.jquery.com/bind/) (_deprecated_, use [`on()`](http://api.jquery.com/on/)) - Does not support namespaces, selectors or eventData
|
|
1425
1425
|
* - [`children()`](http://api.jquery.com/children/) - Does not support selectors
|
|
1426
1426
|
* - [`data()`](http://api.jquery.com/data/)
|
|
1427
1427
|
* - [`empty()`](http://api.jquery.com/empty/)
|
|
@@ -1432,7 +1432,6 @@
|
|
|
1432
1432
|
* - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors
|
|
1433
1433
|
* - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors
|
|
1434
1434
|
* - [`prepend()`](http://api.jquery.com/prepend/)
|
|
1435
|
-
* - [`prop()`](http://api.jquery.com/prop/)
|
|
1436
1435
|
* - [`remove()`](http://api.jquery.com/remove/)
|
|
1437
1436
|
* - [`removeData()`](http://api.jquery.com/removeData/)
|
|
1438
1437
|
* - [`replaceWith()`](http://api.jquery.com/replaceWith/)
|
|
@@ -1473,7 +1472,6 @@
|
|
|
1473
1472
|
|
|
1474
1473
|
JQLite.cache = CACHE;
|
|
1475
1474
|
|
|
1476
|
-
const EXPANDO = "ngId";
|
|
1477
1475
|
let jqId = 1;
|
|
1478
1476
|
|
|
1479
1477
|
/**
|
|
@@ -1568,13 +1566,6 @@
|
|
|
1568
1566
|
}
|
|
1569
1567
|
}
|
|
1570
1568
|
|
|
1571
|
-
function jqLiteHasData(node) {
|
|
1572
|
-
for (const key in JQLite.cache.get(node[EXPANDO])) {
|
|
1573
|
-
return true;
|
|
1574
|
-
}
|
|
1575
|
-
return false;
|
|
1576
|
-
}
|
|
1577
|
-
|
|
1578
1569
|
function jqLiteBuildFragment(html, context) {
|
|
1579
1570
|
let tmp;
|
|
1580
1571
|
let tag;
|
|
@@ -1970,7 +1961,6 @@
|
|
|
1970
1961
|
{
|
|
1971
1962
|
data: jqLiteData,
|
|
1972
1963
|
removeData: jqLiteRemoveData,
|
|
1973
|
-
hasData: jqLiteHasData,
|
|
1974
1964
|
cleanData: jqLiteCleanData,
|
|
1975
1965
|
},
|
|
1976
1966
|
(fn, name) => {
|
|
@@ -2043,15 +2033,6 @@
|
|
|
2043
2033
|
return ret === null ? undefined : ret;
|
|
2044
2034
|
}
|
|
2045
2035
|
},
|
|
2046
|
-
|
|
2047
|
-
prop(element, name, value) {
|
|
2048
|
-
if (isDefined(value)) {
|
|
2049
|
-
element[name] = value;
|
|
2050
|
-
} else {
|
|
2051
|
-
return element[name];
|
|
2052
|
-
}
|
|
2053
|
-
},
|
|
2054
|
-
|
|
2055
2036
|
text: (function () {
|
|
2056
2037
|
getText.$dv = "";
|
|
2057
2038
|
return getText;
|
|
@@ -6415,1104 +6396,6 @@
|
|
|
6415
6396
|
};
|
|
6416
6397
|
}
|
|
6417
6398
|
|
|
6418
|
-
/* ! VARIABLE/FUNCTION NAMING CONVENTIONS THAT APPLY TO THIS FILE!
|
|
6419
|
-
*
|
|
6420
|
-
* DOM-related variables:
|
|
6421
|
-
*
|
|
6422
|
-
* - "node" - DOM Node
|
|
6423
|
-
* - "element" - DOM Element or Node
|
|
6424
|
-
* - "$node" or "$element" - jqLite-wrapped node or element
|
|
6425
|
-
*
|
|
6426
|
-
*
|
|
6427
|
-
* Compiler related stuff:
|
|
6428
|
-
*
|
|
6429
|
-
* - "linkFn" - linking fn of a single directive
|
|
6430
|
-
* - "nodeLinkFn" - function that aggregates all linking fns for a particular node
|
|
6431
|
-
* - "childLinkFn" - function that aggregates all linking fns for child nodes of a particular node
|
|
6432
|
-
* - "compositeLinkFn" - function that aggregates all linking fns for a compilation root (nodeList)
|
|
6433
|
-
*/
|
|
6434
|
-
|
|
6435
|
-
/**
|
|
6436
|
-
* @ngdoc service
|
|
6437
|
-
* @name $compile
|
|
6438
|
-
* @kind function
|
|
6439
|
-
*
|
|
6440
|
-
* @description
|
|
6441
|
-
* Compiles an HTML string or DOM into a template and produces a template function, which
|
|
6442
|
-
* can then be used to link {@link ng.$rootScope.Scope `scope`} and the template together.
|
|
6443
|
-
*
|
|
6444
|
-
* The compilation is a process of walking the DOM tree and matching DOM elements to
|
|
6445
|
-
* {@link ng.$compileProvider#directive directives}.
|
|
6446
|
-
*
|
|
6447
|
-
* <div class="alert alert-warning">
|
|
6448
|
-
* **Note:** This document is an in-depth reference of all directive options.
|
|
6449
|
-
* For a gentle introduction to directives with examples of common use cases,
|
|
6450
|
-
* see the {@link guide/directive directive guide}.
|
|
6451
|
-
* </div>
|
|
6452
|
-
*
|
|
6453
|
-
* ## Comprehensive Directive API
|
|
6454
|
-
*
|
|
6455
|
-
* There are many different options for a directive.
|
|
6456
|
-
*
|
|
6457
|
-
* The difference resides in the return value of the factory function.
|
|
6458
|
-
* You can either return a {@link $compile#directive-definition-object Directive Definition Object (see below)}
|
|
6459
|
-
* that defines the directive properties, or just the `postLink` function (all other properties will have
|
|
6460
|
-
* the default values).
|
|
6461
|
-
*
|
|
6462
|
-
* <div class="alert alert-success">
|
|
6463
|
-
* **Best Practice:** It's recommended to use the "directive definition object" form.
|
|
6464
|
-
* </div>
|
|
6465
|
-
*
|
|
6466
|
-
* Here's an example directive declared with a Directive Definition Object:
|
|
6467
|
-
*
|
|
6468
|
-
* ```js
|
|
6469
|
-
* let myModule = angular.module(...);
|
|
6470
|
-
*
|
|
6471
|
-
* myModule.directive('directiveName', function factory(injectables) {
|
|
6472
|
-
* let directiveDefinitionObject = {
|
|
6473
|
-
* {@link $compile#-priority- priority}: 0,
|
|
6474
|
-
* {@link $compile#-template- template}: '<div></div>', // or // function(tElement, tAttrs) { ... },
|
|
6475
|
-
* // or
|
|
6476
|
-
* // {@link $compile#-templateurl- templateUrl}: 'directive.html', // or // function(tElement, tAttrs) { ... },
|
|
6477
|
-
* {@link $compile#-transclude- transclude}: false,
|
|
6478
|
-
* {@link $compile#-restrict- restrict}: 'A',
|
|
6479
|
-
* {@link $compile#-templatenamespace- templateNamespace}: 'html',
|
|
6480
|
-
* {@link $compile#-scope- scope}: false,
|
|
6481
|
-
* {@link $compile#-controller- controller}: function($scope, $element, $attrs, $transclude, otherInjectables) { ... },
|
|
6482
|
-
* {@link $compile#-controlleras- controllerAs}: 'stringIdentifier',
|
|
6483
|
-
* {@link $compile#-bindtocontroller- bindToController}: false,
|
|
6484
|
-
* {@link $compile#-require- require}: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'],
|
|
6485
|
-
* {@link $compile#-multielement- multiElement}: false,
|
|
6486
|
-
* {@link $compile#-compile- compile}: function compile(tElement, tAttrs, transclude) {
|
|
6487
|
-
* return {
|
|
6488
|
-
* {@link $compile#pre-linking-function pre}: function preLink(scope, iElement, iAttrs, controller) { ... },
|
|
6489
|
-
* {@link $compile#post-linking-function post}: function postLink(scope, iElement, iAttrs, controller) { ... }
|
|
6490
|
-
* }
|
|
6491
|
-
* // or
|
|
6492
|
-
* // return function postLink( ... ) { ... }
|
|
6493
|
-
* },
|
|
6494
|
-
* // or
|
|
6495
|
-
* // {@link $compile#-link- link}: {
|
|
6496
|
-
* // {@link $compile#pre-linking-function pre}: function preLink(scope, iElement, iAttrs, controller) { ... },
|
|
6497
|
-
* // {@link $compile#post-linking-function post}: function postLink(scope, iElement, iAttrs, controller) { ... }
|
|
6498
|
-
* // }
|
|
6499
|
-
* // or
|
|
6500
|
-
* // {@link $compile#-link- link}: function postLink( ... ) { ... }
|
|
6501
|
-
* };
|
|
6502
|
-
* return directiveDefinitionObject;
|
|
6503
|
-
* });
|
|
6504
|
-
* ```
|
|
6505
|
-
*
|
|
6506
|
-
* <div class="alert alert-warning">
|
|
6507
|
-
* **Note:** Any unspecified options will use the default value. You can see the default values below.
|
|
6508
|
-
* </div>
|
|
6509
|
-
*
|
|
6510
|
-
* Therefore the above can be simplified as:
|
|
6511
|
-
*
|
|
6512
|
-
* ```js
|
|
6513
|
-
* let myModule = angular.module(...);
|
|
6514
|
-
*
|
|
6515
|
-
* myModule.directive('directiveName', function factory(injectables) {
|
|
6516
|
-
* let directiveDefinitionObject = {
|
|
6517
|
-
* link: function postLink(scope, iElement, iAttrs) { ... }
|
|
6518
|
-
* };
|
|
6519
|
-
* return directiveDefinitionObject;
|
|
6520
|
-
* // or
|
|
6521
|
-
* // return function postLink(scope, iElement, iAttrs) { ... }
|
|
6522
|
-
* });
|
|
6523
|
-
* ```
|
|
6524
|
-
*
|
|
6525
|
-
* ### Life-cycle hooks
|
|
6526
|
-
* Directive controllers can provide the following methods that are called by AngularJS at points in the life-cycle of the
|
|
6527
|
-
* directive:
|
|
6528
|
-
* * `$onInit()` - Called on each controller after all the controllers on an element have been constructed and
|
|
6529
|
-
* had their bindings initialized (and before the pre & post linking functions for the directives on
|
|
6530
|
-
* this element). This is a good place to put initialization code for your controller.
|
|
6531
|
-
* * `$onChanges(changesObj)` - Called whenever one-way (`<`) or interpolation (`@`) bindings are updated. The
|
|
6532
|
-
* `changesObj` is a hash whose keys are the names of the bound properties that have changed, and the values are an
|
|
6533
|
-
* object of the form `{ currentValue, previousValue, isFirstChange() }`. Use this hook to trigger updates within a
|
|
6534
|
-
* component such as cloning the bound value to prevent accidental mutation of the outer value. Note that this will
|
|
6535
|
-
* also be called when your bindings are initialized.
|
|
6536
|
-
* * `$doCheck()` - Called on each turn of the digest cycle. Provides an opportunity to detect and act on
|
|
6537
|
-
* changes. Any actions that you wish to take in response to the changes that you detect must be
|
|
6538
|
-
* invoked from this hook; implementing this has no effect on when `$onChanges` is called. For example, this hook
|
|
6539
|
-
* could be useful if you wish to perform a deep equality check, or to check a Date object, changes to which would not
|
|
6540
|
-
* be detected by AngularJS's change detector and thus not trigger `$onChanges`. This hook is invoked with no arguments;
|
|
6541
|
-
* if detecting changes, you must store the previous value(s) for comparison to the current values.
|
|
6542
|
-
* * `$onDestroy()` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
|
|
6543
|
-
* external resources, watches and event handlers. Note that components have their `$onDestroy()` hooks called in
|
|
6544
|
-
* the same order as the `$scope.$broadcast` events are triggered, which is top down. This means that parent
|
|
6545
|
-
* components will have their `$onDestroy()` hook called before child components.
|
|
6546
|
-
* * `$postLink()` - Called after this controller's element and its children have been linked. Similar to the post-link
|
|
6547
|
-
* function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
|
|
6548
|
-
* Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
|
|
6549
|
-
* they are waiting for their template to load asynchronously and their own compilation and linking has been
|
|
6550
|
-
* suspended until that occurs.
|
|
6551
|
-
*
|
|
6552
|
-
* #### Comparison with life-cycle hooks in the new Angular
|
|
6553
|
-
* The new Angular also uses life-cycle hooks for its components. While the AngularJS life-cycle hooks are similar there are
|
|
6554
|
-
* some differences that you should be aware of, especially when it comes to moving your code from AngularJS to Angular:
|
|
6555
|
-
*
|
|
6556
|
-
* * AngularJS hooks are prefixed with `$`, such as `$onInit`. Angular hooks are prefixed with `ng`, such as `ngOnInit`.
|
|
6557
|
-
* * AngularJS hooks can be defined on the controller prototype or added to the controller inside its constructor.
|
|
6558
|
-
* In Angular you can only define hooks on the prototype of the Component class.
|
|
6559
|
-
* * Due to the differences in change-detection, you may get many more calls to `$doCheck` in AngularJS than you would to
|
|
6560
|
-
* `ngDoCheck` in Angular.
|
|
6561
|
-
* * Changes to the model inside `$doCheck` will trigger new turns of the digest loop, which will cause the changes to be
|
|
6562
|
-
* propagated throughout the application.
|
|
6563
|
-
* Angular does not allow the `ngDoCheck` hook to trigger a change outside of the component. It will either throw an
|
|
6564
|
-
* error or do nothing depending upon the state of `enableProdMode()`.
|
|
6565
|
-
*
|
|
6566
|
-
* #### Life-cycle hook examples
|
|
6567
|
-
*
|
|
6568
|
-
* This example shows how you can check for mutations to a Date object even though the identity of the object
|
|
6569
|
-
* has not changed.
|
|
6570
|
-
*
|
|
6571
|
-
* <example name="doCheckDateExample" module="do-check-module">
|
|
6572
|
-
* <file name="app.js">
|
|
6573
|
-
* angular.module('do-check-module', [])
|
|
6574
|
-
* .component('app', {
|
|
6575
|
-
* template:
|
|
6576
|
-
* 'Month: <input ng-model="$ctrl.month" ng-change="$ctrl.updateDate()">' +
|
|
6577
|
-
* 'Date: {{ $ctrl.date }}' +
|
|
6578
|
-
* '<test date="$ctrl.date"></test>',
|
|
6579
|
-
* controller: function() {
|
|
6580
|
-
* this.date = new Date();
|
|
6581
|
-
* this.month = this.date.getMonth();
|
|
6582
|
-
* this.updateDate = function() {
|
|
6583
|
-
* this.date.setMonth(this.month);
|
|
6584
|
-
* };
|
|
6585
|
-
* }
|
|
6586
|
-
* })
|
|
6587
|
-
* .component('test', {
|
|
6588
|
-
* bindings: { date: '<' },
|
|
6589
|
-
* template:
|
|
6590
|
-
* '<pre>{{ $ctrl.log | json }}</pre>',
|
|
6591
|
-
* controller: function() {
|
|
6592
|
-
* let previousValue;
|
|
6593
|
-
* this.log = [];
|
|
6594
|
-
* this.$doCheck = function() {
|
|
6595
|
-
* let currentValue = this.date && this.date.valueOf();
|
|
6596
|
-
* if (previousValue !== currentValue) {
|
|
6597
|
-
* this.log.push('doCheck: date mutated: ' + this.date);
|
|
6598
|
-
* previousValue = currentValue;
|
|
6599
|
-
* }
|
|
6600
|
-
* };
|
|
6601
|
-
* }
|
|
6602
|
-
* });
|
|
6603
|
-
* </file>
|
|
6604
|
-
* <file name="index.html">
|
|
6605
|
-
* <app></app>
|
|
6606
|
-
* </file>
|
|
6607
|
-
* </example>
|
|
6608
|
-
*
|
|
6609
|
-
* This example show how you might use `$doCheck` to trigger changes in your component's inputs even if the
|
|
6610
|
-
* actual identity of the component doesn't change. (Be aware that cloning and deep equality checks on large
|
|
6611
|
-
* arrays or objects can have a negative impact on your application performance.)
|
|
6612
|
-
*
|
|
6613
|
-
* <example name="doCheckArrayExample" module="do-check-module">
|
|
6614
|
-
* <file name="index.html">
|
|
6615
|
-
* <div ng-init="items = []">
|
|
6616
|
-
* <button ng-click="items.push(items.length)">Add Item</button>
|
|
6617
|
-
* <button ng-click="items = []">Reset Items</button>
|
|
6618
|
-
* <pre>{{ items }}</pre>
|
|
6619
|
-
* <test items="items"></test>
|
|
6620
|
-
* </div>
|
|
6621
|
-
* </file>
|
|
6622
|
-
* <file name="app.js">
|
|
6623
|
-
* angular.module('do-check-module', [])
|
|
6624
|
-
* .component('test', {
|
|
6625
|
-
* bindings: { items: '<' },
|
|
6626
|
-
* template:
|
|
6627
|
-
* '<pre>{{ $ctrl.log | json }}</pre>',
|
|
6628
|
-
* controller: function() {
|
|
6629
|
-
* this.log = [];
|
|
6630
|
-
*
|
|
6631
|
-
* this.$doCheck = function() {
|
|
6632
|
-
* if (this.items_ref !== this.items) {
|
|
6633
|
-
* this.log.push('doCheck: items changed');
|
|
6634
|
-
* this.items_ref = this.items;
|
|
6635
|
-
* }
|
|
6636
|
-
* if (!angular.equals(this.items_clone, this.items)) {
|
|
6637
|
-
* this.log.push('doCheck: items mutated');
|
|
6638
|
-
* this.items_clone = structuredClone(this.items);
|
|
6639
|
-
* }
|
|
6640
|
-
* };
|
|
6641
|
-
* }
|
|
6642
|
-
* });
|
|
6643
|
-
* </file>
|
|
6644
|
-
* </example>
|
|
6645
|
-
*
|
|
6646
|
-
*
|
|
6647
|
-
* ### Directive Definition Object
|
|
6648
|
-
*
|
|
6649
|
-
* The directive definition object provides instructions to the {@link ng.$compile
|
|
6650
|
-
* compiler}. The attributes are:
|
|
6651
|
-
*
|
|
6652
|
-
* #### `multiElement`
|
|
6653
|
-
* When this property is set to true (default is `false`), the HTML compiler will collect DOM nodes between
|
|
6654
|
-
* nodes with the attributes `directive-name-start` and `directive-name-end`, and group them
|
|
6655
|
-
* together as the directive elements. It is recommended that this feature be used on directives
|
|
6656
|
-
* which are not strictly behavioral (such as {@link ngClick}), and which
|
|
6657
|
-
* do not manipulate or replace child nodes (such as {@link ngInclude}).
|
|
6658
|
-
*
|
|
6659
|
-
* #### `priority`
|
|
6660
|
-
* When there are multiple directives defined on a single DOM element, sometimes it
|
|
6661
|
-
* is necessary to specify the order in which the directives are applied. The `priority` is used
|
|
6662
|
-
* to sort the directives before their `compile` functions get called. Priority is defined as a
|
|
6663
|
-
* number. Directives with greater numerical `priority` are compiled first. Pre-link functions
|
|
6664
|
-
* are also run in priority order, but post-link functions are run in reverse order. The order
|
|
6665
|
-
* of directives with the same priority is undefined. The default priority is `0`.
|
|
6666
|
-
*
|
|
6667
|
-
* #### `terminal`
|
|
6668
|
-
* If set to true then the current `priority` will be the last set of directives
|
|
6669
|
-
* which will execute (any directives at the current priority will still execute
|
|
6670
|
-
* as the order of execution on same `priority` is undefined). Note that expressions
|
|
6671
|
-
* and other directives used in the directive's template will also be excluded from execution.
|
|
6672
|
-
*
|
|
6673
|
-
* #### `scope`
|
|
6674
|
-
* The scope property can be `false`, `true`, or an object:
|
|
6675
|
-
*
|
|
6676
|
-
* * **`false` (default):** No scope will be created for the directive. The directive will use its
|
|
6677
|
-
* parent's scope.
|
|
6678
|
-
*
|
|
6679
|
-
* * **`true`:** A new child scope that prototypically inherits from its parent will be created for
|
|
6680
|
-
* the directive's element. If multiple directives on the same element request a new scope,
|
|
6681
|
-
* only one new scope is created.
|
|
6682
|
-
*
|
|
6683
|
-
* * **`{...}` (an object hash):** A new "isolate" scope is created for the directive's template.
|
|
6684
|
-
* The 'isolate' scope differs from normal scope in that it does not prototypically
|
|
6685
|
-
* inherit from its parent scope. This is useful when creating reusable components, which should not
|
|
6686
|
-
* accidentally read or modify data in the parent scope. Note that an isolate scope
|
|
6687
|
-
* directive without a `template` or `templateUrl` will not apply the isolate scope
|
|
6688
|
-
* to its children elements.
|
|
6689
|
-
*
|
|
6690
|
-
* The 'isolate' scope object hash defines a set of local scope properties derived from attributes on the
|
|
6691
|
-
* directive's element. These local properties are useful for aliasing values for templates. The keys in
|
|
6692
|
-
* the object hash map to the name of the property on the isolate scope; the values define how the property
|
|
6693
|
-
* is bound to the parent scope, via matching attributes on the directive's element:
|
|
6694
|
-
*
|
|
6695
|
-
* * `@` or `@attr` - bind a local scope property to the value of DOM attribute. The result is
|
|
6696
|
-
* always a string since DOM attributes are strings. If no `attr` name is specified then the
|
|
6697
|
-
* attribute name is assumed to be the same as the local name. Given `<my-component
|
|
6698
|
-
* my-attr="hello {{name}}">` and the isolate scope definition `scope: { localName:'@myAttr' }`,
|
|
6699
|
-
* the directive's scope property `localName` will reflect the interpolated value of `hello
|
|
6700
|
-
* {{name}}`. As the `name` attribute changes so will the `localName` property on the directive's
|
|
6701
|
-
* scope. The `name` is read from the parent scope (not the directive's scope).
|
|
6702
|
-
*
|
|
6703
|
-
* * `=` or `=attr` - set up a bidirectional binding between a local scope property and an expression
|
|
6704
|
-
* passed via the attribute `attr`. The expression is evaluated in the context of the parent scope.
|
|
6705
|
-
* If no `attr` name is specified then the attribute name is assumed to be the same as the local
|
|
6706
|
-
* name. Given `<my-component my-attr="parentModel">` and the isolate scope definition `scope: {
|
|
6707
|
-
* localModel: '=myAttr' }`, the property `localModel` on the directive's scope will reflect the
|
|
6708
|
-
* value of `parentModel` on the parent scope. Changes to `parentModel` will be reflected in
|
|
6709
|
-
* `localModel` and vice versa. If the binding expression is non-assignable, or if the attribute
|
|
6710
|
-
* isn't optional and doesn't exist, an exception
|
|
6711
|
-
* ({@link error/$compile/nonassign `$compile:nonassign`}) will be thrown upon discovering changes
|
|
6712
|
-
* to the local value, since it will be impossible to sync them back to the parent scope.
|
|
6713
|
-
*
|
|
6714
|
-
* By default, the {@link ng.$rootScope.Scope#$watch `$watch`}
|
|
6715
|
-
* method is used for tracking changes, and the equality check is based on object identity.
|
|
6716
|
-
* However, if an object literal or an array literal is passed as the binding expression, the
|
|
6717
|
-
* equality check is done by value (using the {@link angular.equals} function). It's also possible
|
|
6718
|
-
* to watch the evaluated value shallowly with {@link ng.$rootScope.Scope#$watchCollection
|
|
6719
|
-
* `$watchCollection`}: use `=*` or `=*attr`
|
|
6720
|
-
*
|
|
6721
|
-
* * `<` or `<attr` - set up a one-way (one-directional) binding between a local scope property and an
|
|
6722
|
-
* expression passed via the attribute `attr`. The expression is evaluated in the context of the
|
|
6723
|
-
* parent scope. If no `attr` name is specified then the attribute name is assumed to be the same as the
|
|
6724
|
-
* local name.
|
|
6725
|
-
*
|
|
6726
|
-
* For example, given `<my-component my-attr="parentModel">` and directive definition of
|
|
6727
|
-
* `scope: { localModel:'<myAttr' }`, then the isolated scope property `localModel` will reflect the
|
|
6728
|
-
* value of `parentModel` on the parent scope. Any changes to `parentModel` will be reflected
|
|
6729
|
-
* in `localModel`, but changes in `localModel` will not reflect in `parentModel`. There are however
|
|
6730
|
-
* two caveats:
|
|
6731
|
-
* 1. one-way binding does not copy the value from the parent to the isolate scope, it simply
|
|
6732
|
-
* sets the same value. That means if your bound value is an object, changes to its properties
|
|
6733
|
-
* in the isolated scope will be reflected in the parent scope (because both reference the same object).
|
|
6734
|
-
* 2. one-way binding watches changes to the **identity** of the parent value. That means the
|
|
6735
|
-
* {@link ng.$rootScope.Scope#$watch `$watch`} on the parent value only fires if the reference
|
|
6736
|
-
* to the value has changed. In most cases, this should not be of concern, but can be important
|
|
6737
|
-
* to know if you one-way bind to an object, and then replace that object in the isolated scope.
|
|
6738
|
-
* If you now change a property of the object in your parent scope, the change will not be
|
|
6739
|
-
* propagated to the isolated scope, because the identity of the object on the parent scope
|
|
6740
|
-
* has not changed. Instead you must assign a new object.
|
|
6741
|
-
*
|
|
6742
|
-
* One-way binding is useful if you do not plan to propagate changes to your isolated scope bindings
|
|
6743
|
-
* back to the parent. However, it does not make this completely impossible.
|
|
6744
|
-
*
|
|
6745
|
-
* By default, the {@link ng.$rootScope.Scope#$watch `$watch`}
|
|
6746
|
-
* method is used for tracking changes, and the equality check is based on object identity.
|
|
6747
|
-
* It's also possible to watch the evaluated value shallowly with
|
|
6748
|
-
* {@link ng.$rootScope.Scope#$watchCollection `$watchCollection`}: use `<*` or `<*attr`
|
|
6749
|
-
*
|
|
6750
|
-
* * `&` or `&attr` - provides a way to execute an expression in the context of the parent scope. If
|
|
6751
|
-
* no `attr` name is specified then the attribute name is assumed to be the same as the local name.
|
|
6752
|
-
* Given `<my-component my-attr="count = count + value">` and the isolate scope definition `scope: {
|
|
6753
|
-
* localFn:'&myAttr' }`, the isolate scope property `localFn` will point to a function wrapper for
|
|
6754
|
-
* the `count = count + value` expression. Often it's desirable to pass data from the isolated scope
|
|
6755
|
-
* via an expression to the parent scope. This can be done by passing a map of local variable names
|
|
6756
|
-
* and values into the expression wrapper fn. For example, if the expression is `increment(amount)`
|
|
6757
|
-
* then we can specify the amount value by calling the `localFn` as `localFn({amount: 22})`.
|
|
6758
|
-
*
|
|
6759
|
-
* All 4 kinds of bindings (`@`, `=`, `<`, and `&`) can be made optional by adding `?` to the expression.
|
|
6760
|
-
* The marker must come after the mode and before the attribute name.
|
|
6761
|
-
* See the {@link error/$compile/iscp Invalid Isolate Scope Definition error} for definition examples.
|
|
6762
|
-
* This is useful to refine the interface directives provide.
|
|
6763
|
-
* One subtle difference between optional and non-optional happens **when the binding attribute is not
|
|
6764
|
-
* set**:
|
|
6765
|
-
* - the binding is optional: the property will not be defined
|
|
6766
|
-
* - the binding is not optional: the property is defined
|
|
6767
|
-
*
|
|
6768
|
-
* ```js
|
|
6769
|
-
*app.directive('testDir', function() {
|
|
6770
|
-
return {
|
|
6771
|
-
scope: {
|
|
6772
|
-
notoptional: '=',
|
|
6773
|
-
optional: '=?',
|
|
6774
|
-
},
|
|
6775
|
-
bindToController: true,
|
|
6776
|
-
controller: function() {
|
|
6777
|
-
this.$onInit = function() {
|
|
6778
|
-
console.log(this.hasOwnProperty('notoptional')) // true
|
|
6779
|
-
console.log(this.hasOwnProperty('optional')) // false
|
|
6780
|
-
}
|
|
6781
|
-
}
|
|
6782
|
-
}
|
|
6783
|
-
})
|
|
6784
|
-
*```
|
|
6785
|
-
*
|
|
6786
|
-
*
|
|
6787
|
-
* ##### Combining directives with different scope defintions
|
|
6788
|
-
*
|
|
6789
|
-
* In general it's possible to apply more than one directive to one element, but there might be limitations
|
|
6790
|
-
* depending on the type of scope required by the directives. The following points will help explain these limitations.
|
|
6791
|
-
* For simplicity only two directives are taken into account, but it is also applicable for several directives:
|
|
6792
|
-
*
|
|
6793
|
-
* * **no scope** + **no scope** => Two directives which don't require their own scope will use their parent's scope
|
|
6794
|
-
* * **child scope** + **no scope** => Both directives will share one single child scope
|
|
6795
|
-
* * **child scope** + **child scope** => Both directives will share one single child scope
|
|
6796
|
-
* * **isolated scope** + **no scope** => The isolated directive will use it's own created isolated scope. The other directive will use
|
|
6797
|
-
* its parent's scope
|
|
6798
|
-
* * **isolated scope** + **child scope** => **Won't work!** Only one scope can be related to one element. Therefore these directives cannot
|
|
6799
|
-
* be applied to the same element.
|
|
6800
|
-
* * **isolated scope** + **isolated scope** => **Won't work!** Only one scope can be related to one element. Therefore these directives
|
|
6801
|
-
* cannot be applied to the same element.
|
|
6802
|
-
*
|
|
6803
|
-
*
|
|
6804
|
-
* #### `bindToController`
|
|
6805
|
-
* This property is used to bind scope properties directly to the controller. It can be either
|
|
6806
|
-
* `true` or an object hash with the same format as the `scope` property.
|
|
6807
|
-
*
|
|
6808
|
-
* When an isolate scope is used for a directive (see above), `bindToController: true` will
|
|
6809
|
-
* allow a component to have its properties bound to the controller, rather than to scope.
|
|
6810
|
-
*
|
|
6811
|
-
* After the controller is instantiated, the initial values of the isolate scope bindings will be bound to the controller
|
|
6812
|
-
* properties. You can access these bindings once they have been initialized by providing a controller method called
|
|
6813
|
-
* `$onInit`, which is called after all the controllers on an element have been constructed and had their bindings
|
|
6814
|
-
* initialized.
|
|
6815
|
-
*
|
|
6816
|
-
* It is also possible to set `bindToController` to an object hash with the same format as the `scope` property.
|
|
6817
|
-
* This will set up the scope bindings to the controller directly. Note that `scope` can still be used
|
|
6818
|
-
* to define which kind of scope is created. By default, no scope is created. Use `scope: {}` to create an isolate
|
|
6819
|
-
* scope (useful for component directives).
|
|
6820
|
-
*
|
|
6821
|
-
* If both `bindToController` and `scope` are defined and have object hashes, `bindToController` overrides `scope`.
|
|
6822
|
-
*
|
|
6823
|
-
*
|
|
6824
|
-
* #### `controller`
|
|
6825
|
-
* Controller constructor function. The controller is instantiated before the
|
|
6826
|
-
* pre-linking phase and can be accessed by other directives (see
|
|
6827
|
-
* `require` attribute). This allows the directives to communicate with each other and augment
|
|
6828
|
-
* each other's behavior. The controller is injectable (and supports bracket notation) with the following locals:
|
|
6829
|
-
*
|
|
6830
|
-
* * `$scope` - Current scope associated with the element
|
|
6831
|
-
* * `$element` - Current element
|
|
6832
|
-
* * `$attrs` - Current attributes object for the element
|
|
6833
|
-
* * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope:
|
|
6834
|
-
* `function([scope], cloneLinkingFn, futureParentElement, slotName)`:
|
|
6835
|
-
* * `scope`: (optional) override the scope.
|
|
6836
|
-
* * `cloneLinkingFn`: (optional) argument to create clones of the original transcluded content.
|
|
6837
|
-
* * `futureParentElement` (optional):
|
|
6838
|
-
* * defines the parent to which the `cloneLinkingFn` will add the cloned elements.
|
|
6839
|
-
* * default: `$element.parent()` resp. `$element` for `transclude:'element'` resp. `transclude:true`.
|
|
6840
|
-
* * only needed for transcludes that are allowed to contain non html elements (e.g. SVG elements)
|
|
6841
|
-
* and when the `cloneLinkingFn` is passed,
|
|
6842
|
-
* as those elements need to created and cloned in a special way when they are defined outside their
|
|
6843
|
-
* usual containers (e.g. like `<svg>`).
|
|
6844
|
-
* * See also the `directive.templateNamespace` property.
|
|
6845
|
-
* * `slotName`: (optional) the name of the slot to transclude. If falsy (e.g. `null`, `undefined` or `''`)
|
|
6846
|
-
* then the default transclusion is provided.
|
|
6847
|
-
* The `$transclude` function also has a method on it, `$transclude.isSlotFilled(slotName)`, which returns
|
|
6848
|
-
* `true` if the specified slot contains content (i.e. one or more DOM nodes).
|
|
6849
|
-
*
|
|
6850
|
-
* #### `require`
|
|
6851
|
-
* Require another directive and inject its controller as the fourth argument to the linking function. The
|
|
6852
|
-
* `require` property can be a string, an array or an object:
|
|
6853
|
-
* * a **string** containing the name of the directive to pass to the linking function
|
|
6854
|
-
* * an **array** containing the names of directives to pass to the linking function. The argument passed to the
|
|
6855
|
-
* linking function will be an array of controllers in the same order as the names in the `require` property
|
|
6856
|
-
* * an **object** whose property values are the names of the directives to pass to the linking function. The argument
|
|
6857
|
-
* passed to the linking function will also be an object with matching keys, whose values will hold the corresponding
|
|
6858
|
-
* controllers.
|
|
6859
|
-
*
|
|
6860
|
-
* If the `require` property is an object and `bindToController` is truthy, then the required controllers are
|
|
6861
|
-
* bound to the controller using the keys of the `require` property. This binding occurs after all the controllers
|
|
6862
|
-
* have been constructed but before `$onInit` is called.
|
|
6863
|
-
* If the name of the required controller is the same as the local name (the key), the name can be
|
|
6864
|
-
* omitted. For example, `{parentDir: '^^'}` is equivalent to `{parentDir: '^^parentDir'}`.
|
|
6865
|
-
* See the {@link $compileProvider#component} helper for an example of how this can be used.
|
|
6866
|
-
* If no such required directive(s) can be found, or if the directive does not have a controller, then an error is
|
|
6867
|
-
* raised (unless no link function is specified and the required controllers are not being bound to the directive
|
|
6868
|
-
* controller, in which case error checking is skipped). The name can be prefixed with:
|
|
6869
|
-
*
|
|
6870
|
-
* * (no prefix) - Locate the required controller on the current element. Throw an error if not found.
|
|
6871
|
-
* * `?` - Attempt to locate the required controller or pass `null` to the `link` fn if not found.
|
|
6872
|
-
* * `^` - Locate the required controller by searching the element and its parents. Throw an error if not found.
|
|
6873
|
-
* * `^^` - Locate the required controller by searching the element's parents. Throw an error if not found.
|
|
6874
|
-
* * `?^` - Attempt to locate the required controller by searching the element and its parents or pass
|
|
6875
|
-
* `null` to the `link` fn if not found.
|
|
6876
|
-
* * `?^^` - Attempt to locate the required controller by searching the element's parents, or pass
|
|
6877
|
-
* `null` to the `link` fn if not found.
|
|
6878
|
-
*
|
|
6879
|
-
*
|
|
6880
|
-
* #### `controllerAs`
|
|
6881
|
-
* Identifier name for a reference to the controller in the directive's scope.
|
|
6882
|
-
* This allows the controller to be referenced from the directive template. This is especially
|
|
6883
|
-
* useful when a directive is used as component, i.e. with an `isolate` scope. It's also possible
|
|
6884
|
-
* to use it in a directive without an `isolate` / `new` scope, but you need to be aware that the
|
|
6885
|
-
* `controllerAs` reference might overwrite a property that already exists on the parent scope.
|
|
6886
|
-
*
|
|
6887
|
-
*
|
|
6888
|
-
* #### `restrict`
|
|
6889
|
-
* String of subset of `EACM` which restricts the directive to a specific directive
|
|
6890
|
-
* declaration style. If omitted, the defaults (elements and attributes) are used.
|
|
6891
|
-
*
|
|
6892
|
-
* * `E` - Element name (default): `<my-directive></my-directive>`
|
|
6893
|
-
* * `A` - Attribute (default): `<div my-directive="exp"></div>`
|
|
6894
|
-
* * `C` - Class: `<div class="my-directive: exp;"></div>`
|
|
6895
|
-
* * `M` - Comment: `<!-- directive: my-directive exp -->`
|
|
6896
|
-
*
|
|
6897
|
-
*
|
|
6898
|
-
* #### `templateNamespace`
|
|
6899
|
-
* String representing the document type used by the markup in the template.
|
|
6900
|
-
* AngularJS needs this information as those elements need to be created and cloned
|
|
6901
|
-
* in a special way when they are defined outside their usual containers like `<svg>` and `<math>`.
|
|
6902
|
-
*
|
|
6903
|
-
* * `html` - All root nodes in the template are HTML. Root nodes may also be
|
|
6904
|
-
* top-level elements such as `<svg>` or `<math>`.
|
|
6905
|
-
* * `svg` - The root nodes in the template are SVG elements (excluding `<math>`).
|
|
6906
|
-
* * `math` - The root nodes in the template are MathML elements (excluding `<svg>`).
|
|
6907
|
-
*
|
|
6908
|
-
* If no `templateNamespace` is specified, then the namespace is considered to be `html`.
|
|
6909
|
-
*
|
|
6910
|
-
* #### `template`
|
|
6911
|
-
* HTML markup that may:
|
|
6912
|
-
* * Replace the contents of the directive's element (default).
|
|
6913
|
-
* * Replace the directive's element itself (if `replace` is true - DEPRECATED).
|
|
6914
|
-
* * Wrap the contents of the directive's element (if `transclude` is true).
|
|
6915
|
-
*
|
|
6916
|
-
* Value may be:
|
|
6917
|
-
*
|
|
6918
|
-
* * A string. For example `<div red-on-hover>{{delete_str}}</div>`.
|
|
6919
|
-
* * A function which takes two arguments `tElement` and `tAttrs` (described in the `compile`
|
|
6920
|
-
* function api below) and returns a string value.
|
|
6921
|
-
*
|
|
6922
|
-
*
|
|
6923
|
-
* #### `templateUrl`
|
|
6924
|
-
* This is similar to `template` but the template is loaded from the specified URL, asynchronously.
|
|
6925
|
-
*
|
|
6926
|
-
* Because template loading is asynchronous the compiler will suspend compilation of directives on that element
|
|
6927
|
-
* for later when the template has been resolved. In the meantime it will continue to compile and link
|
|
6928
|
-
* sibling and parent elements as though this element had not contained any directives.
|
|
6929
|
-
*
|
|
6930
|
-
* The compiler does not suspend the entire compilation to wait for templates to be loaded because this
|
|
6931
|
-
* would result in the whole app "stalling" until all templates are loaded asynchronously - even in the
|
|
6932
|
-
* case when only one deeply nested directive has `templateUrl`.
|
|
6933
|
-
*
|
|
6934
|
-
* Template loading is asynchronous even if the template has been preloaded into the {@link $templateCache}.
|
|
6935
|
-
*
|
|
6936
|
-
* You can specify `templateUrl` as a string representing the URL or as a function which takes two
|
|
6937
|
-
* arguments `tElement` and `tAttrs` (described in the `compile` function api below) and returns
|
|
6938
|
-
* a string value representing the url. In either case, the template URL is passed through {@link
|
|
6939
|
-
* $sce#getTrustedResourceUrl $sce.getTrustedResourceUrl}.
|
|
6940
|
-
*
|
|
6941
|
-
*
|
|
6942
|
-
* #### `replace`
|
|
6943
|
-
* <div class="alert alert-danger">
|
|
6944
|
-
* **Note:** `replace` is deprecated in AngularJS and has been removed in the new Angular (v2+).
|
|
6945
|
-
* </div>
|
|
6946
|
-
*
|
|
6947
|
-
* Specifies what the template should replace. Defaults to `false`.
|
|
6948
|
-
*
|
|
6949
|
-
* * `true` - the template will replace the directive's element.
|
|
6950
|
-
* * `false` - the template will replace the contents of the directive's element.
|
|
6951
|
-
*
|
|
6952
|
-
* The replacement process migrates all of the attributes / classes from the old element to the new
|
|
6953
|
-
* one. See the {@link guide/directive#template-expanding-directive
|
|
6954
|
-
* Directives Guide} for an example.
|
|
6955
|
-
*
|
|
6956
|
-
* There are very few scenarios where element replacement is required for the application function,
|
|
6957
|
-
* the main one being reusable custom components that are used within SVG contexts
|
|
6958
|
-
* (because SVG doesn't work with custom elements in the DOM tree).
|
|
6959
|
-
*
|
|
6960
|
-
* #### `transclude`
|
|
6961
|
-
* Extract the contents of the element where the directive appears and make it available to the directive.
|
|
6962
|
-
* The contents are compiled and provided to the directive as a **transclusion function**. See the
|
|
6963
|
-
* {@link $compile#transclusion Transclusion} section below.
|
|
6964
|
-
*
|
|
6965
|
-
*
|
|
6966
|
-
* #### `compile`
|
|
6967
|
-
*
|
|
6968
|
-
* ```js
|
|
6969
|
-
* function compile(tElement, tAttrs, transclude) { ... }
|
|
6970
|
-
* ```
|
|
6971
|
-
*
|
|
6972
|
-
* The compile function deals with transforming the template DOM. Since most directives do not do
|
|
6973
|
-
* template transformation, it is not used often. The compile function takes the following arguments:
|
|
6974
|
-
*
|
|
6975
|
-
* * `tElement` - template element - The element where the directive has been declared. It is
|
|
6976
|
-
* safe to do template transformation on the element and child elements only.
|
|
6977
|
-
*
|
|
6978
|
-
* * `tAttrs` - template attributes - Normalized list of attributes declared on this element shared
|
|
6979
|
-
* between all directive compile functions.
|
|
6980
|
-
*
|
|
6981
|
-
* * `transclude` - [*DEPRECATED*!] A transclude linking function: `function(scope, cloneLinkingFn)`
|
|
6982
|
-
*
|
|
6983
|
-
* <div class="alert alert-warning">
|
|
6984
|
-
* **Note:** The template instance and the link instance may be different objects if the template has
|
|
6985
|
-
* been cloned. For this reason it is **not** safe to do anything other than DOM transformations that
|
|
6986
|
-
* apply to all cloned DOM nodes within the compile function. Specifically, DOM listener registration
|
|
6987
|
-
* should be done in a linking function rather than in a compile function.
|
|
6988
|
-
* </div>
|
|
6989
|
-
|
|
6990
|
-
* <div class="alert alert-warning">
|
|
6991
|
-
* **Note:** The compile function cannot handle directives that recursively use themselves in their
|
|
6992
|
-
* own templates or compile functions. Compiling these directives results in an infinite loop and
|
|
6993
|
-
* stack overflow errors.
|
|
6994
|
-
*
|
|
6995
|
-
* This can be avoided by manually using `$compile` in the postLink function to imperatively compile
|
|
6996
|
-
* a directive's template instead of relying on automatic template compilation via `template` or
|
|
6997
|
-
* `templateUrl` declaration or manual compilation inside the compile function.
|
|
6998
|
-
* </div>
|
|
6999
|
-
*
|
|
7000
|
-
* <div class="alert alert-danger">
|
|
7001
|
-
* **Note:** The `transclude` function that is passed to the compile function is deprecated, as it
|
|
7002
|
-
* e.g. does not know about the right outer scope. Please use the transclude function that is passed
|
|
7003
|
-
* to the link function instead.
|
|
7004
|
-
* </div>
|
|
7005
|
-
|
|
7006
|
-
* A compile function can have a return value which can be either a function or an object.
|
|
7007
|
-
*
|
|
7008
|
-
* * returning a (post-link) function - is equivalent to registering the linking function via the
|
|
7009
|
-
* `link` property of the config object when the compile function is empty.
|
|
7010
|
-
*
|
|
7011
|
-
* * returning an object with function(s) registered via `pre` and `post` properties - allows you to
|
|
7012
|
-
* control when a linking function should be called during the linking phase. See info about
|
|
7013
|
-
* pre-linking and post-linking functions below.
|
|
7014
|
-
*
|
|
7015
|
-
*
|
|
7016
|
-
* #### `link`
|
|
7017
|
-
* This property is used only if the `compile` property is not defined.
|
|
7018
|
-
*
|
|
7019
|
-
* ```js
|
|
7020
|
-
* function link(scope, iElement, iAttrs, controller, transcludeFn) { ... }
|
|
7021
|
-
* ```
|
|
7022
|
-
*
|
|
7023
|
-
* The link function is responsible for registering DOM listeners as well as updating the DOM. It is
|
|
7024
|
-
* executed after the template has been cloned. This is where most of the directive logic will be
|
|
7025
|
-
* put.
|
|
7026
|
-
*
|
|
7027
|
-
* * `scope` - {@link ng.$rootScope.Scope Scope} - The scope to be used by the
|
|
7028
|
-
* directive for registering {@link ng.$rootScope.Scope#$watch watches}.
|
|
7029
|
-
*
|
|
7030
|
-
* * `iElement` - instance element - The element where the directive is to be used. It is safe to
|
|
7031
|
-
* manipulate the children of the element only in `postLink` function since the children have
|
|
7032
|
-
* already been linked.
|
|
7033
|
-
*
|
|
7034
|
-
* * `iAttrs` - instance attributes - Normalized list of attributes declared on this element shared
|
|
7035
|
-
* between all directive linking functions.
|
|
7036
|
-
*
|
|
7037
|
-
* * `controller` - the directive's required controller instance(s) - Instances are shared
|
|
7038
|
-
* among all directives, which allows the directives to use the controllers as a communication
|
|
7039
|
-
* channel. The exact value depends on the directive's `require` property:
|
|
7040
|
-
* * no controller(s) required: the directive's own controller, or `undefined` if it doesn't have one
|
|
7041
|
-
* * `string`: the controller instance
|
|
7042
|
-
* * `array`: array of controller instances
|
|
7043
|
-
*
|
|
7044
|
-
* If a required controller cannot be found, and it is optional, the instance is `null`,
|
|
7045
|
-
* otherwise the {@link error:$compile:ctreq Missing Required Controller} error is thrown.
|
|
7046
|
-
*
|
|
7047
|
-
* Note that you can also require the directive's own controller - it will be made available like
|
|
7048
|
-
* any other controller.
|
|
7049
|
-
*
|
|
7050
|
-
* * `transcludeFn` - A transclude linking function pre-bound to the correct transclusion scope.
|
|
7051
|
-
* This is the same as the `$transclude` parameter of directive controllers,
|
|
7052
|
-
* see {@link ng.$compile#-controller- the controller section for details}.
|
|
7053
|
-
* `function([scope], cloneLinkingFn, futureParentElement)`.
|
|
7054
|
-
*
|
|
7055
|
-
* #### Pre-linking function
|
|
7056
|
-
*
|
|
7057
|
-
* Executed before the child elements are linked. Not safe to do DOM transformation since the
|
|
7058
|
-
* compiler linking function will fail to locate the correct elements for linking.
|
|
7059
|
-
*
|
|
7060
|
-
* #### Post-linking function
|
|
7061
|
-
*
|
|
7062
|
-
* Executed after the child elements are linked.
|
|
7063
|
-
*
|
|
7064
|
-
* Note that child elements that contain `templateUrl` directives will not have been compiled
|
|
7065
|
-
* and linked since they are waiting for their template to load asynchronously and their own
|
|
7066
|
-
* compilation and linking has been suspended until that occurs.
|
|
7067
|
-
*
|
|
7068
|
-
* It is safe to do DOM transformation in the post-linking function on elements that are not waiting
|
|
7069
|
-
* for their async templates to be resolved.
|
|
7070
|
-
*
|
|
7071
|
-
*
|
|
7072
|
-
* ### Transclusion
|
|
7073
|
-
*
|
|
7074
|
-
* Transclusion is the process of extracting a collection of DOM elements from one part of the DOM and
|
|
7075
|
-
* copying them to another part of the DOM, while maintaining their connection to the original AngularJS
|
|
7076
|
-
* scope from where they were taken.
|
|
7077
|
-
*
|
|
7078
|
-
* Transclusion is used (often with {@link ngTransclude}) to insert the
|
|
7079
|
-
* original contents of a directive's element into a specified place in the template of the directive.
|
|
7080
|
-
* The benefit of transclusion, over simply moving the DOM elements manually, is that the transcluded
|
|
7081
|
-
* content has access to the properties on the scope from which it was taken, even if the directive
|
|
7082
|
-
* has isolated scope.
|
|
7083
|
-
* See the {@link guide/directive#creating-a-directive-that-wraps-other-elements Directives Guide}.
|
|
7084
|
-
*
|
|
7085
|
-
* This makes it possible for the widget to have private state for its template, while the transcluded
|
|
7086
|
-
* content has access to its originating scope.
|
|
7087
|
-
*
|
|
7088
|
-
* <div class="alert alert-warning">
|
|
7089
|
-
* **Note:** When testing an element transclude directive you must not place the directive at the root of the
|
|
7090
|
-
* DOM fragment that is being compiled. See {@link guide/unit-testing#testing-transclusion-directives
|
|
7091
|
-
* Testing Transclusion Directives}.
|
|
7092
|
-
* </div>
|
|
7093
|
-
*
|
|
7094
|
-
* There are three kinds of transclusion depending upon whether you want to transclude just the contents of the
|
|
7095
|
-
* directive's element, the entire element or multiple parts of the element contents:
|
|
7096
|
-
*
|
|
7097
|
-
* * `true` - transclude the content (i.e. the child nodes) of the directive's element.
|
|
7098
|
-
* * `'element'` - transclude the whole of the directive's element including any directives on this
|
|
7099
|
-
* element that are defined at a lower priority than this directive. When used, the `template`
|
|
7100
|
-
* property is ignored.
|
|
7101
|
-
* * **`{...}` (an object hash):** - map elements of the content onto transclusion "slots" in the template.
|
|
7102
|
-
*
|
|
7103
|
-
* **Multi-slot transclusion** is declared by providing an object for the `transclude` property.
|
|
7104
|
-
*
|
|
7105
|
-
* This object is a map where the keys are the name of the slot to fill and the value is an element selector
|
|
7106
|
-
* used to match the HTML to the slot. The element selector should be in normalized form (e.g. `myElement`)
|
|
7107
|
-
* and will match the standard element variants (e.g. `my-element`, `my:element`, `data-my-element`, etc).
|
|
7108
|
-
*
|
|
7109
|
-
* For further information check out the guide on {@link guide/directive#matching-directives Matching Directives}.
|
|
7110
|
-
*
|
|
7111
|
-
* If the element selector is prefixed with a `?` then that slot is optional.
|
|
7112
|
-
*
|
|
7113
|
-
* For example, the transclude object `{ slotA: '?myCustomElement' }` maps `<my-custom-element>` elements to
|
|
7114
|
-
* the `slotA` slot, which can be accessed via the `$transclude` function or via the {@link ngTransclude} directive.
|
|
7115
|
-
*
|
|
7116
|
-
* Slots that are not marked as optional (`?`) will trigger a compile time error if there are no matching elements
|
|
7117
|
-
* in the transclude content. If you wish to know if an optional slot was filled with content, then you can call
|
|
7118
|
-
* `$transclude.isSlotFilled(slotName)` on the transclude function passed to the directive's link function and
|
|
7119
|
-
* injectable into the directive's controller.
|
|
7120
|
-
*
|
|
7121
|
-
*
|
|
7122
|
-
* #### Transclusion Functions
|
|
7123
|
-
*
|
|
7124
|
-
* When a directive requests transclusion, the compiler extracts its contents and provides a **transclusion
|
|
7125
|
-
* function** to the directive's `link` function and `controller`. This transclusion function is a special
|
|
7126
|
-
* **linking function** that will return the compiled contents linked to a new transclusion scope.
|
|
7127
|
-
*
|
|
7128
|
-
* <div class="alert alert-info">
|
|
7129
|
-
* If you are just using {@link ngTransclude} then you don't need to worry about this function, since
|
|
7130
|
-
* ngTransclude will deal with it for us.
|
|
7131
|
-
* </div>
|
|
7132
|
-
*
|
|
7133
|
-
* If you want to manually control the insertion and removal of the transcluded content in your directive
|
|
7134
|
-
* then you must use this transclude function. When you call a transclude function it returns a jqLite/JQuery
|
|
7135
|
-
* object that contains the compiled DOM, which is linked to the correct transclusion scope.
|
|
7136
|
-
*
|
|
7137
|
-
* When you call a transclusion function you can pass in a **clone attach function**. This function accepts
|
|
7138
|
-
* two parameters, `function(clone, scope) { ... }`, where the `clone` is a fresh compiled copy of your transcluded
|
|
7139
|
-
* content and the `scope` is the newly created transclusion scope, which the clone will be linked to.
|
|
7140
|
-
*
|
|
7141
|
-
* <div class="alert alert-info">
|
|
7142
|
-
* **Best Practice**: Always provide a `cloneFn` (clone attach function) when you call a transclude function
|
|
7143
|
-
* since you then get a fresh clone of the original DOM and also have access to the new transclusion scope.
|
|
7144
|
-
* </div>
|
|
7145
|
-
*
|
|
7146
|
-
* It is normal practice to attach your transcluded content (`clone`) to the DOM inside your **clone
|
|
7147
|
-
* attach function**:
|
|
7148
|
-
*
|
|
7149
|
-
* ```js
|
|
7150
|
-
* let transcludedContent, transclusionScope;
|
|
7151
|
-
*
|
|
7152
|
-
* $transclude(function(clone, scope) {
|
|
7153
|
-
* element.append(clone);
|
|
7154
|
-
* transcludedContent = clone;
|
|
7155
|
-
* transclusionScope = scope;
|
|
7156
|
-
* });
|
|
7157
|
-
* ```
|
|
7158
|
-
*
|
|
7159
|
-
* Later, if you want to remove the transcluded content from your DOM then you should also destroy the
|
|
7160
|
-
* associated transclusion scope:
|
|
7161
|
-
*
|
|
7162
|
-
* ```js
|
|
7163
|
-
* transcludedContent.remove();
|
|
7164
|
-
* transclusionScope.$destroy();
|
|
7165
|
-
* ```
|
|
7166
|
-
*
|
|
7167
|
-
* <div class="alert alert-info">
|
|
7168
|
-
* **Best Practice**: if you intend to add and remove transcluded content manually in your directive
|
|
7169
|
-
* (by calling the transclude function to get the DOM and calling `element.remove()` to remove it),
|
|
7170
|
-
* then you are also responsible for calling `$destroy` on the transclusion scope.
|
|
7171
|
-
* </div>
|
|
7172
|
-
*
|
|
7173
|
-
* The built-in DOM manipulation directives, such as {@link ngIf}, {@link ngSwitch} and {@link ngRepeat}
|
|
7174
|
-
* automatically destroy their transcluded clones as necessary so you do not need to worry about this if
|
|
7175
|
-
* you are simply using {@link ngTransclude} to inject the transclusion into your directive.
|
|
7176
|
-
*
|
|
7177
|
-
*
|
|
7178
|
-
* #### Transclusion Scopes
|
|
7179
|
-
*
|
|
7180
|
-
* When you call a transclude function it returns a DOM fragment that is pre-bound to a **transclusion
|
|
7181
|
-
* scope**. This scope is special, in that it is a child of the directive's scope (and so gets destroyed
|
|
7182
|
-
* when the directive's scope gets destroyed) but it inherits the properties of the scope from which it
|
|
7183
|
-
* was taken.
|
|
7184
|
-
*
|
|
7185
|
-
* For example consider a directive that uses transclusion and isolated scope. The DOM hierarchy might look
|
|
7186
|
-
* like this:
|
|
7187
|
-
*
|
|
7188
|
-
* ```html
|
|
7189
|
-
* <div ng-app>
|
|
7190
|
-
* <div isolate>
|
|
7191
|
-
* <div transclusion>
|
|
7192
|
-
* </div>
|
|
7193
|
-
* </div>
|
|
7194
|
-
* </div>
|
|
7195
|
-
* ```
|
|
7196
|
-
*
|
|
7197
|
-
* The `$parent` scope hierarchy will look like this:
|
|
7198
|
-
*
|
|
7199
|
-
```
|
|
7200
|
-
- $rootScope
|
|
7201
|
-
- isolate
|
|
7202
|
-
- transclusion
|
|
7203
|
-
```
|
|
7204
|
-
*
|
|
7205
|
-
* but the scopes will inherit prototypically from different scopes to their `$parent`.
|
|
7206
|
-
*
|
|
7207
|
-
```
|
|
7208
|
-
- $rootScope
|
|
7209
|
-
- transclusion
|
|
7210
|
-
- isolate
|
|
7211
|
-
```
|
|
7212
|
-
*
|
|
7213
|
-
*
|
|
7214
|
-
* ### Attributes
|
|
7215
|
-
*
|
|
7216
|
-
* The {@link ng.$compile.directive.Attributes Attributes} object - passed as a parameter in the
|
|
7217
|
-
* `link()` or `compile()` functions. It has a variety of uses.
|
|
7218
|
-
*
|
|
7219
|
-
* * *Accessing normalized attribute names:* Directives like `ngBind` can be expressed in many ways:
|
|
7220
|
-
* `ng:bind`, `data-ng-bind`, or `x-ng-bind`. The attributes object allows for normalized access
|
|
7221
|
-
* to the attributes.
|
|
7222
|
-
*
|
|
7223
|
-
* * *Directive inter-communication:* All directives share the same instance of the attributes
|
|
7224
|
-
* object which allows the directives to use the attributes object as inter directive
|
|
7225
|
-
* communication.
|
|
7226
|
-
*
|
|
7227
|
-
* * *Supports interpolation:* Interpolation attributes are assigned to the attribute object
|
|
7228
|
-
* allowing other directives to read the interpolated value.
|
|
7229
|
-
*
|
|
7230
|
-
* * *Observing interpolated attributes:* Use `$observe` to observe the value changes of attributes
|
|
7231
|
-
* that contain interpolation (e.g. `src="{{bar}}"`). Not only is this very efficient but it's also
|
|
7232
|
-
* the only way to easily get the actual value because during the linking phase the interpolation
|
|
7233
|
-
* hasn't been evaluated yet and so the value is at this time set to `undefined`.
|
|
7234
|
-
*
|
|
7235
|
-
* ```js
|
|
7236
|
-
* function linkingFn(scope, elm, attrs, ctrl) {
|
|
7237
|
-
* // get the attribute value
|
|
7238
|
-
* console.log(attrs.ngModel);
|
|
7239
|
-
*
|
|
7240
|
-
* // change the attribute
|
|
7241
|
-
* attrs.$set('ngModel', 'new value');
|
|
7242
|
-
*
|
|
7243
|
-
* // observe changes to interpolated attribute
|
|
7244
|
-
* attrs.$observe('ngModel', function(value) {
|
|
7245
|
-
* console.log('ngModel has changed value to ' + value);
|
|
7246
|
-
* });
|
|
7247
|
-
* }
|
|
7248
|
-
* ```
|
|
7249
|
-
*
|
|
7250
|
-
*
|
|
7251
|
-
*
|
|
7252
|
-
* @param {string|Element} element Element or HTML string to compile into a template function.
|
|
7253
|
-
* @param {function(angular.Scope, cloneAttachFn=)} transclude function available to directives - DEPRECATED.
|
|
7254
|
-
*
|
|
7255
|
-
* <div class="alert alert-danger">
|
|
7256
|
-
* **Note:** Passing a `transclude` function to the $compile function is deprecated, as it
|
|
7257
|
-
* e.g. will not use the right outer scope. Please pass the transclude function as a
|
|
7258
|
-
* `parentBoundTranscludeFn` to the link function instead.
|
|
7259
|
-
* </div>
|
|
7260
|
-
*
|
|
7261
|
-
* @param {number} maxPriority only apply directives lower than given priority (Only effects the
|
|
7262
|
-
* root element(s), not their children)
|
|
7263
|
-
* @returns {function(scope, cloneAttachFn=, options=)} a link function which is used to bind template
|
|
7264
|
-
* (a DOM element/tree) to a scope. Where:
|
|
7265
|
-
*
|
|
7266
|
-
* * `scope` - A {@link ng.$rootScope.Scope Scope} to bind to.
|
|
7267
|
-
* * `cloneAttachFn` - If `cloneAttachFn` is provided, then the link function will clone the
|
|
7268
|
-
* `template` and call the `cloneAttachFn` function allowing the caller to attach the
|
|
7269
|
-
* cloned elements to the DOM document at the appropriate place. The `cloneAttachFn` is
|
|
7270
|
-
* called as: <br/> `cloneAttachFn(clonedElement, scope)` where:
|
|
7271
|
-
*
|
|
7272
|
-
* * `clonedElement` - is a clone of the original `element` passed into the compiler.
|
|
7273
|
-
* * `scope` - is the current scope with which the linking function is working with.
|
|
7274
|
-
*
|
|
7275
|
-
* * `options` - An optional object hash with linking options. If `options` is provided, then the following
|
|
7276
|
-
* keys may be used to control linking behavior:
|
|
7277
|
-
*
|
|
7278
|
-
* * `parentBoundTranscludeFn` - the transclude function made available to
|
|
7279
|
-
* directives; if given, it will be passed through to the link functions of
|
|
7280
|
-
* directives found in `element` during compilation.
|
|
7281
|
-
* * `transcludeControllers` - an object hash with keys that map controller names
|
|
7282
|
-
* to a hash with the key `instance`, which maps to the controller instance;
|
|
7283
|
-
* if given, it will make the controllers available to directives on the compileNode:
|
|
7284
|
-
* ```
|
|
7285
|
-
* {
|
|
7286
|
-
* parent: {
|
|
7287
|
-
* instance: parentControllerInstance
|
|
7288
|
-
* }
|
|
7289
|
-
* }
|
|
7290
|
-
* ```
|
|
7291
|
-
* * `futureParentElement` - defines the parent to which the `cloneAttachFn` will add
|
|
7292
|
-
* the cloned elements; only needed for transcludes that are allowed to contain non HTML
|
|
7293
|
-
* elements (e.g. SVG elements). See also the `directive.controller` property.
|
|
7294
|
-
*
|
|
7295
|
-
* Calling the linking function returns the element of the template. It is either the original
|
|
7296
|
-
* element passed in, or the clone of the element if the `cloneAttachFn` is provided.
|
|
7297
|
-
*
|
|
7298
|
-
* After linking the view is not updated until after a call to `$digest`, which typically is done by
|
|
7299
|
-
* AngularJS automatically.
|
|
7300
|
-
*
|
|
7301
|
-
* If you need access to the bound view, there are two ways to do it:
|
|
7302
|
-
*
|
|
7303
|
-
* - If you are not asking the linking function to clone the template, create the DOM element(s)
|
|
7304
|
-
* before you send them to the compiler and keep this reference around.
|
|
7305
|
-
* ```js
|
|
7306
|
-
* let element = angular.element('<p>{{total}}</p>');
|
|
7307
|
-
* $compile(element)(scope);
|
|
7308
|
-
* ```
|
|
7309
|
-
*
|
|
7310
|
-
* - if on the other hand, you need the element to be cloned, the view reference from the original
|
|
7311
|
-
* example would not point to the clone, but rather to the original template that was cloned. In
|
|
7312
|
-
* this case, you can access the clone either via the `cloneAttachFn` or the value returned by the
|
|
7313
|
-
* linking function:
|
|
7314
|
-
* ```js
|
|
7315
|
-
* let templateElement = angular.element('<p>{{total}}</p>');
|
|
7316
|
-
* let clonedElement = $compile(templateElement)(scope, function(clonedElement, scope) {
|
|
7317
|
-
* // Attach the clone to DOM document at the right place.
|
|
7318
|
-
* });
|
|
7319
|
-
*
|
|
7320
|
-
* // Now we have reference to the cloned DOM via `clonedElement`.
|
|
7321
|
-
* // NOTE: The `clonedElement` returned by the linking function is the same as the
|
|
7322
|
-
* // `clonedElement` passed to `cloneAttachFn`.
|
|
7323
|
-
* ```
|
|
7324
|
-
*
|
|
7325
|
-
*
|
|
7326
|
-
* For information on how the compiler works, see the
|
|
7327
|
-
* {@link guide/compiler AngularJS HTML Compiler} section of the Developer Guide.
|
|
7328
|
-
*
|
|
7329
|
-
* @knownIssue
|
|
7330
|
-
*
|
|
7331
|
-
* ### Double Compilation
|
|
7332
|
-
*
|
|
7333
|
-
Double compilation occurs when an already compiled part of the DOM gets
|
|
7334
|
-
compiled again. This is an undesired effect and can lead to misbehaving directives, performance issues,
|
|
7335
|
-
and memory leaks. Refer to the Compiler Guide {@link guide/compiler#double-compilation-and-how-to-avoid-it
|
|
7336
|
-
section on double compilation} for an in-depth explanation and ways to avoid it.
|
|
7337
|
-
|
|
7338
|
-
* @knownIssue
|
|
7339
|
-
|
|
7340
|
-
### Issues with `replace: true`
|
|
7341
|
-
*
|
|
7342
|
-
* <div class="alert alert-danger">
|
|
7343
|
-
* **Note**: {@link $compile#-replace- `replace: true`} is deprecated and not recommended to use,
|
|
7344
|
-
* mainly due to the issues listed here. It has been completely removed in the new Angular.
|
|
7345
|
-
* </div>
|
|
7346
|
-
*
|
|
7347
|
-
* #### Attribute values are not merged
|
|
7348
|
-
*
|
|
7349
|
-
* When a `replace` directive encounters the same attribute on the original and the replace node,
|
|
7350
|
-
* it will simply deduplicate the attribute and join the values with a space or with a `;` in case of
|
|
7351
|
-
* the `style` attribute.
|
|
7352
|
-
* ```html
|
|
7353
|
-
* Original Node: <span class="original" style="color: red;"></span>
|
|
7354
|
-
* Replace Template: <span class="replaced" style="background: blue;"></span>
|
|
7355
|
-
* Result: <span class="original replaced" style="color: red; background: blue;"></span>
|
|
7356
|
-
* ```
|
|
7357
|
-
*
|
|
7358
|
-
* That means attributes that contain AngularJS expressions will not be merged correctly, e.g.
|
|
7359
|
-
* {@link ngShow} or {@link ngClass} will cause a {@link $parse} error:
|
|
7360
|
-
*
|
|
7361
|
-
* ```html
|
|
7362
|
-
* Original Node: <span ng-class="{'something': something}" ng-show="!condition"></span>
|
|
7363
|
-
* Replace Template: <span ng-class="{'else': else}" ng-show="otherCondition"></span>
|
|
7364
|
-
* Result: <span ng-class="{'something': something} {'else': else}" ng-show="!condition otherCondition"></span>
|
|
7365
|
-
* ```
|
|
7366
|
-
*
|
|
7367
|
-
* See issue [#5695](https://github.com/angular/angular.js/issues/5695).
|
|
7368
|
-
*
|
|
7369
|
-
* #### Directives are not deduplicated before compilation
|
|
7370
|
-
*
|
|
7371
|
-
* When the original node and the replace template declare the same directive(s), they will be
|
|
7372
|
-
* {@link guide/compiler#double-compilation-and-how-to-avoid-it compiled twice} because the compiler
|
|
7373
|
-
* does not deduplicate them. In many cases, this is not noticeable, but e.g. {@link ngModel} will
|
|
7374
|
-
* attach `$formatters` and `$parsers` twice.
|
|
7375
|
-
*
|
|
7376
|
-
* See issue [#2573](https://github.com/angular/angular.js/issues/2573).
|
|
7377
|
-
*
|
|
7378
|
-
* #### `transclude: element` in the replace template root can have unexpected effects
|
|
7379
|
-
*
|
|
7380
|
-
* When the replace template has a directive at the root node that uses
|
|
7381
|
-
* {@link $compile#-transclude- `transclude: element`}, e.g.
|
|
7382
|
-
* {@link ngIf} or {@link ngRepeat}, the DOM structure or scope inheritance can be incorrect.
|
|
7383
|
-
* See the following issues:
|
|
7384
|
-
*
|
|
7385
|
-
* - Incorrect scope on replaced element:
|
|
7386
|
-
* [#9837](https://github.com/angular/angular.js/issues/9837)
|
|
7387
|
-
* - Different DOM between `template` and `templateUrl`:
|
|
7388
|
-
* [#10612](https://github.com/angular/angular.js/issues/14326)
|
|
7389
|
-
*
|
|
7390
|
-
*/
|
|
7391
|
-
|
|
7392
|
-
/**
|
|
7393
|
-
* @ngdoc directive
|
|
7394
|
-
* @name ngProp
|
|
7395
|
-
* @restrict A
|
|
7396
|
-
* @element ANY
|
|
7397
|
-
*
|
|
7398
|
-
* @usage
|
|
7399
|
-
*
|
|
7400
|
-
* ```html
|
|
7401
|
-
* <ANY ng-prop-propname="expression">
|
|
7402
|
-
* </ANY>
|
|
7403
|
-
* ```
|
|
7404
|
-
*
|
|
7405
|
-
* or with uppercase letters in property (e.g. "propName"):
|
|
7406
|
-
*
|
|
7407
|
-
*
|
|
7408
|
-
* ```html
|
|
7409
|
-
* <ANY ng-prop-prop_name="expression">
|
|
7410
|
-
* </ANY>
|
|
7411
|
-
* ```
|
|
7412
|
-
*
|
|
7413
|
-
*
|
|
7414
|
-
* @description
|
|
7415
|
-
* The `ngProp` directive binds an expression to a DOM element property.
|
|
7416
|
-
* `ngProp` allows writing to arbitrary properties by including
|
|
7417
|
-
* the property name in the attribute, e.g. `ng-prop-value="'my value'"` binds 'my value' to
|
|
7418
|
-
* the `value` property.
|
|
7419
|
-
*
|
|
7420
|
-
* Usually, it's not necessary to write to properties in AngularJS, as the built-in directives
|
|
7421
|
-
* handle the most common use cases (instead of the above example, you would use {@link ngValue}).
|
|
7422
|
-
*
|
|
7423
|
-
* However, [custom elements](https://developer.mozilla.org/docs/Web/Web_Components/Using_custom_elements)
|
|
7424
|
-
* often use custom properties to hold data, and `ngProp` can be used to provide input to these
|
|
7425
|
-
* custom elements.
|
|
7426
|
-
*
|
|
7427
|
-
* ## Binding to camelCase properties
|
|
7428
|
-
*
|
|
7429
|
-
* Since HTML attributes are case-insensitive, camelCase properties like `innerHTML` must be escaped.
|
|
7430
|
-
* AngularJS uses the underscore (_) in front of a character to indicate that it is uppercase, so
|
|
7431
|
-
* `innerHTML` must be written as `ng-prop-inner_h_t_m_l="expression"` (Note that this is just an
|
|
7432
|
-
* example, and for binding HTML {@link ngBindHtml} should be used.
|
|
7433
|
-
*
|
|
7434
|
-
* ## Security
|
|
7435
|
-
*
|
|
7436
|
-
* Binding expressions to arbitrary properties poses a security risk, as properties like `innerHTML`
|
|
7437
|
-
* can insert potentially dangerous HTML into the application, e.g. script tags that execute
|
|
7438
|
-
* malicious code.
|
|
7439
|
-
* For this reason, `ngProp` applies Strict Contextual Escaping with the {@link ng.$sce $sce service}.
|
|
7440
|
-
* This means vulnerable properties require their content to be "trusted", based on the
|
|
7441
|
-
* context of the property. For example, the `innerHTML` is in the `HTML` context, and the
|
|
7442
|
-
* `iframe.src` property is in the `RESOURCE_URL` context, which requires that values written to
|
|
7443
|
-
* this property are trusted as a `RESOURCE_URL`.
|
|
7444
|
-
*
|
|
7445
|
-
* This can be set explicitly by calling $sce.trustAs(type, value) on the value that is
|
|
7446
|
-
* trusted before passing it to the `ng-prop-*` directive. There are exist shorthand methods for
|
|
7447
|
-
* each context type in the form of {@link ng.$sce#trustAsResourceUrl $sce.trustAsResourceUrl()} et al.
|
|
7448
|
-
*
|
|
7449
|
-
* In some cases you can also rely upon automatic sanitization of untrusted values - see below.
|
|
7450
|
-
*
|
|
7451
|
-
* Based on the context, other options may exist to mark a value as trusted / configure the behavior
|
|
7452
|
-
* of {@link ng.$sce}. For example, to restrict the `RESOURCE_URL` context to specific origins, use
|
|
7453
|
-
* the {@link $sceDelegateProvider#trustedResourceUrlList trustedResourceUrlList()}
|
|
7454
|
-
* and {@link $sceDelegateProvider#bannedResourceUrlList bannedResourceUrlList()}.
|
|
7455
|
-
*
|
|
7456
|
-
* {@link ng.$sce#what-trusted-context-types-are-supported- Find out more about the different context types}.
|
|
7457
|
-
*
|
|
7458
|
-
* ### HTML Sanitization
|
|
7459
|
-
*
|
|
7460
|
-
* By default, `$sce` will throw an error if it detects untrusted HTML content, and will not bind the
|
|
7461
|
-
* content.
|
|
7462
|
-
* However, if you include the {@link ngSanitize ngSanitize module}, it will try to sanitize the
|
|
7463
|
-
* potentially dangerous HTML, e.g. strip non-trusted tags and attributes when binding to
|
|
7464
|
-
* `innerHTML`.
|
|
7465
|
-
*
|
|
7466
|
-
*
|
|
7467
|
-
*/
|
|
7468
|
-
|
|
7469
|
-
/** @ngdoc directive
|
|
7470
|
-
* @name ngOn
|
|
7471
|
-
* @restrict A
|
|
7472
|
-
* @element ANY
|
|
7473
|
-
*
|
|
7474
|
-
* @usage
|
|
7475
|
-
*
|
|
7476
|
-
* ```html
|
|
7477
|
-
* <ANY ng-on-eventname="expression">
|
|
7478
|
-
* </ANY>
|
|
7479
|
-
* ```
|
|
7480
|
-
*
|
|
7481
|
-
* or with uppercase letters in property (e.g. "eventName"):
|
|
7482
|
-
*
|
|
7483
|
-
*
|
|
7484
|
-
* ```html
|
|
7485
|
-
* <ANY ng-on-event_name="expression">
|
|
7486
|
-
* </ANY>
|
|
7487
|
-
* ```
|
|
7488
|
-
*
|
|
7489
|
-
* @description
|
|
7490
|
-
* The `ngOn` directive adds an event listener to a DOM element via
|
|
7491
|
-
* {@link angular.element angular.element().on()}, and evaluates an expression when the event is
|
|
7492
|
-
* fired.
|
|
7493
|
-
* `ngOn` allows adding listeners for arbitrary events by including
|
|
7494
|
-
* the event name in the attribute, e.g. `ng-on-drop="onDrop()"` executes the 'onDrop()' expression
|
|
7495
|
-
* when the `drop` event is fired.
|
|
7496
|
-
*
|
|
7497
|
-
* AngularJS provides specific directives for many events, such as {@link ngClick}, so in most
|
|
7498
|
-
* cases it is not necessary to use `ngOn`. However, AngularJS does not support all events
|
|
7499
|
-
* (e.g. the `drop` event in the example above), and new events might be introduced in later DOM
|
|
7500
|
-
* standards.
|
|
7501
|
-
*
|
|
7502
|
-
* Another use-case for `ngOn` is listening to
|
|
7503
|
-
* [custom events](https://developer.mozilla.org/docs/Web/Guide/Events/Creating_and_triggering_events)
|
|
7504
|
-
* fired by
|
|
7505
|
-
* [custom elements](https://developer.mozilla.org/docs/Web/Web_Components/Using_custom_elements).
|
|
7506
|
-
*
|
|
7507
|
-
* ## Binding to camelCase properties
|
|
7508
|
-
*
|
|
7509
|
-
* Since HTML attributes are case-insensitive, camelCase properties like `myEvent` must be escaped.
|
|
7510
|
-
* AngularJS uses the underscore (_) in front of a character to indicate that it is uppercase, so
|
|
7511
|
-
* `myEvent` must be written as `ng-on-my_event="expression"`.
|
|
7512
|
-
*
|
|
7513
|
-
*
|
|
7514
|
-
*/
|
|
7515
|
-
|
|
7516
6399
|
const $compileMinErr = minErr("$compile");
|
|
7517
6400
|
|
|
7518
6401
|
function UNINITIALIZED_VALUE() {}
|
|
@@ -8419,7 +7302,7 @@
|
|
|
8419
7302
|
let nodeName;
|
|
8420
7303
|
|
|
8421
7304
|
if (booleanKey) {
|
|
8422
|
-
this.$$element
|
|
7305
|
+
this.$$element[0][key] = value;
|
|
8423
7306
|
attrName = booleanKey;
|
|
8424
7307
|
} else if (aliasedKey) {
|
|
8425
7308
|
this[aliasedKey] = value;
|
|
@@ -10547,6 +9430,7 @@
|
|
|
10547
9430
|
function sanitizeSrcsetPropertyValue(value) {
|
|
10548
9431
|
return sanitizeSrcset($sce.valueOf(value), "ng-prop-srcset");
|
|
10549
9432
|
}
|
|
9433
|
+
|
|
10550
9434
|
function addPropertyDirective(node, directives, attrName, propName) {
|
|
10551
9435
|
if (EVENT_HANDLER_ATTR_REGEXP.test(propName)) {
|
|
10552
9436
|
throw $compileMinErr(
|
|
@@ -10699,9 +9583,9 @@
|
|
|
10699
9583
|
* This is a special jqLite.replaceWith, which can replace items which
|
|
10700
9584
|
* have no parents, provided that the containing jqLite collection is provided.
|
|
10701
9585
|
*
|
|
10702
|
-
* @param {
|
|
9586
|
+
* @param {JQLite} $rootElement The root of the compile tree. Used so that we can replace nodes
|
|
10703
9587
|
* in the root of the tree.
|
|
10704
|
-
* @param {
|
|
9588
|
+
* @param {JQLite} elementsToRemove The jqLite element which we are going to replace. We keep
|
|
10705
9589
|
* the shell, but replace its DOM node reference.
|
|
10706
9590
|
* @param {Node} newNode The new DOM node.
|
|
10707
9591
|
*/
|
|
@@ -10753,7 +9637,7 @@
|
|
|
10753
9637
|
fragment.appendChild(elementsToRemove[i]);
|
|
10754
9638
|
}
|
|
10755
9639
|
|
|
10756
|
-
if (
|
|
9640
|
+
if (CACHE.has(firstElementToRemove[EXPANDO])) {
|
|
10757
9641
|
// Copy over user data (that includes AngularJS's $scope etc.). Don't copy private
|
|
10758
9642
|
// data here because there's no public interface in jQuery to do that and copying over
|
|
10759
9643
|
// event listeners (which is the main use of private data) wouldn't work anyway.
|
|
@@ -11127,7 +10011,7 @@
|
|
|
11127
10011
|
|
|
11128
10012
|
// SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.
|
|
11129
10013
|
const href =
|
|
11130
|
-
toString.call(element.
|
|
10014
|
+
toString.call(element[0].href) === "[object SVGAnimatedString]"
|
|
11131
10015
|
? "xlink:href"
|
|
11132
10016
|
: "href";
|
|
11133
10017
|
element.on("click", (event) => {
|
|
@@ -14763,7 +13647,7 @@
|
|
|
14763
13647
|
|
|
14764
13648
|
if (nativeValidation) {
|
|
14765
13649
|
ctrl.$parsers.push((value) => {
|
|
14766
|
-
const validity = element
|
|
13650
|
+
const validity = element[0][VALIDITY_STATE_PROPERTY] || {};
|
|
14767
13651
|
if (validity.badInput || validity.typeMismatch) {
|
|
14768
13652
|
ctrl.$$parserName = parserName;
|
|
14769
13653
|
return undefined;
|
|
@@ -15420,7 +14304,7 @@
|
|
|
15420
14304
|
// Support: IE9 only
|
|
15421
14305
|
// In IE9 values are converted to string (e.g. `input.value = null` results in `input.value === 'null'`).
|
|
15422
14306
|
const propValue = isDefined(value) ? value : null;
|
|
15423
|
-
element
|
|
14307
|
+
element[0]["value"] = propValue;
|
|
15424
14308
|
attr.$set("value", value);
|
|
15425
14309
|
}
|
|
15426
14310
|
|
|
@@ -15477,7 +14361,7 @@
|
|
|
15477
14361
|
const noopNgModelController = { $setViewValue: () => {}, $render: () => {} };
|
|
15478
14362
|
|
|
15479
14363
|
function setOptionSelectedStatus(optionEl, value) {
|
|
15480
|
-
optionEl.
|
|
14364
|
+
optionEl[0].selected = value;
|
|
15481
14365
|
/**
|
|
15482
14366
|
* When unselecting an option, setting the property to null / false should be enough
|
|
15483
14367
|
* However, screenreaders might react to the selected attribute instead, see
|
|
@@ -15744,7 +14628,7 @@
|
|
|
15744
14628
|
|
|
15745
14629
|
optionAttrs.$observe("value", (newVal) => {
|
|
15746
14630
|
let removal;
|
|
15747
|
-
const previouslySelected = optionElement.
|
|
14631
|
+
const previouslySelected = optionElement[0].selected;
|
|
15748
14632
|
|
|
15749
14633
|
if (isDefined(hashedVal)) {
|
|
15750
14634
|
self.removeOption(oldVal);
|
|
@@ -15772,7 +14656,7 @@
|
|
|
15772
14656
|
self.readValue();
|
|
15773
14657
|
|
|
15774
14658
|
let removal;
|
|
15775
|
-
const previouslySelected = optionElement.
|
|
14659
|
+
const previouslySelected = optionElement[0].selected;
|
|
15776
14660
|
|
|
15777
14661
|
if (isDefined(oldVal)) {
|
|
15778
14662
|
self.removeOption(oldVal);
|
|
@@ -15789,7 +14673,7 @@
|
|
|
15789
14673
|
// The text content is interpolated
|
|
15790
14674
|
optionScope.$watch(interpolateTextFn, (newVal, oldVal) => {
|
|
15791
14675
|
optionAttrs.$set("value", newVal);
|
|
15792
|
-
const previouslySelected = optionElement.
|
|
14676
|
+
const previouslySelected = optionElement[0].selected;
|
|
15793
14677
|
if (oldVal !== newVal) {
|
|
15794
14678
|
self.removeOption(oldVal);
|
|
15795
14679
|
}
|
|
@@ -15808,7 +14692,7 @@
|
|
|
15808
14692
|
// Since model updates will also select disabled options (like ngOptions),
|
|
15809
14693
|
// we only have to handle options becoming disabled, not enabled
|
|
15810
14694
|
|
|
15811
|
-
if (newVal === "true" || (newVal && optionElement.
|
|
14695
|
+
if (newVal === "true" || (newVal && optionElement[0].selected)) {
|
|
15812
14696
|
if (self.multiple) {
|
|
15813
14697
|
scheduleViewValueUpdate(true);
|
|
15814
14698
|
} else {
|
|
@@ -19096,7 +17980,7 @@
|
|
|
19096
17980
|
|
|
19097
17981
|
if (
|
|
19098
17982
|
attrName === "href" &&
|
|
19099
|
-
toString.call(element.
|
|
17983
|
+
toString.call(element[0].href) === "[object SVGAnimatedString]"
|
|
19100
17984
|
) {
|
|
19101
17985
|
name = "xlinkHref";
|
|
19102
17986
|
attr.$attr[name] = "xlink:href";
|
|
@@ -23544,31 +22428,6 @@
|
|
|
23544
22428
|
];
|
|
23545
22429
|
}
|
|
23546
22430
|
|
|
23547
|
-
function $$ForceReflowProvider() {
|
|
23548
|
-
this.$get = [
|
|
23549
|
-
"$document",
|
|
23550
|
-
($document) =>
|
|
23551
|
-
function (domNode) {
|
|
23552
|
-
// the line below will force the browser to perform a repaint so
|
|
23553
|
-
// that all the animated elements within the animation frame will
|
|
23554
|
-
// be properly updated and drawn on screen. This is required to
|
|
23555
|
-
// ensure that the preparation animation is properly flushed so that
|
|
23556
|
-
// the active state picks up from there. DO NOT REMOVE THIS LINE.
|
|
23557
|
-
// DO NOT OPTIMIZE THIS LINE. THE MINIFIER WILL REMOVE IT OTHERWISE WHICH
|
|
23558
|
-
// WILL RESULT IN AN UNPREDICTABLE BUG THAT IS VERY HARD TO TRACK DOWN AND
|
|
23559
|
-
// WILL TAKE YEARS AWAY FROM YOUR LIFE.
|
|
23560
|
-
if (domNode) {
|
|
23561
|
-
if (!domNode.nodeType && domNode instanceof jqLite) {
|
|
23562
|
-
domNode = domNode[0];
|
|
23563
|
-
}
|
|
23564
|
-
} else {
|
|
23565
|
-
domNode = $document[0].body;
|
|
23566
|
-
}
|
|
23567
|
-
return domNode.offsetWidth + 1;
|
|
23568
|
-
},
|
|
23569
|
-
];
|
|
23570
|
-
}
|
|
23571
|
-
|
|
23572
22431
|
const APPLICATION_JSON = "application/json";
|
|
23573
22432
|
const CONTENT_TYPE_APPLICATION_JSON = {
|
|
23574
22433
|
"Content-Type": `${APPLICATION_JSON};charset=utf-8`,
|
|
@@ -26208,7 +25067,7 @@
|
|
|
26208
25067
|
if (isString(rewriteLinks) && isUndefined(elm.attr(rewriteLinks)))
|
|
26209
25068
|
return;
|
|
26210
25069
|
|
|
26211
|
-
let absHref = elm.
|
|
25070
|
+
let absHref = elm[0].href;
|
|
26212
25071
|
// get the actual href attribute - see
|
|
26213
25072
|
// http://msdn.microsoft.com/en-us/library/ie/dd347148(v=vs.85).aspx
|
|
26214
25073
|
const relHref = elm.attr("href") || elm.attr("xlink:href");
|
|
@@ -26353,52 +25212,6 @@
|
|
|
26353
25212
|
];
|
|
26354
25213
|
}
|
|
26355
25214
|
|
|
26356
|
-
/**
|
|
26357
|
-
* @ngdoc service
|
|
26358
|
-
* @name $log
|
|
26359
|
-
*
|
|
26360
|
-
* @description
|
|
26361
|
-
* Simple service for logging. Default implementation safely writes the message
|
|
26362
|
-
* into the browser's console (if present).
|
|
26363
|
-
*
|
|
26364
|
-
* The main purpose of this service is to simplify debugging and troubleshooting.
|
|
26365
|
-
*
|
|
26366
|
-
* To reveal the location of the calls to `$log` in the JavaScript console,
|
|
26367
|
-
* you can "blackbox" the AngularJS source in your browser:
|
|
26368
|
-
*
|
|
26369
|
-
* [Mozilla description of blackboxing](https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Black_box_a_source).
|
|
26370
|
-
* [Chrome description of blackboxing](https://developer.chrome.com/devtools/docs/blackboxing).
|
|
26371
|
-
*
|
|
26372
|
-
* Note: Not all browsers support blackboxing.
|
|
26373
|
-
*
|
|
26374
|
-
* The default is to log `debug` messages. You can use
|
|
26375
|
-
* {@link ng.$logProvider ng.$logProvider#debugEnabled} to change this.
|
|
26376
|
-
*
|
|
26377
|
-
* @example
|
|
26378
|
-
<example module="logExample" name="log-service">
|
|
26379
|
-
<file name="script.js">
|
|
26380
|
-
angular.module('logExample', [])
|
|
26381
|
-
.controller('LogController', ['$scope', '$log', function($scope, $log) {
|
|
26382
|
-
$scope.$log = $log;
|
|
26383
|
-
$scope.message = 'Hello World!';
|
|
26384
|
-
}]);
|
|
26385
|
-
</file>
|
|
26386
|
-
<file name="index.html">
|
|
26387
|
-
<div ng-controller="LogController">
|
|
26388
|
-
<p>Reload this page with open console, enter text and hit the log button...</p>
|
|
26389
|
-
<label>Message:
|
|
26390
|
-
<input type="text" ng-model="message" /></label>
|
|
26391
|
-
<button ng-click="$log.log(message)">log</button>
|
|
26392
|
-
<button ng-click="$log.warn(message)">warn</button>
|
|
26393
|
-
<button ng-click="$log.info(message)">info</button>
|
|
26394
|
-
<button ng-click="$log.error(message)">error</button>
|
|
26395
|
-
<button ng-click="$log.debug(message)">debug</button>
|
|
26396
|
-
</div>
|
|
26397
|
-
</file>
|
|
26398
|
-
</example>
|
|
26399
|
-
*/
|
|
26400
|
-
|
|
26401
|
-
|
|
26402
25215
|
/**
|
|
26403
25216
|
* @ngdoc provider
|
|
26404
25217
|
* @name $logProvider
|
|
@@ -26407,9 +25220,10 @@
|
|
|
26407
25220
|
* @description
|
|
26408
25221
|
* Use the `$logProvider` to configure how the application logs messages
|
|
26409
25222
|
*/
|
|
26410
|
-
|
|
26411
|
-
|
|
26412
|
-
|
|
25223
|
+
class $LogProvider {
|
|
25224
|
+
constructor() {
|
|
25225
|
+
this.debug = true;
|
|
25226
|
+
}
|
|
26413
25227
|
|
|
26414
25228
|
/**
|
|
26415
25229
|
* @ngdoc method
|
|
@@ -26418,15 +25232,15 @@
|
|
|
26418
25232
|
* @param {boolean=} flag enable or disable debug level messages
|
|
26419
25233
|
* @returns {*} current value if used as getter or itself (chaining) if used as setter
|
|
26420
25234
|
*/
|
|
26421
|
-
|
|
26422
|
-
if (
|
|
26423
|
-
debug = flag;
|
|
25235
|
+
debugEnabled(flag) {
|
|
25236
|
+
if (typeof flag !== "undefined") {
|
|
25237
|
+
this.debug = flag;
|
|
26424
25238
|
return this;
|
|
26425
25239
|
}
|
|
26426
|
-
return debug;
|
|
26427
|
-
}
|
|
25240
|
+
return this.debug;
|
|
25241
|
+
}
|
|
26428
25242
|
|
|
26429
|
-
|
|
25243
|
+
formatError(arg) {
|
|
26430
25244
|
if (isError(arg)) {
|
|
26431
25245
|
if (arg.stack) {
|
|
26432
25246
|
arg =
|
|
@@ -26440,77 +25254,71 @@
|
|
|
26440
25254
|
return arg;
|
|
26441
25255
|
}
|
|
26442
25256
|
|
|
26443
|
-
|
|
25257
|
+
consoleLog(type) {
|
|
26444
25258
|
const console = window.console || {};
|
|
26445
25259
|
const logFn = console[type] || console.log || (() => {});
|
|
26446
25260
|
|
|
26447
|
-
return
|
|
26448
|
-
|
|
26449
|
-
|
|
26450
|
-
args.push(formatError(arg));
|
|
26451
|
-
});
|
|
26452
|
-
return logFn.apply(console, args);
|
|
25261
|
+
return (...args) => {
|
|
25262
|
+
const formattedArgs = args.map((arg) => this.formatError(arg));
|
|
25263
|
+
return logFn.apply(console, formattedArgs);
|
|
26453
25264
|
};
|
|
26454
25265
|
}
|
|
26455
25266
|
|
|
26456
|
-
|
|
26457
|
-
|
|
26458
|
-
|
|
26459
|
-
|
|
26460
|
-
|
|
26461
|
-
|
|
26462
|
-
|
|
26463
|
-
|
|
26464
|
-
|
|
26465
|
-
|
|
26466
|
-
log: consoleLog("log"),
|
|
26467
|
-
|
|
26468
|
-
/**
|
|
26469
|
-
* @ngdoc method
|
|
26470
|
-
* @name $log#info
|
|
26471
|
-
*
|
|
26472
|
-
* @description
|
|
26473
|
-
* Write an information message
|
|
26474
|
-
*/
|
|
26475
|
-
info: consoleLog("info"),
|
|
25267
|
+
$get() {
|
|
25268
|
+
return {
|
|
25269
|
+
/**
|
|
25270
|
+
* @ngdoc method
|
|
25271
|
+
* @name $log#log
|
|
25272
|
+
*
|
|
25273
|
+
* @description
|
|
25274
|
+
* Write a log message
|
|
25275
|
+
*/
|
|
25276
|
+
log: this.consoleLog("log"),
|
|
26476
25277
|
|
|
26477
|
-
|
|
26478
|
-
|
|
26479
|
-
|
|
26480
|
-
|
|
26481
|
-
|
|
26482
|
-
|
|
26483
|
-
|
|
26484
|
-
|
|
25278
|
+
/**
|
|
25279
|
+
* @ngdoc method
|
|
25280
|
+
* @name $log#info
|
|
25281
|
+
*
|
|
25282
|
+
* @description
|
|
25283
|
+
* Write an information message
|
|
25284
|
+
*/
|
|
25285
|
+
info: this.consoleLog("info"),
|
|
26485
25286
|
|
|
26486
|
-
|
|
26487
|
-
|
|
26488
|
-
|
|
26489
|
-
|
|
26490
|
-
|
|
26491
|
-
|
|
26492
|
-
|
|
26493
|
-
|
|
25287
|
+
/**
|
|
25288
|
+
* @ngdoc method
|
|
25289
|
+
* @name $log#warn
|
|
25290
|
+
*
|
|
25291
|
+
* @description
|
|
25292
|
+
* Write a warning message
|
|
25293
|
+
*/
|
|
25294
|
+
warn: this.consoleLog("warn"),
|
|
26494
25295
|
|
|
26495
|
-
|
|
26496
|
-
|
|
26497
|
-
|
|
26498
|
-
|
|
26499
|
-
|
|
26500
|
-
|
|
26501
|
-
|
|
26502
|
-
|
|
26503
|
-
const fn = consoleLog("debug");
|
|
25296
|
+
/**
|
|
25297
|
+
* @ngdoc method
|
|
25298
|
+
* @name $log#error
|
|
25299
|
+
*
|
|
25300
|
+
* @description
|
|
25301
|
+
* Write an error message
|
|
25302
|
+
*/
|
|
25303
|
+
error: this.consoleLog("error"),
|
|
26504
25304
|
|
|
26505
|
-
|
|
26506
|
-
|
|
26507
|
-
|
|
26508
|
-
|
|
26509
|
-
|
|
26510
|
-
|
|
26511
|
-
|
|
26512
|
-
|
|
26513
|
-
|
|
25305
|
+
/**
|
|
25306
|
+
* @ngdoc method
|
|
25307
|
+
* @name $log#debug
|
|
25308
|
+
*
|
|
25309
|
+
* @description
|
|
25310
|
+
* Write a debug message
|
|
25311
|
+
*/
|
|
25312
|
+
debug: (() => {
|
|
25313
|
+
const fn = this.consoleLog("debug");
|
|
25314
|
+
return (...args) => {
|
|
25315
|
+
if (this.debug) {
|
|
25316
|
+
fn.apply(this, args);
|
|
25317
|
+
}
|
|
25318
|
+
};
|
|
25319
|
+
})(),
|
|
25320
|
+
};
|
|
25321
|
+
}
|
|
26514
25322
|
}
|
|
26515
25323
|
|
|
26516
25324
|
const $parseMinErr = minErr("$parse");
|
|
@@ -31211,501 +30019,498 @@
|
|
|
31211
30019
|
},
|
|
31212
30020
|
];
|
|
31213
30021
|
|
|
31214
|
-
|
|
31215
|
-
"
|
|
31216
|
-
function ($animateProvider) {
|
|
31217
|
-
const NG_ANIMATE_REF_ATTR = "ng-animate-ref";
|
|
31218
|
-
|
|
31219
|
-
const drivers = (this.drivers = []);
|
|
30022
|
+
function $$AnimationProvider() {
|
|
30023
|
+
const NG_ANIMATE_REF_ATTR = "ng-animate-ref";
|
|
31220
30024
|
|
|
31221
|
-
|
|
31222
|
-
const PREPARE_CLASSES_KEY = "$$animatePrepareClasses";
|
|
30025
|
+
const drivers = (this.drivers = []);
|
|
31223
30026
|
|
|
31224
|
-
|
|
31225
|
-
|
|
31226
|
-
}
|
|
30027
|
+
const RUNNER_STORAGE_KEY = "$$animationRunner";
|
|
30028
|
+
const PREPARE_CLASSES_KEY = "$$animatePrepareClasses";
|
|
31227
30029
|
|
|
31228
|
-
|
|
31229
|
-
|
|
31230
|
-
|
|
30030
|
+
function setRunner(element, runner) {
|
|
30031
|
+
element.data(RUNNER_STORAGE_KEY, runner);
|
|
30032
|
+
}
|
|
31231
30033
|
|
|
31232
|
-
|
|
31233
|
-
|
|
31234
|
-
|
|
30034
|
+
function removeRunner(element) {
|
|
30035
|
+
element.removeData(RUNNER_STORAGE_KEY);
|
|
30036
|
+
}
|
|
31235
30037
|
|
|
31236
|
-
|
|
31237
|
-
|
|
31238
|
-
|
|
31239
|
-
"$$AnimateRunner",
|
|
31240
|
-
"$$rAFScheduler",
|
|
31241
|
-
"$$animateCache",
|
|
31242
|
-
function (
|
|
31243
|
-
$rootScope,
|
|
31244
|
-
$injector,
|
|
31245
|
-
$$AnimateRunner,
|
|
31246
|
-
$$rAFScheduler,
|
|
31247
|
-
$$animateCache,
|
|
31248
|
-
) {
|
|
31249
|
-
const animationQueue = [];
|
|
31250
|
-
const applyAnimationClasses = applyAnimationClassesFactory();
|
|
30038
|
+
function getRunner(element) {
|
|
30039
|
+
return element.data(RUNNER_STORAGE_KEY);
|
|
30040
|
+
}
|
|
31251
30041
|
|
|
31252
|
-
|
|
31253
|
-
|
|
31254
|
-
|
|
31255
|
-
|
|
30042
|
+
this.$get = [
|
|
30043
|
+
"$rootScope",
|
|
30044
|
+
"$injector",
|
|
30045
|
+
"$$AnimateRunner",
|
|
30046
|
+
"$$rAFScheduler",
|
|
30047
|
+
"$$animateCache",
|
|
30048
|
+
function (
|
|
30049
|
+
$rootScope,
|
|
30050
|
+
$injector,
|
|
30051
|
+
$$AnimateRunner,
|
|
30052
|
+
$$rAFScheduler,
|
|
30053
|
+
$$animateCache,
|
|
30054
|
+
) {
|
|
30055
|
+
const animationQueue = [];
|
|
30056
|
+
const applyAnimationClasses = applyAnimationClassesFactory();
|
|
31256
30057
|
|
|
31257
|
-
|
|
31258
|
-
|
|
31259
|
-
|
|
31260
|
-
|
|
31261
|
-
|
|
31262
|
-
|
|
31263
|
-
|
|
31264
|
-
|
|
31265
|
-
|
|
31266
|
-
|
|
31267
|
-
|
|
31268
|
-
|
|
31269
|
-
|
|
31270
|
-
|
|
31271
|
-
|
|
30058
|
+
function sortAnimations(animations) {
|
|
30059
|
+
const tree = { children: [] };
|
|
30060
|
+
let i;
|
|
30061
|
+
const lookup = new Map();
|
|
30062
|
+
|
|
30063
|
+
// this is done first beforehand so that the map
|
|
30064
|
+
// is filled with a list of the elements that will be animated
|
|
30065
|
+
// eslint-disable-next-line no-plusplus
|
|
30066
|
+
for (i = 0; i < animations.length; i++) {
|
|
30067
|
+
const animation = animations[i];
|
|
30068
|
+
lookup.set(
|
|
30069
|
+
animation.domNode,
|
|
30070
|
+
(animations[i] = {
|
|
30071
|
+
domNode: animation.domNode,
|
|
30072
|
+
element: animation.element,
|
|
30073
|
+
fn: animation.fn,
|
|
30074
|
+
children: [],
|
|
30075
|
+
}),
|
|
30076
|
+
);
|
|
30077
|
+
}
|
|
31272
30078
|
|
|
31273
|
-
|
|
31274
|
-
|
|
31275
|
-
|
|
30079
|
+
for (i = 0; i < animations.length; i++) {
|
|
30080
|
+
processNode(animations[i]);
|
|
30081
|
+
}
|
|
31276
30082
|
|
|
31277
|
-
|
|
30083
|
+
return flatten(tree);
|
|
31278
30084
|
|
|
31279
|
-
|
|
31280
|
-
|
|
31281
|
-
|
|
30085
|
+
function processNode(entry) {
|
|
30086
|
+
if (entry.processed) return entry;
|
|
30087
|
+
entry.processed = true;
|
|
31282
30088
|
|
|
31283
|
-
|
|
31284
|
-
|
|
31285
|
-
|
|
30089
|
+
const elementNode = entry.domNode;
|
|
30090
|
+
let { parentNode } = elementNode;
|
|
30091
|
+
lookup.set(elementNode, entry);
|
|
31286
30092
|
|
|
31287
|
-
|
|
31288
|
-
|
|
31289
|
-
|
|
31290
|
-
|
|
31291
|
-
|
|
31292
|
-
|
|
31293
|
-
}
|
|
31294
|
-
break;
|
|
30093
|
+
let parentEntry;
|
|
30094
|
+
while (parentNode) {
|
|
30095
|
+
parentEntry = lookup.get(parentNode);
|
|
30096
|
+
if (parentEntry) {
|
|
30097
|
+
if (!parentEntry.processed) {
|
|
30098
|
+
parentEntry = processNode(parentEntry);
|
|
31295
30099
|
}
|
|
31296
|
-
|
|
30100
|
+
break;
|
|
31297
30101
|
}
|
|
31298
|
-
|
|
31299
|
-
(parentEntry || tree).children.push(entry);
|
|
31300
|
-
return entry;
|
|
30102
|
+
parentNode = parentNode.parentNode;
|
|
31301
30103
|
}
|
|
31302
30104
|
|
|
31303
|
-
|
|
31304
|
-
|
|
31305
|
-
|
|
31306
|
-
let i;
|
|
30105
|
+
(parentEntry || tree).children.push(entry);
|
|
30106
|
+
return entry;
|
|
30107
|
+
}
|
|
31307
30108
|
|
|
31308
|
-
|
|
31309
|
-
|
|
31310
|
-
|
|
30109
|
+
function flatten(tree) {
|
|
30110
|
+
const result = [];
|
|
30111
|
+
const queue = [];
|
|
30112
|
+
let i;
|
|
31311
30113
|
|
|
31312
|
-
|
|
31313
|
-
|
|
31314
|
-
|
|
31315
|
-
|
|
31316
|
-
for (i = 0; i < queue.length; i++) {
|
|
31317
|
-
const entry = queue[i];
|
|
31318
|
-
if (remainingLevelEntries <= 0) {
|
|
31319
|
-
remainingLevelEntries = nextLevelEntries;
|
|
31320
|
-
nextLevelEntries = 0;
|
|
31321
|
-
result.push(row);
|
|
31322
|
-
row = [];
|
|
31323
|
-
}
|
|
31324
|
-
row.push(entry);
|
|
31325
|
-
entry.children.forEach((childEntry) => {
|
|
31326
|
-
nextLevelEntries++;
|
|
31327
|
-
queue.push(childEntry);
|
|
31328
|
-
});
|
|
31329
|
-
remainingLevelEntries--;
|
|
31330
|
-
}
|
|
30114
|
+
for (i = 0; i < tree.children.length; i++) {
|
|
30115
|
+
queue.push(tree.children[i]);
|
|
30116
|
+
}
|
|
31331
30117
|
|
|
31332
|
-
|
|
30118
|
+
let remainingLevelEntries = queue.length;
|
|
30119
|
+
let nextLevelEntries = 0;
|
|
30120
|
+
let row = [];
|
|
30121
|
+
|
|
30122
|
+
for (i = 0; i < queue.length; i++) {
|
|
30123
|
+
const entry = queue[i];
|
|
30124
|
+
if (remainingLevelEntries <= 0) {
|
|
30125
|
+
remainingLevelEntries = nextLevelEntries;
|
|
30126
|
+
nextLevelEntries = 0;
|
|
31333
30127
|
result.push(row);
|
|
30128
|
+
row = [];
|
|
31334
30129
|
}
|
|
30130
|
+
row.push(entry);
|
|
30131
|
+
entry.children.forEach((childEntry) => {
|
|
30132
|
+
nextLevelEntries++;
|
|
30133
|
+
queue.push(childEntry);
|
|
30134
|
+
});
|
|
30135
|
+
remainingLevelEntries--;
|
|
30136
|
+
}
|
|
31335
30137
|
|
|
31336
|
-
|
|
30138
|
+
if (row.length) {
|
|
30139
|
+
result.push(row);
|
|
31337
30140
|
}
|
|
31338
|
-
}
|
|
31339
30141
|
|
|
31340
|
-
|
|
31341
|
-
|
|
31342
|
-
|
|
31343
|
-
const isStructural = ["enter", "move", "leave"].indexOf(event) >= 0;
|
|
30142
|
+
return result;
|
|
30143
|
+
}
|
|
30144
|
+
}
|
|
31344
30145
|
|
|
31345
|
-
|
|
31346
|
-
|
|
31347
|
-
|
|
31348
|
-
|
|
31349
|
-
const runner = new $$AnimateRunner({
|
|
31350
|
-
end() {
|
|
31351
|
-
close();
|
|
31352
|
-
},
|
|
31353
|
-
cancel() {
|
|
31354
|
-
close(true);
|
|
31355
|
-
},
|
|
31356
|
-
});
|
|
30146
|
+
// TODO(matsko): document the signature in a better way
|
|
30147
|
+
return function (element, event, options) {
|
|
30148
|
+
options = prepareAnimationOptions(options);
|
|
30149
|
+
const isStructural = ["enter", "move", "leave"].indexOf(event) >= 0;
|
|
31357
30150
|
|
|
31358
|
-
|
|
30151
|
+
// there is no animation at the current moment, however
|
|
30152
|
+
// these runner methods will get later updated with the
|
|
30153
|
+
// methods leading into the driver's end/cancel methods
|
|
30154
|
+
// for now they just stop the animation from starting
|
|
30155
|
+
const runner = new $$AnimateRunner({
|
|
30156
|
+
end() {
|
|
31359
30157
|
close();
|
|
31360
|
-
|
|
31361
|
-
|
|
31362
|
-
|
|
31363
|
-
|
|
31364
|
-
|
|
31365
|
-
mergeClasses$1(options.addClass, options.removeClass),
|
|
31366
|
-
);
|
|
31367
|
-
let { tempClasses } = options;
|
|
31368
|
-
if (tempClasses) {
|
|
31369
|
-
classes += ` ${tempClasses}`;
|
|
31370
|
-
options.tempClasses = null;
|
|
31371
|
-
}
|
|
30158
|
+
},
|
|
30159
|
+
cancel() {
|
|
30160
|
+
close(true);
|
|
30161
|
+
},
|
|
30162
|
+
});
|
|
31372
30163
|
|
|
31373
|
-
|
|
31374
|
-
|
|
31375
|
-
|
|
31376
|
-
|
|
31377
|
-
);
|
|
31378
|
-
}
|
|
30164
|
+
if (!drivers.length) {
|
|
30165
|
+
close();
|
|
30166
|
+
return runner;
|
|
30167
|
+
}
|
|
31379
30168
|
|
|
31380
|
-
|
|
30169
|
+
let classes = mergeClasses$1(
|
|
30170
|
+
element.attr("class"),
|
|
30171
|
+
mergeClasses$1(options.addClass, options.removeClass),
|
|
30172
|
+
);
|
|
30173
|
+
let { tempClasses } = options;
|
|
30174
|
+
if (tempClasses) {
|
|
30175
|
+
classes += ` ${tempClasses}`;
|
|
30176
|
+
options.tempClasses = null;
|
|
30177
|
+
}
|
|
31381
30178
|
|
|
31382
|
-
|
|
31383
|
-
|
|
31384
|
-
|
|
31385
|
-
|
|
31386
|
-
|
|
31387
|
-
|
|
31388
|
-
structural: isStructural,
|
|
31389
|
-
options,
|
|
31390
|
-
beforeStart,
|
|
31391
|
-
close,
|
|
31392
|
-
});
|
|
30179
|
+
if (isStructural) {
|
|
30180
|
+
element.data(
|
|
30181
|
+
PREPARE_CLASSES_KEY,
|
|
30182
|
+
`ng-${event}${PREPARE_CLASS_SUFFIX}`,
|
|
30183
|
+
);
|
|
30184
|
+
}
|
|
31393
30185
|
|
|
31394
|
-
|
|
30186
|
+
setRunner(element, runner);
|
|
31395
30187
|
|
|
31396
|
-
|
|
31397
|
-
//
|
|
31398
|
-
//
|
|
31399
|
-
|
|
30188
|
+
animationQueue.push({
|
|
30189
|
+
// this data is used by the postDigest code and passed into
|
|
30190
|
+
// the driver step function
|
|
30191
|
+
element,
|
|
30192
|
+
classes,
|
|
30193
|
+
event,
|
|
30194
|
+
structural: isStructural,
|
|
30195
|
+
options,
|
|
30196
|
+
beforeStart,
|
|
30197
|
+
close,
|
|
30198
|
+
});
|
|
31400
30199
|
|
|
31401
|
-
|
|
31402
|
-
|
|
31403
|
-
|
|
31404
|
-
|
|
31405
|
-
|
|
31406
|
-
|
|
31407
|
-
|
|
31408
|
-
|
|
31409
|
-
|
|
31410
|
-
|
|
31411
|
-
|
|
31412
|
-
|
|
30200
|
+
element.on("$destroy", handleDestroyedElement);
|
|
30201
|
+
|
|
30202
|
+
// we only want there to be one function called within the post digest
|
|
30203
|
+
// block. This way we can group animations for all the animations that
|
|
30204
|
+
// were apart of the same postDigest flush call.
|
|
30205
|
+
if (animationQueue.length > 1) return runner;
|
|
30206
|
+
|
|
30207
|
+
$rootScope.$$postDigest(() => {
|
|
30208
|
+
const animations = [];
|
|
30209
|
+
forEach(animationQueue, (entry) => {
|
|
30210
|
+
// the element was destroyed early on which removed the runner
|
|
30211
|
+
// form its storage. This means we can't animate this element
|
|
30212
|
+
// at all and it already has been closed due to destruction.
|
|
30213
|
+
if (getRunner(entry.element)) {
|
|
30214
|
+
animations.push(entry);
|
|
30215
|
+
} else {
|
|
30216
|
+
entry.close();
|
|
30217
|
+
}
|
|
30218
|
+
});
|
|
31413
30219
|
|
|
31414
|
-
|
|
31415
|
-
|
|
30220
|
+
// now any future animations will be in another postDigest
|
|
30221
|
+
animationQueue.length = 0;
|
|
31416
30222
|
|
|
31417
|
-
|
|
31418
|
-
|
|
30223
|
+
const groupedAnimations = groupAnimations(animations);
|
|
30224
|
+
const toBeSortedAnimations = [];
|
|
31419
30225
|
|
|
31420
|
-
|
|
31421
|
-
|
|
31422
|
-
|
|
31423
|
-
|
|
31424
|
-
|
|
30226
|
+
forEach(groupedAnimations, (animationEntry) => {
|
|
30227
|
+
const element = animationEntry.from
|
|
30228
|
+
? animationEntry.from.element
|
|
30229
|
+
: animationEntry.element;
|
|
30230
|
+
let extraClasses = options.addClass;
|
|
31425
30231
|
|
|
31426
|
-
|
|
31427
|
-
|
|
31428
|
-
|
|
31429
|
-
|
|
31430
|
-
|
|
31431
|
-
|
|
31432
|
-
|
|
31433
|
-
|
|
30232
|
+
extraClasses =
|
|
30233
|
+
(extraClasses ? `${extraClasses} ` : "") + NG_ANIMATE_CLASSNAME;
|
|
30234
|
+
const cacheKey = $$animateCache.cacheKey(
|
|
30235
|
+
element[0],
|
|
30236
|
+
animationEntry.event,
|
|
30237
|
+
extraClasses,
|
|
30238
|
+
options.removeClass,
|
|
30239
|
+
);
|
|
31434
30240
|
|
|
31435
|
-
|
|
31436
|
-
|
|
31437
|
-
|
|
31438
|
-
|
|
31439
|
-
|
|
31440
|
-
|
|
31441
|
-
|
|
31442
|
-
|
|
31443
|
-
|
|
31444
|
-
|
|
31445
|
-
|
|
31446
|
-
|
|
31447
|
-
|
|
31448
|
-
|
|
31449
|
-
|
|
31450
|
-
|
|
31451
|
-
|
|
31452
|
-
|
|
30241
|
+
toBeSortedAnimations.push({
|
|
30242
|
+
element,
|
|
30243
|
+
domNode: getDomNode(element),
|
|
30244
|
+
fn: function triggerAnimationStart() {
|
|
30245
|
+
let startAnimationFn;
|
|
30246
|
+
const closeFn = animationEntry.close;
|
|
30247
|
+
|
|
30248
|
+
// in the event that we've cached the animation status for this element
|
|
30249
|
+
// and it's in fact an invalid animation (something that has duration = 0)
|
|
30250
|
+
// then we should skip all the heavy work from here on
|
|
30251
|
+
if (
|
|
30252
|
+
$$animateCache.containsCachedAnimationWithoutDuration(
|
|
30253
|
+
cacheKey,
|
|
30254
|
+
)
|
|
30255
|
+
) {
|
|
30256
|
+
closeFn();
|
|
30257
|
+
return;
|
|
30258
|
+
}
|
|
31453
30259
|
|
|
31454
|
-
|
|
31455
|
-
|
|
31456
|
-
|
|
31457
|
-
|
|
31458
|
-
|
|
31459
|
-
|
|
31460
|
-
|
|
31461
|
-
|
|
31462
|
-
|
|
31463
|
-
|
|
31464
|
-
|
|
31465
|
-
|
|
31466
|
-
|
|
31467
|
-
|
|
31468
|
-
|
|
31469
|
-
}
|
|
30260
|
+
// it's important that we apply the `ng-animate` CSS class and the
|
|
30261
|
+
// temporary classes before we do any driver invoking since these
|
|
30262
|
+
// CSS classes may be required for proper CSS detection.
|
|
30263
|
+
animationEntry.beforeStart();
|
|
30264
|
+
|
|
30265
|
+
// in the event that the element was removed before the digest runs or
|
|
30266
|
+
// during the RAF sequencing then we should not trigger the animation.
|
|
30267
|
+
const targetElement = animationEntry.anchors
|
|
30268
|
+
? animationEntry.from.element || animationEntry.to.element
|
|
30269
|
+
: animationEntry.element;
|
|
30270
|
+
|
|
30271
|
+
if (getRunner(targetElement)) {
|
|
30272
|
+
const operation = invokeFirstDriver(animationEntry);
|
|
30273
|
+
if (operation) {
|
|
30274
|
+
startAnimationFn = operation.start;
|
|
31470
30275
|
}
|
|
30276
|
+
}
|
|
31471
30277
|
|
|
31472
|
-
|
|
31473
|
-
|
|
31474
|
-
|
|
31475
|
-
|
|
31476
|
-
|
|
31477
|
-
|
|
31478
|
-
|
|
31479
|
-
|
|
31480
|
-
|
|
31481
|
-
|
|
31482
|
-
});
|
|
30278
|
+
if (!startAnimationFn) {
|
|
30279
|
+
closeFn();
|
|
30280
|
+
} else {
|
|
30281
|
+
const animationRunner = startAnimationFn();
|
|
30282
|
+
animationRunner.done((status) => {
|
|
30283
|
+
closeFn(!status);
|
|
30284
|
+
});
|
|
30285
|
+
updateAnimationRunners(animationEntry, animationRunner);
|
|
30286
|
+
}
|
|
30287
|
+
},
|
|
31483
30288
|
});
|
|
30289
|
+
});
|
|
31484
30290
|
|
|
31485
|
-
|
|
31486
|
-
|
|
31487
|
-
|
|
31488
|
-
|
|
31489
|
-
|
|
31490
|
-
|
|
31491
|
-
|
|
31492
|
-
|
|
31493
|
-
|
|
31494
|
-
|
|
31495
|
-
|
|
31496
|
-
|
|
31497
|
-
|
|
31498
|
-
|
|
31499
|
-
|
|
31500
|
-
|
|
31501
|
-
|
|
31502
|
-
|
|
31503
|
-
|
|
31504
|
-
|
|
30291
|
+
// we need to sort each of the animations in order of parent to child
|
|
30292
|
+
// relationships. This ensures that the child classes are applied at the
|
|
30293
|
+
// right time.
|
|
30294
|
+
const finalAnimations = sortAnimations(toBeSortedAnimations);
|
|
30295
|
+
for (let i = 0; i < finalAnimations.length; i++) {
|
|
30296
|
+
const innerArray = finalAnimations[i];
|
|
30297
|
+
for (let j = 0; j < innerArray.length; j++) {
|
|
30298
|
+
const entry = innerArray[j];
|
|
30299
|
+
const { element } = entry;
|
|
30300
|
+
|
|
30301
|
+
// the RAFScheduler code only uses functions
|
|
30302
|
+
finalAnimations[i][j] = entry.fn;
|
|
30303
|
+
|
|
30304
|
+
// the first row of elements shouldn't have a prepare-class added to them
|
|
30305
|
+
// since the elements are at the top of the animation hierarchy and they
|
|
30306
|
+
// will be applied without a RAF having to pass...
|
|
30307
|
+
if (i === 0) {
|
|
30308
|
+
element.removeData(PREPARE_CLASSES_KEY);
|
|
30309
|
+
continue;
|
|
30310
|
+
}
|
|
31505
30311
|
|
|
31506
|
-
|
|
31507
|
-
|
|
31508
|
-
|
|
31509
|
-
}
|
|
30312
|
+
const prepareClassName = element.data(PREPARE_CLASSES_KEY);
|
|
30313
|
+
if (prepareClassName) {
|
|
30314
|
+
element[0].classList.add(prepareClassName);
|
|
31510
30315
|
}
|
|
31511
30316
|
}
|
|
30317
|
+
}
|
|
31512
30318
|
|
|
31513
|
-
|
|
30319
|
+
$$rAFScheduler(finalAnimations);
|
|
30320
|
+
});
|
|
30321
|
+
|
|
30322
|
+
return runner;
|
|
30323
|
+
|
|
30324
|
+
// TODO(matsko): change to reference nodes
|
|
30325
|
+
function getAnchorNodes(node) {
|
|
30326
|
+
const SELECTOR = `[${NG_ANIMATE_REF_ATTR}]`;
|
|
30327
|
+
const items = node.hasAttribute(NG_ANIMATE_REF_ATTR)
|
|
30328
|
+
? [node]
|
|
30329
|
+
: node.querySelectorAll(SELECTOR);
|
|
30330
|
+
const anchors = [];
|
|
30331
|
+
forEach(items, (node) => {
|
|
30332
|
+
const attr = node.getAttribute(NG_ANIMATE_REF_ATTR);
|
|
30333
|
+
if (attr && attr.length) {
|
|
30334
|
+
anchors.push(node);
|
|
30335
|
+
}
|
|
31514
30336
|
});
|
|
30337
|
+
return anchors;
|
|
30338
|
+
}
|
|
30339
|
+
|
|
30340
|
+
function groupAnimations(animations) {
|
|
30341
|
+
const preparedAnimations = [];
|
|
30342
|
+
const refLookup = {};
|
|
30343
|
+
forEach(animations, (animation, index) => {
|
|
30344
|
+
const { element } = animation;
|
|
30345
|
+
const node = getDomNode(element);
|
|
30346
|
+
const { event } = animation;
|
|
30347
|
+
const enterOrMove = ["enter", "move"].indexOf(event) >= 0;
|
|
30348
|
+
const anchorNodes = animation.structural
|
|
30349
|
+
? getAnchorNodes(node)
|
|
30350
|
+
: [];
|
|
31515
30351
|
|
|
31516
|
-
|
|
30352
|
+
if (anchorNodes.length) {
|
|
30353
|
+
const direction = enterOrMove ? "to" : "from";
|
|
31517
30354
|
|
|
31518
|
-
|
|
31519
|
-
|
|
31520
|
-
|
|
31521
|
-
|
|
31522
|
-
|
|
31523
|
-
|
|
31524
|
-
|
|
31525
|
-
|
|
31526
|
-
|
|
31527
|
-
|
|
31528
|
-
|
|
31529
|
-
|
|
31530
|
-
});
|
|
31531
|
-
return anchors;
|
|
31532
|
-
}
|
|
31533
|
-
|
|
31534
|
-
function groupAnimations(animations) {
|
|
31535
|
-
const preparedAnimations = [];
|
|
31536
|
-
const refLookup = {};
|
|
31537
|
-
forEach(animations, (animation, index) => {
|
|
31538
|
-
const { element } = animation;
|
|
31539
|
-
const node = getDomNode(element);
|
|
31540
|
-
const { event } = animation;
|
|
31541
|
-
const enterOrMove = ["enter", "move"].indexOf(event) >= 0;
|
|
31542
|
-
const anchorNodes = animation.structural
|
|
31543
|
-
? getAnchorNodes(node)
|
|
31544
|
-
: [];
|
|
31545
|
-
|
|
31546
|
-
if (anchorNodes.length) {
|
|
31547
|
-
const direction = enterOrMove ? "to" : "from";
|
|
31548
|
-
|
|
31549
|
-
forEach(anchorNodes, (anchor) => {
|
|
31550
|
-
const key = anchor.getAttribute(NG_ANIMATE_REF_ATTR);
|
|
31551
|
-
refLookup[key] = refLookup[key] || {};
|
|
31552
|
-
refLookup[key][direction] = {
|
|
31553
|
-
animationID: index,
|
|
31554
|
-
element: jqLite(anchor),
|
|
31555
|
-
};
|
|
31556
|
-
});
|
|
31557
|
-
} else {
|
|
31558
|
-
preparedAnimations.push(animation);
|
|
31559
|
-
}
|
|
31560
|
-
});
|
|
30355
|
+
forEach(anchorNodes, (anchor) => {
|
|
30356
|
+
const key = anchor.getAttribute(NG_ANIMATE_REF_ATTR);
|
|
30357
|
+
refLookup[key] = refLookup[key] || {};
|
|
30358
|
+
refLookup[key][direction] = {
|
|
30359
|
+
animationID: index,
|
|
30360
|
+
element: jqLite(anchor),
|
|
30361
|
+
};
|
|
30362
|
+
});
|
|
30363
|
+
} else {
|
|
30364
|
+
preparedAnimations.push(animation);
|
|
30365
|
+
}
|
|
30366
|
+
});
|
|
31561
30367
|
|
|
31562
|
-
|
|
31563
|
-
|
|
31564
|
-
|
|
31565
|
-
|
|
31566
|
-
|
|
31567
|
-
|
|
31568
|
-
|
|
31569
|
-
|
|
31570
|
-
|
|
31571
|
-
|
|
31572
|
-
|
|
31573
|
-
|
|
31574
|
-
|
|
31575
|
-
|
|
31576
|
-
}
|
|
31577
|
-
return;
|
|
30368
|
+
const usedIndicesLookup = {};
|
|
30369
|
+
const anchorGroups = {};
|
|
30370
|
+
Object.values(refLookup).forEach((operations) => {
|
|
30371
|
+
const { from } = operations;
|
|
30372
|
+
const { to } = operations;
|
|
30373
|
+
|
|
30374
|
+
if (!from || !to) {
|
|
30375
|
+
// only one of these is set therefore we can't have an
|
|
30376
|
+
// anchor animation since all three pieces are required
|
|
30377
|
+
const index = from ? from.animationID : to.animationID;
|
|
30378
|
+
const indexKey = index.toString();
|
|
30379
|
+
if (!usedIndicesLookup[indexKey]) {
|
|
30380
|
+
usedIndicesLookup[indexKey] = true;
|
|
30381
|
+
preparedAnimations.push(animations[index]);
|
|
31578
30382
|
}
|
|
30383
|
+
return;
|
|
30384
|
+
}
|
|
31579
30385
|
|
|
31580
|
-
|
|
31581
|
-
|
|
31582
|
-
|
|
31583
|
-
|
|
31584
|
-
|
|
31585
|
-
|
|
31586
|
-
|
|
31587
|
-
|
|
31588
|
-
|
|
31589
|
-
|
|
31590
|
-
|
|
31591
|
-
|
|
31592
|
-
|
|
31593
|
-
|
|
31594
|
-
|
|
31595
|
-
|
|
31596
|
-
|
|
31597
|
-
|
|
31598
|
-
|
|
31599
|
-
|
|
31600
|
-
|
|
31601
|
-
|
|
30386
|
+
const fromAnimation = animations[from.animationID];
|
|
30387
|
+
const toAnimation = animations[to.animationID];
|
|
30388
|
+
const lookupKey = from.animationID.toString();
|
|
30389
|
+
if (!anchorGroups[lookupKey]) {
|
|
30390
|
+
const group = (anchorGroups[lookupKey] = {
|
|
30391
|
+
structural: true,
|
|
30392
|
+
beforeStart() {
|
|
30393
|
+
fromAnimation.beforeStart();
|
|
30394
|
+
toAnimation.beforeStart();
|
|
30395
|
+
},
|
|
30396
|
+
close() {
|
|
30397
|
+
fromAnimation.close();
|
|
30398
|
+
toAnimation.close();
|
|
30399
|
+
},
|
|
30400
|
+
classes: cssClassesIntersection(
|
|
30401
|
+
fromAnimation.classes,
|
|
30402
|
+
toAnimation.classes,
|
|
30403
|
+
),
|
|
30404
|
+
from: fromAnimation,
|
|
30405
|
+
to: toAnimation,
|
|
30406
|
+
anchors: [], // TODO(matsko): change to reference nodes
|
|
30407
|
+
});
|
|
31602
30408
|
|
|
31603
|
-
|
|
31604
|
-
|
|
31605
|
-
|
|
31606
|
-
|
|
31607
|
-
|
|
31608
|
-
|
|
31609
|
-
|
|
31610
|
-
|
|
31611
|
-
}
|
|
30409
|
+
// the anchor animations require that the from and to elements both have at least
|
|
30410
|
+
// one shared CSS class which effectively marries the two elements together to use
|
|
30411
|
+
// the same animation driver and to properly sequence the anchor animation.
|
|
30412
|
+
if (group.classes.length) {
|
|
30413
|
+
preparedAnimations.push(group);
|
|
30414
|
+
} else {
|
|
30415
|
+
preparedAnimations.push(fromAnimation);
|
|
30416
|
+
preparedAnimations.push(toAnimation);
|
|
31612
30417
|
}
|
|
30418
|
+
}
|
|
31613
30419
|
|
|
31614
|
-
|
|
31615
|
-
|
|
31616
|
-
|
|
31617
|
-
});
|
|
30420
|
+
anchorGroups[lookupKey].anchors.push({
|
|
30421
|
+
out: from.element,
|
|
30422
|
+
in: to.element,
|
|
31618
30423
|
});
|
|
30424
|
+
});
|
|
31619
30425
|
|
|
31620
|
-
|
|
31621
|
-
|
|
30426
|
+
return preparedAnimations;
|
|
30427
|
+
}
|
|
31622
30428
|
|
|
31623
|
-
|
|
31624
|
-
|
|
31625
|
-
|
|
31626
|
-
|
|
30429
|
+
function cssClassesIntersection(a, b) {
|
|
30430
|
+
a = a.split(" ");
|
|
30431
|
+
b = b.split(" ");
|
|
30432
|
+
const matches = [];
|
|
31627
30433
|
|
|
31628
|
-
|
|
31629
|
-
|
|
31630
|
-
|
|
30434
|
+
for (let i = 0; i < a.length; i++) {
|
|
30435
|
+
const aa = a[i];
|
|
30436
|
+
if (aa.substring(0, 3) === "ng-") continue;
|
|
31631
30437
|
|
|
31632
|
-
|
|
31633
|
-
|
|
31634
|
-
|
|
31635
|
-
|
|
31636
|
-
}
|
|
30438
|
+
for (let j = 0; j < b.length; j++) {
|
|
30439
|
+
if (aa === b[j]) {
|
|
30440
|
+
matches.push(aa);
|
|
30441
|
+
break;
|
|
31637
30442
|
}
|
|
31638
30443
|
}
|
|
31639
|
-
|
|
31640
|
-
return matches.join(" ");
|
|
31641
30444
|
}
|
|
31642
30445
|
|
|
31643
|
-
|
|
31644
|
-
|
|
31645
|
-
// may attempt more elements, but custom drivers are more particular
|
|
31646
|
-
for (let i = drivers.length - 1; i >= 0; i--) {
|
|
31647
|
-
const driverName = drivers[i];
|
|
31648
|
-
const factory = $injector.get(driverName);
|
|
31649
|
-
const driver = factory(animationDetails);
|
|
31650
|
-
if (driver) {
|
|
31651
|
-
return driver;
|
|
31652
|
-
}
|
|
31653
|
-
}
|
|
31654
|
-
}
|
|
30446
|
+
return matches.join(" ");
|
|
30447
|
+
}
|
|
31655
30448
|
|
|
31656
|
-
|
|
31657
|
-
|
|
31658
|
-
|
|
31659
|
-
|
|
31660
|
-
|
|
31661
|
-
|
|
31662
|
-
|
|
31663
|
-
|
|
30449
|
+
function invokeFirstDriver(animationDetails) {
|
|
30450
|
+
// we loop in reverse order since the more general drivers (like CSS and JS)
|
|
30451
|
+
// may attempt more elements, but custom drivers are more particular
|
|
30452
|
+
for (let i = drivers.length - 1; i >= 0; i--) {
|
|
30453
|
+
const driverName = drivers[i];
|
|
30454
|
+
const factory = $injector.get(driverName);
|
|
30455
|
+
const driver = factory(animationDetails);
|
|
30456
|
+
if (driver) {
|
|
30457
|
+
return driver;
|
|
31664
30458
|
}
|
|
31665
30459
|
}
|
|
30460
|
+
}
|
|
31666
30461
|
|
|
31667
|
-
|
|
31668
|
-
|
|
31669
|
-
|
|
31670
|
-
|
|
31671
|
-
|
|
31672
|
-
|
|
31673
|
-
|
|
30462
|
+
function beforeStart() {
|
|
30463
|
+
tempClasses =
|
|
30464
|
+
(tempClasses ? `${tempClasses} ` : "") + NG_ANIMATE_CLASSNAME;
|
|
30465
|
+
element.className += ` ${tempClasses}`;
|
|
30466
|
+
let prepareClassName = element.data(PREPARE_CLASSES_KEY);
|
|
30467
|
+
if (prepareClassName) {
|
|
30468
|
+
element[0].classList.remove(prepareClassName);
|
|
30469
|
+
prepareClassName = null;
|
|
30470
|
+
}
|
|
30471
|
+
}
|
|
31674
30472
|
|
|
31675
|
-
|
|
31676
|
-
|
|
31677
|
-
|
|
31678
|
-
|
|
30473
|
+
function updateAnimationRunners(animation, newRunner) {
|
|
30474
|
+
if (animation.from && animation.to) {
|
|
30475
|
+
update(animation.from.element);
|
|
30476
|
+
update(animation.to.element);
|
|
30477
|
+
} else {
|
|
30478
|
+
update(animation.element);
|
|
31679
30479
|
}
|
|
31680
30480
|
|
|
31681
|
-
function
|
|
30481
|
+
function update(element) {
|
|
31682
30482
|
const runner = getRunner(element);
|
|
31683
|
-
if (runner
|
|
31684
|
-
runner.end();
|
|
31685
|
-
}
|
|
30483
|
+
if (runner) runner.setHost(newRunner);
|
|
31686
30484
|
}
|
|
30485
|
+
}
|
|
31687
30486
|
|
|
31688
|
-
|
|
31689
|
-
|
|
31690
|
-
|
|
30487
|
+
function handleDestroyedElement() {
|
|
30488
|
+
const runner = getRunner(element);
|
|
30489
|
+
if (runner && (event !== "leave" || !options.$$domOperationFired)) {
|
|
30490
|
+
runner.end();
|
|
30491
|
+
}
|
|
30492
|
+
}
|
|
31691
30493
|
|
|
31692
|
-
|
|
31693
|
-
|
|
31694
|
-
|
|
30494
|
+
function close(rejected) {
|
|
30495
|
+
element.off("$destroy", handleDestroyedElement);
|
|
30496
|
+
removeRunner(element);
|
|
31695
30497
|
|
|
31696
|
-
|
|
31697
|
-
|
|
31698
|
-
|
|
31699
|
-
.forEach((cls) => element[0].classList.remove(cls));
|
|
31700
|
-
}
|
|
30498
|
+
applyAnimationClasses(element, options);
|
|
30499
|
+
applyAnimationStyles(element, options);
|
|
30500
|
+
options.domOperation();
|
|
31701
30501
|
|
|
31702
|
-
|
|
30502
|
+
if (tempClasses) {
|
|
30503
|
+
tempClasses
|
|
30504
|
+
.split(" ")
|
|
30505
|
+
.forEach((cls) => element[0].classList.remove(cls));
|
|
31703
30506
|
}
|
|
31704
|
-
|
|
31705
|
-
|
|
31706
|
-
|
|
31707
|
-
|
|
31708
|
-
|
|
30507
|
+
|
|
30508
|
+
runner.complete(!rejected);
|
|
30509
|
+
}
|
|
30510
|
+
};
|
|
30511
|
+
},
|
|
30512
|
+
];
|
|
30513
|
+
}
|
|
31709
30514
|
|
|
31710
30515
|
const $$rAFSchedulerFactory = [
|
|
31711
30516
|
() => {
|
|
@@ -33072,14 +31877,12 @@
|
|
|
33072
31877
|
"$$AnimateRunner",
|
|
33073
31878
|
"$timeout",
|
|
33074
31879
|
"$$animateCache",
|
|
33075
|
-
"$$forceReflow",
|
|
33076
31880
|
"$$rAFScheduler",
|
|
33077
31881
|
"$$animateQueue",
|
|
33078
31882
|
function (
|
|
33079
31883
|
$$AnimateRunner,
|
|
33080
31884
|
$timeout,
|
|
33081
31885
|
$$animateCache,
|
|
33082
|
-
$$forceReflow,
|
|
33083
31886
|
$$rAFScheduler,
|
|
33084
31887
|
$$animateQueue,
|
|
33085
31888
|
) {
|
|
@@ -33162,8 +31965,16 @@
|
|
|
33162
31965
|
$$animateCache.flush();
|
|
33163
31966
|
|
|
33164
31967
|
// DO NOT REMOVE THIS LINE OR REFACTOR OUT THE `pageWidth` variable.
|
|
33165
|
-
//
|
|
33166
|
-
|
|
31968
|
+
// the line below will force the browser to perform a repaint so
|
|
31969
|
+
// that all the animated elements within the animation frame will
|
|
31970
|
+
// be properly updated and drawn on screen. This is required to
|
|
31971
|
+
// ensure that the preparation animation is properly flushed so that
|
|
31972
|
+
// the active state picks up from there. DO NOT REMOVE THIS LINE.
|
|
31973
|
+
// DO NOT OPTIMIZE THIS LINE. THE MINIFIER WILL REMOVE IT OTHERWISE WHICH
|
|
31974
|
+
// WILL RESULT IN AN UNPREDICTABLE BUG THAT IS VERY HARD TO TRACK DOWN AND
|
|
31975
|
+
// WILL TAKE YEARS AWAY FROM YOUR LIFE.
|
|
31976
|
+
|
|
31977
|
+
const pageWidth = document.body.offsetWidth + 1;
|
|
33167
31978
|
|
|
33168
31979
|
// we use a for loop to ensure that if the queue is changed
|
|
33169
31980
|
// during this looping then it will consider new requests
|
|
@@ -36800,7 +35611,6 @@
|
|
|
36800
35611
|
$$isDocumentHidden: $$IsDocumentHiddenProvider,
|
|
36801
35612
|
$exceptionHandler: $ExceptionHandlerProvider,
|
|
36802
35613
|
$filter: $FilterProvider,
|
|
36803
|
-
$$forceReflow: $$ForceReflowProvider,
|
|
36804
35614
|
$interpolate: $InterpolateProvider,
|
|
36805
35615
|
$interval: $IntervalProvider,
|
|
36806
35616
|
$$intervalFactory: $$IntervalFactoryProvider,
|