@angular-wave/angular.ts 0.0.1

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.
Files changed (231) hide show
  1. package/.eslintignore +1 -0
  2. package/.eslintrc.cjs +29 -0
  3. package/.github/workflows/playwright.yml +27 -0
  4. package/CHANGELOG.md +17974 -0
  5. package/CODE_OF_CONDUCT.md +3 -0
  6. package/CONTRIBUTING.md +246 -0
  7. package/DEVELOPERS.md +488 -0
  8. package/LICENSE +22 -0
  9. package/Makefile +31 -0
  10. package/README.md +115 -0
  11. package/RELEASE.md +98 -0
  12. package/SECURITY.md +16 -0
  13. package/TRIAGING.md +135 -0
  14. package/css/angular.css +22 -0
  15. package/dist/angular-ts.cjs.js +36843 -0
  16. package/dist/angular-ts.esm.js +36841 -0
  17. package/dist/angular-ts.umd.js +36848 -0
  18. package/dist/build/angular-animate.js +4272 -0
  19. package/dist/build/angular-aria.js +426 -0
  20. package/dist/build/angular-message-format.js +1072 -0
  21. package/dist/build/angular-messages.js +829 -0
  22. package/dist/build/angular-mocks.js +3757 -0
  23. package/dist/build/angular-parse-ext.js +1275 -0
  24. package/dist/build/angular-resource.js +911 -0
  25. package/dist/build/angular-route.js +1266 -0
  26. package/dist/build/angular-sanitize.js +891 -0
  27. package/dist/build/angular-touch.js +368 -0
  28. package/dist/build/angular.js +36600 -0
  29. package/e2e/unit.spec.ts +15 -0
  30. package/images/android-chrome-192x192.png +0 -0
  31. package/images/android-chrome-512x512.png +0 -0
  32. package/images/apple-touch-icon.png +0 -0
  33. package/images/favicon-16x16.png +0 -0
  34. package/images/favicon-32x32.png +0 -0
  35. package/images/favicon.ico +0 -0
  36. package/images/site.webmanifest +1 -0
  37. package/index.html +104 -0
  38. package/package.json +47 -0
  39. package/playwright.config.ts +78 -0
  40. package/public/circle.html +1 -0
  41. package/public/my_child_directive.html +1 -0
  42. package/public/my_directive.html +1 -0
  43. package/public/my_other_directive.html +1 -0
  44. package/public/test.html +1 -0
  45. package/rollup.config.js +31 -0
  46. package/src/animations/animateCache.js +55 -0
  47. package/src/animations/animateChildrenDirective.js +105 -0
  48. package/src/animations/animateCss.js +1139 -0
  49. package/src/animations/animateCssDriver.js +291 -0
  50. package/src/animations/animateJs.js +367 -0
  51. package/src/animations/animateJsDriver.js +67 -0
  52. package/src/animations/animateQueue.js +851 -0
  53. package/src/animations/animation.js +506 -0
  54. package/src/animations/module.js +779 -0
  55. package/src/animations/ngAnimateSwap.js +119 -0
  56. package/src/animations/rafScheduler.js +50 -0
  57. package/src/animations/shared.js +378 -0
  58. package/src/constants.js +20 -0
  59. package/src/core/animate.js +845 -0
  60. package/src/core/animateCss.js +73 -0
  61. package/src/core/animateRunner.js +195 -0
  62. package/src/core/attributes.js +199 -0
  63. package/src/core/cache.js +45 -0
  64. package/src/core/compile.js +4727 -0
  65. package/src/core/controller.js +225 -0
  66. package/src/core/exceptionHandler.js +63 -0
  67. package/src/core/filter.js +146 -0
  68. package/src/core/interpolate.js +442 -0
  69. package/src/core/interval.js +188 -0
  70. package/src/core/intervalFactory.js +57 -0
  71. package/src/core/location.js +1086 -0
  72. package/src/core/parser/parse.js +2562 -0
  73. package/src/core/parser/parse.md +13 -0
  74. package/src/core/q.js +746 -0
  75. package/src/core/rootScope.js +1596 -0
  76. package/src/core/sanitizeUri.js +85 -0
  77. package/src/core/sce.js +1161 -0
  78. package/src/core/taskTrackerFactory.js +125 -0
  79. package/src/core/timeout.js +121 -0
  80. package/src/core/urlUtils.js +187 -0
  81. package/src/core/utils.js +1349 -0
  82. package/src/directive/a.js +37 -0
  83. package/src/directive/attrs.js +283 -0
  84. package/src/directive/bind.js +51 -0
  85. package/src/directive/bind.md +142 -0
  86. package/src/directive/change.js +12 -0
  87. package/src/directive/change.md +25 -0
  88. package/src/directive/cloak.js +12 -0
  89. package/src/directive/cloak.md +24 -0
  90. package/src/directive/events.js +75 -0
  91. package/src/directive/events.md +166 -0
  92. package/src/directive/form.js +725 -0
  93. package/src/directive/init.js +15 -0
  94. package/src/directive/init.md +41 -0
  95. package/src/directive/input.js +1783 -0
  96. package/src/directive/list.js +46 -0
  97. package/src/directive/list.md +22 -0
  98. package/src/directive/ngClass.js +249 -0
  99. package/src/directive/ngController.js +64 -0
  100. package/src/directive/ngCsp.js +82 -0
  101. package/src/directive/ngIf.js +134 -0
  102. package/src/directive/ngInclude.js +217 -0
  103. package/src/directive/ngModel.js +1356 -0
  104. package/src/directive/ngModelOptions.js +509 -0
  105. package/src/directive/ngOptions.js +670 -0
  106. package/src/directive/ngRef.js +90 -0
  107. package/src/directive/ngRepeat.js +650 -0
  108. package/src/directive/ngShowHide.js +255 -0
  109. package/src/directive/ngSwitch.js +178 -0
  110. package/src/directive/ngTransclude.js +98 -0
  111. package/src/directive/non-bindable.js +11 -0
  112. package/src/directive/non-bindable.md +17 -0
  113. package/src/directive/script.js +30 -0
  114. package/src/directive/select.js +624 -0
  115. package/src/directive/style.js +25 -0
  116. package/src/directive/style.md +23 -0
  117. package/src/directive/validators.js +329 -0
  118. package/src/exts/aria.js +544 -0
  119. package/src/exts/messages.js +852 -0
  120. package/src/filters/filter.js +207 -0
  121. package/src/filters/filter.md +69 -0
  122. package/src/filters/filters.js +239 -0
  123. package/src/filters/json.md +16 -0
  124. package/src/filters/limit-to.js +43 -0
  125. package/src/filters/limit-to.md +19 -0
  126. package/src/filters/order-by.js +183 -0
  127. package/src/filters/order-by.md +83 -0
  128. package/src/index.js +13 -0
  129. package/src/injector.js +1034 -0
  130. package/src/jqLite.js +1117 -0
  131. package/src/loader.js +1320 -0
  132. package/src/public.js +215 -0
  133. package/src/routeToRegExp.js +41 -0
  134. package/src/services/anchorScroll.js +135 -0
  135. package/src/services/browser.js +321 -0
  136. package/src/services/cacheFactory.js +398 -0
  137. package/src/services/cookieReader.js +72 -0
  138. package/src/services/document.js +64 -0
  139. package/src/services/http.js +1537 -0
  140. package/src/services/httpBackend.js +206 -0
  141. package/src/services/log.js +160 -0
  142. package/src/services/templateRequest.js +139 -0
  143. package/test/angular.spec.js +2153 -0
  144. package/test/aria/aria.spec.js +1245 -0
  145. package/test/binding.spec.js +504 -0
  146. package/test/build-test.html +14 -0
  147. package/test/injector.spec.js +2327 -0
  148. package/test/jasmine/jasmine-5.1.2/boot0.js +65 -0
  149. package/test/jasmine/jasmine-5.1.2/boot1.js +133 -0
  150. package/test/jasmine/jasmine-5.1.2/jasmine-html.js +963 -0
  151. package/test/jasmine/jasmine-5.1.2/jasmine.css +320 -0
  152. package/test/jasmine/jasmine-5.1.2/jasmine.js +10824 -0
  153. package/test/jasmine/jasmine-5.1.2/jasmine_favicon.png +0 -0
  154. package/test/jasmine/jasmine-browser.json +17 -0
  155. package/test/jasmine/jasmine.json +9 -0
  156. package/test/jqlite.spec.js +2133 -0
  157. package/test/loader.spec.js +219 -0
  158. package/test/messages/messages.spec.js +1146 -0
  159. package/test/min-err.spec.js +174 -0
  160. package/test/mock-test.html +13 -0
  161. package/test/module-test.html +15 -0
  162. package/test/ng/anomate.spec.js +606 -0
  163. package/test/ng/cache-factor.spec.js +334 -0
  164. package/test/ng/compile.spec.js +17956 -0
  165. package/test/ng/controller-provider.spec.js +227 -0
  166. package/test/ng/cookie-reader.spec.js +98 -0
  167. package/test/ng/directive/a.spec.js +192 -0
  168. package/test/ng/directive/bind.spec.js +334 -0
  169. package/test/ng/directive/boolean.spec.js +136 -0
  170. package/test/ng/directive/change.spec.js +71 -0
  171. package/test/ng/directive/class.spec.js +858 -0
  172. package/test/ng/directive/click.spec.js +38 -0
  173. package/test/ng/directive/cloak.spec.js +44 -0
  174. package/test/ng/directive/constoller.spec.js +194 -0
  175. package/test/ng/directive/element-style.spec.js +92 -0
  176. package/test/ng/directive/event.spec.js +282 -0
  177. package/test/ng/directive/form.spec.js +1518 -0
  178. package/test/ng/directive/href.spec.js +143 -0
  179. package/test/ng/directive/if.spec.js +402 -0
  180. package/test/ng/directive/include.spec.js +828 -0
  181. package/test/ng/directive/init.spec.js +68 -0
  182. package/test/ng/directive/input.spec.js +3810 -0
  183. package/test/ng/directive/list.spec.js +170 -0
  184. package/test/ng/directive/model-options.spec.js +1008 -0
  185. package/test/ng/directive/model.spec.js +1905 -0
  186. package/test/ng/directive/non-bindable.spec.js +55 -0
  187. package/test/ng/directive/options.spec.js +3583 -0
  188. package/test/ng/directive/ref.spec.js +575 -0
  189. package/test/ng/directive/repeat.spec.js +1675 -0
  190. package/test/ng/directive/script.spec.js +52 -0
  191. package/test/ng/directive/scrset.spec.js +67 -0
  192. package/test/ng/directive/select.spec.js +2541 -0
  193. package/test/ng/directive/show-hide.spec.js +253 -0
  194. package/test/ng/directive/src.spec.js +157 -0
  195. package/test/ng/directive/style.spec.js +178 -0
  196. package/test/ng/directive/switch.spec.js +647 -0
  197. package/test/ng/directive/validators.spec.js +717 -0
  198. package/test/ng/document.spec.js +52 -0
  199. package/test/ng/filter/filter.spec.js +714 -0
  200. package/test/ng/filter/filters.spec.js +35 -0
  201. package/test/ng/filter/limit-to.spec.js +251 -0
  202. package/test/ng/filter/order-by.spec.js +891 -0
  203. package/test/ng/filter.spec.js +149 -0
  204. package/test/ng/http-backend.spec.js +398 -0
  205. package/test/ng/http.spec.js +4071 -0
  206. package/test/ng/interpolate.spec.js +642 -0
  207. package/test/ng/interval.spec.js +343 -0
  208. package/test/ng/location.spec.js +3488 -0
  209. package/test/ng/on.spec.js +229 -0
  210. package/test/ng/parse.spec.js +4655 -0
  211. package/test/ng/prop.spec.js +805 -0
  212. package/test/ng/q.spec.js +2904 -0
  213. package/test/ng/root-element.spec.js +16 -0
  214. package/test/ng/sanitize-uri.spec.js +249 -0
  215. package/test/ng/sce.spec.js +660 -0
  216. package/test/ng/scope.spec.js +3442 -0
  217. package/test/ng/template-request.spec.js +236 -0
  218. package/test/ng/timeout.spec.js +351 -0
  219. package/test/ng/url-utils.spec.js +156 -0
  220. package/test/ng/utils.spec.js +144 -0
  221. package/test/original-test.html +21 -0
  222. package/test/public.spec.js +34 -0
  223. package/test/sanitize/bing-html.spec.js +36 -0
  224. package/test/server/express.js +158 -0
  225. package/test/test-utils.js +11 -0
  226. package/tsconfig.json +17 -0
  227. package/types/angular.d.ts +138 -0
  228. package/types/global.d.ts +9 -0
  229. package/types/index.d.ts +2357 -0
  230. package/types/jqlite.d.ts +558 -0
  231. package/vite.config.js +14 -0
@@ -0,0 +1,291 @@
1
+ import { jqLite } from "../jqLite";
2
+ import { forEach, isString } from "../core/utils";
3
+ import { concatWithSpace, getDomNode } from "./shared";
4
+
5
+ export const $$AnimateCssDriverProvider = [
6
+ "$$animationProvider",
7
+ function ($$animationProvider) {
8
+ $$animationProvider.drivers.push("$$animateCssDriver");
9
+
10
+ const NG_ANIMATE_SHIM_CLASS_NAME = "ng-animate-shim";
11
+ const NG_ANIMATE_ANCHOR_CLASS_NAME = "ng-anchor";
12
+
13
+ const NG_OUT_ANCHOR_CLASS_NAME = "ng-anchor-out";
14
+ const NG_IN_ANCHOR_CLASS_NAME = "ng-anchor-in";
15
+
16
+ function isDocumentFragment(node) {
17
+ return node.parentNode && node.parentNode.nodeType === 11;
18
+ }
19
+
20
+ this.$get = [
21
+ "$animateCss",
22
+ "$rootScope",
23
+ "$$AnimateRunner",
24
+ "$rootElement",
25
+ "$document",
26
+ function (
27
+ $animateCss,
28
+ $rootScope,
29
+ $$AnimateRunner,
30
+ $rootElement,
31
+ $document,
32
+ ) {
33
+ const bodyNode = $document[0].body;
34
+ const rootNode = getDomNode($rootElement);
35
+
36
+ const rootBodyElement = jqLite(
37
+ // this is to avoid using something that exists outside of the body
38
+ // we also special case the doc fragment case because our unit test code
39
+ // appends the $rootElement to the body after the app has been bootstrapped
40
+ isDocumentFragment(rootNode) || bodyNode.contains(rootNode)
41
+ ? rootNode
42
+ : bodyNode,
43
+ );
44
+
45
+ return function initDriverFn(animationDetails) {
46
+ return animationDetails.from && animationDetails.to
47
+ ? prepareFromToAnchorAnimation(
48
+ animationDetails.from,
49
+ animationDetails.to,
50
+ animationDetails.classes,
51
+ animationDetails.anchors,
52
+ )
53
+ : prepareRegularAnimation(animationDetails);
54
+ };
55
+
56
+ function filterCssClasses(classes) {
57
+ // remove all the `ng-` stuff
58
+ return classes.replace(/\bng-\S+\b/g, "");
59
+ }
60
+
61
+ function getUniqueValues(a, b) {
62
+ if (isString(a)) a = a.split(" ");
63
+ if (isString(b)) b = b.split(" ");
64
+ return a.filter((val) => b.indexOf(val) === -1).join(" ");
65
+ }
66
+
67
+ function prepareAnchoredAnimation(classes, outAnchor, inAnchor) {
68
+ const clone = jqLite(getDomNode(outAnchor).cloneNode(true));
69
+ const startingClasses = filterCssClasses(getClassVal(clone));
70
+
71
+ outAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME);
72
+ inAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME);
73
+
74
+ clone.addClass(NG_ANIMATE_ANCHOR_CLASS_NAME);
75
+
76
+ rootBodyElement.append(clone);
77
+
78
+ let animatorIn;
79
+ const animatorOut = prepareOutAnimation();
80
+
81
+ // the user may not end up using the `out` animation and
82
+ // only making use of the `in` animation or vice-versa.
83
+ // In either case we should allow this and not assume the
84
+ // animation is over unless both animations are not used.
85
+ if (!animatorOut) {
86
+ animatorIn = prepareInAnimation();
87
+ if (!animatorIn) {
88
+ return end();
89
+ }
90
+ }
91
+
92
+ const startingAnimator = animatorOut || animatorIn;
93
+
94
+ return {
95
+ start() {
96
+ let runner;
97
+
98
+ let currentAnimation = startingAnimator.start();
99
+ currentAnimation.done(() => {
100
+ currentAnimation = null;
101
+ if (!animatorIn) {
102
+ animatorIn = prepareInAnimation();
103
+ if (animatorIn) {
104
+ currentAnimation = animatorIn.start();
105
+ currentAnimation.done(() => {
106
+ currentAnimation = null;
107
+ end();
108
+ runner.complete();
109
+ });
110
+ return currentAnimation;
111
+ }
112
+ }
113
+ // in the event that there is no `in` animation
114
+ end();
115
+ runner.complete();
116
+ });
117
+
118
+ runner = new $$AnimateRunner({
119
+ end: endFn,
120
+ cancel: endFn,
121
+ });
122
+
123
+ return runner;
124
+
125
+ function endFn() {
126
+ if (currentAnimation) {
127
+ currentAnimation.end();
128
+ }
129
+ }
130
+ },
131
+ };
132
+
133
+ function calculateAnchorStyles(anchor) {
134
+ const styles = {};
135
+
136
+ const coords = getDomNode(anchor).getBoundingClientRect();
137
+
138
+ // we iterate directly since safari messes up and doesn't return
139
+ // all the keys for the coords object when iterated
140
+ forEach(["width", "height", "top", "left"], (key) => {
141
+ let value = coords[key];
142
+ switch (key) {
143
+ case "top":
144
+ value += bodyNode.scrollTop;
145
+ break;
146
+ case "left":
147
+ value += bodyNode.scrollLeft;
148
+ break;
149
+ }
150
+ styles[key] = `${Math.floor(value)}px`;
151
+ });
152
+ return styles;
153
+ }
154
+
155
+ function prepareOutAnimation() {
156
+ const animator = $animateCss(clone, {
157
+ addClass: NG_OUT_ANCHOR_CLASS_NAME,
158
+ delay: true,
159
+ from: calculateAnchorStyles(outAnchor),
160
+ });
161
+
162
+ // read the comment within `prepareRegularAnimation` to understand
163
+ // why this check is necessary
164
+ return animator.$$willAnimate ? animator : null;
165
+ }
166
+
167
+ function getClassVal(element) {
168
+ return element.attr("class") || "";
169
+ }
170
+
171
+ function prepareInAnimation() {
172
+ const endingClasses = filterCssClasses(getClassVal(inAnchor));
173
+ const toAdd = getUniqueValues(endingClasses, startingClasses);
174
+ const toRemove = getUniqueValues(startingClasses, endingClasses);
175
+
176
+ const animator = $animateCss(clone, {
177
+ to: calculateAnchorStyles(inAnchor),
178
+ addClass: `${NG_IN_ANCHOR_CLASS_NAME} ${toAdd}`,
179
+ removeClass: `${NG_OUT_ANCHOR_CLASS_NAME} ${toRemove}`,
180
+ delay: true,
181
+ });
182
+
183
+ // read the comment within `prepareRegularAnimation` to understand
184
+ // why this check is necessary
185
+ return animator.$$willAnimate ? animator : null;
186
+ }
187
+
188
+ function end() {
189
+ clone.remove();
190
+ outAnchor.removeClass(NG_ANIMATE_SHIM_CLASS_NAME);
191
+ inAnchor.removeClass(NG_ANIMATE_SHIM_CLASS_NAME);
192
+ }
193
+ }
194
+
195
+ function prepareFromToAnchorAnimation(from, to, classes, anchors) {
196
+ const fromAnimation = prepareRegularAnimation(from, function () {});
197
+ const toAnimation = prepareRegularAnimation(to, function () {});
198
+
199
+ const anchorAnimations = [];
200
+ forEach(anchors, (anchor) => {
201
+ const outElement = anchor.out;
202
+ const inElement = anchor.in;
203
+ const animator = prepareAnchoredAnimation(
204
+ classes,
205
+ outElement,
206
+ inElement,
207
+ );
208
+ if (animator) {
209
+ anchorAnimations.push(animator);
210
+ }
211
+ });
212
+
213
+ // no point in doing anything when there are no elements to animate
214
+ if (!fromAnimation && !toAnimation && anchorAnimations.length === 0)
215
+ return;
216
+
217
+ return {
218
+ start() {
219
+ const animationRunners = [];
220
+
221
+ if (fromAnimation) {
222
+ animationRunners.push(fromAnimation.start());
223
+ }
224
+
225
+ if (toAnimation) {
226
+ animationRunners.push(toAnimation.start());
227
+ }
228
+
229
+ forEach(anchorAnimations, (animation) => {
230
+ animationRunners.push(animation.start());
231
+ });
232
+
233
+ const runner = new $$AnimateRunner({
234
+ end: endFn,
235
+ cancel: endFn, // CSS-driven animations cannot be cancelled, only ended
236
+ });
237
+
238
+ $$AnimateRunner.all(animationRunners, (status) => {
239
+ runner.complete(status);
240
+ });
241
+
242
+ return runner;
243
+
244
+ function endFn() {
245
+ forEach(animationRunners, (runner) => {
246
+ runner.end();
247
+ });
248
+ }
249
+ },
250
+ };
251
+ }
252
+
253
+ function prepareRegularAnimation(animationDetails) {
254
+ const { element } = animationDetails;
255
+ const options = animationDetails.options || {};
256
+
257
+ if (animationDetails.structural) {
258
+ options.event = animationDetails.event;
259
+ options.structural = true;
260
+ options.applyClassesEarly = true;
261
+
262
+ // we special case the leave animation since we want to ensure that
263
+ // the element is removed as soon as the animation is over. Otherwise
264
+ // a flicker might appear or the element may not be removed at all
265
+ if (animationDetails.event === "leave") {
266
+ options.onDone = options.domOperation;
267
+ }
268
+ }
269
+
270
+ // We assign the preparationClasses as the actual animation event since
271
+ // the internals of $animateCss will just suffix the event token values
272
+ // with `-active` to trigger the animation.
273
+ if (options.preparationClasses) {
274
+ options.event = concatWithSpace(
275
+ options.event,
276
+ options.preparationClasses,
277
+ );
278
+ }
279
+
280
+ const animator = $animateCss(element, options);
281
+
282
+ // the driver lookup code inside of $$animation attempts to spawn a
283
+ // driver one by one until a driver returns a.$$willAnimate animator object.
284
+ // $animateCss will always return an object, however, it will pass in
285
+ // a flag as a hint as to whether an animation was detected or not
286
+ return animator.$$willAnimate ? animator : null;
287
+ }
288
+ },
289
+ ];
290
+ },
291
+ ];
@@ -0,0 +1,367 @@
1
+ import { forEach, isArray, isObject, isFunction } from "../core/utils";
2
+ import {
3
+ applyAnimationClassesFactory,
4
+ applyAnimationStyles,
5
+ prepareAnimationOptions,
6
+ } from "./shared";
7
+
8
+ // TODO(matsko): use caching here to speed things up for detection
9
+ // TODO(matsko): add documentation
10
+ // by the time...
11
+
12
+ export const $$AnimateJsProvider = [
13
+ "$animateProvider",
14
+ function ($animateProvider) {
15
+ this.$get = [
16
+ "$injector",
17
+ "$$AnimateRunner",
18
+ function ($injector, $$AnimateRunner) {
19
+ const applyAnimationClasses = applyAnimationClassesFactory();
20
+ // $animateJs(element, 'enter');
21
+ return function (element, event, classes, options) {
22
+ let animationClosed = false;
23
+
24
+ // the `classes` argument is optional and if it is not used
25
+ // then the classes will be resolved from the element's className
26
+ // property as well as options.addClass/options.removeClass.
27
+ if (arguments.length === 3 && isObject(classes)) {
28
+ options = classes;
29
+ classes = null;
30
+ }
31
+
32
+ options = prepareAnimationOptions(options);
33
+ if (!classes) {
34
+ classes = element.attr("class") || "";
35
+ if (options.addClass) {
36
+ classes += ` ${options.addClass}`;
37
+ }
38
+ if (options.removeClass) {
39
+ classes += ` ${options.removeClass}`;
40
+ }
41
+ }
42
+
43
+ const classesToAdd = options.addClass;
44
+ const classesToRemove = options.removeClass;
45
+
46
+ // the lookupAnimations function returns a series of animation objects that are
47
+ // matched up with one or more of the CSS classes. These animation objects are
48
+ // defined via the module.animation factory function. If nothing is detected then
49
+ // we don't return anything which then makes $animation query the next driver.
50
+ const animations = lookupAnimations(classes);
51
+ let before;
52
+ let after;
53
+ if (animations.length) {
54
+ let afterFn;
55
+ let beforeFn;
56
+ if (event === "leave") {
57
+ beforeFn = "leave";
58
+ afterFn = "afterLeave"; // TODO(matsko): get rid of this
59
+ } else {
60
+ beforeFn = `before${event.charAt(0).toUpperCase()}${event.substr(1)}`;
61
+ afterFn = event;
62
+ }
63
+
64
+ if (event !== "enter" && event !== "move") {
65
+ before = packageAnimations(
66
+ element,
67
+ event,
68
+ options,
69
+ animations,
70
+ beforeFn,
71
+ );
72
+ }
73
+ after = packageAnimations(
74
+ element,
75
+ event,
76
+ options,
77
+ animations,
78
+ afterFn,
79
+ );
80
+ }
81
+
82
+ // no matching animations
83
+ if (!before && !after) return;
84
+
85
+ function applyOptions() {
86
+ options.domOperation();
87
+ applyAnimationClasses(element, options);
88
+ }
89
+
90
+ function close() {
91
+ animationClosed = true;
92
+ applyOptions();
93
+ applyAnimationStyles(element, options);
94
+ }
95
+
96
+ let runner;
97
+
98
+ return {
99
+ $$willAnimate: true,
100
+ end() {
101
+ if (runner) {
102
+ runner.end();
103
+ } else {
104
+ close();
105
+ runner = new $$AnimateRunner();
106
+ runner.complete(true);
107
+ }
108
+ return runner;
109
+ },
110
+ start() {
111
+ if (runner) {
112
+ return runner;
113
+ }
114
+
115
+ runner = new $$AnimateRunner();
116
+ let closeActiveAnimations;
117
+ const chain = [];
118
+
119
+ if (before) {
120
+ chain.push((fn) => {
121
+ closeActiveAnimations = before(fn);
122
+ });
123
+ }
124
+
125
+ if (chain.length) {
126
+ chain.push((fn) => {
127
+ applyOptions();
128
+ fn(true);
129
+ });
130
+ } else {
131
+ applyOptions();
132
+ }
133
+
134
+ if (after) {
135
+ chain.push((fn) => {
136
+ closeActiveAnimations = after(fn);
137
+ });
138
+ }
139
+
140
+ runner.setHost({
141
+ end() {
142
+ endAnimations();
143
+ },
144
+ cancel() {
145
+ endAnimations(true);
146
+ },
147
+ });
148
+
149
+ $$AnimateRunner.chain(chain, onComplete);
150
+ return runner;
151
+
152
+ function onComplete(success) {
153
+ close(success);
154
+ runner.complete(success);
155
+ }
156
+
157
+ function endAnimations(cancelled) {
158
+ if (!animationClosed) {
159
+ (closeActiveAnimations || (() => {}))(cancelled);
160
+ onComplete(cancelled);
161
+ }
162
+ }
163
+ },
164
+ };
165
+
166
+ function executeAnimationFn(fn, element, event, options, onDone) {
167
+ let args;
168
+ switch (event) {
169
+ case "animate":
170
+ args = [element, options.from, options.to, onDone];
171
+ break;
172
+
173
+ case "setClass":
174
+ args = [element, classesToAdd, classesToRemove, onDone];
175
+ break;
176
+
177
+ case "addClass":
178
+ args = [element, classesToAdd, onDone];
179
+ break;
180
+
181
+ case "removeClass":
182
+ args = [element, classesToRemove, onDone];
183
+ break;
184
+
185
+ default:
186
+ args = [element, onDone];
187
+ break;
188
+ }
189
+
190
+ args.push(options);
191
+
192
+ let value = fn.apply(fn, args);
193
+ if (value) {
194
+ if (isFunction(value.start)) {
195
+ value = value.start();
196
+ }
197
+
198
+ if (value instanceof $$AnimateRunner) {
199
+ value.done(onDone);
200
+ } else if (isFunction(value)) {
201
+ // optional onEnd / onCancel callback
202
+ return value;
203
+ }
204
+ }
205
+
206
+ return () => {};
207
+ }
208
+
209
+ function groupEventedAnimations(
210
+ element,
211
+ event,
212
+ options,
213
+ animations,
214
+ fnName,
215
+ ) {
216
+ const operations = [];
217
+ forEach(animations, (ani) => {
218
+ const animation = ani[fnName];
219
+ if (!animation) return;
220
+
221
+ // note that all of these animations will run in parallel
222
+ operations.push(() => {
223
+ let runner;
224
+ let endProgressCb;
225
+
226
+ let resolved = false;
227
+ const onAnimationComplete = function (rejected) {
228
+ if (!resolved) {
229
+ resolved = true;
230
+ (endProgressCb || (() => {}))(rejected);
231
+ runner.complete(!rejected);
232
+ }
233
+ };
234
+
235
+ runner = new $$AnimateRunner({
236
+ end() {
237
+ onAnimationComplete();
238
+ },
239
+ cancel() {
240
+ onAnimationComplete(true);
241
+ },
242
+ });
243
+
244
+ endProgressCb = executeAnimationFn(
245
+ animation,
246
+ element,
247
+ event,
248
+ options,
249
+ (result) => {
250
+ const cancelled = result === false;
251
+ onAnimationComplete(cancelled);
252
+ },
253
+ );
254
+
255
+ return runner;
256
+ });
257
+ });
258
+
259
+ return operations;
260
+ }
261
+
262
+ function packageAnimations(
263
+ element,
264
+ event,
265
+ options,
266
+ animations,
267
+ fnName,
268
+ ) {
269
+ let operations = groupEventedAnimations(
270
+ element,
271
+ event,
272
+ options,
273
+ animations,
274
+ fnName,
275
+ );
276
+ if (operations.length === 0) {
277
+ let a;
278
+ let b;
279
+ if (fnName === "beforeSetClass") {
280
+ a = groupEventedAnimations(
281
+ element,
282
+ "removeClass",
283
+ options,
284
+ animations,
285
+ "beforeRemoveClass",
286
+ );
287
+ b = groupEventedAnimations(
288
+ element,
289
+ "addClass",
290
+ options,
291
+ animations,
292
+ "beforeAddClass",
293
+ );
294
+ } else if (fnName === "setClass") {
295
+ a = groupEventedAnimations(
296
+ element,
297
+ "removeClass",
298
+ options,
299
+ animations,
300
+ "removeClass",
301
+ );
302
+ b = groupEventedAnimations(
303
+ element,
304
+ "addClass",
305
+ options,
306
+ animations,
307
+ "addClass",
308
+ );
309
+ }
310
+
311
+ if (a) {
312
+ operations = operations.concat(a);
313
+ }
314
+ if (b) {
315
+ operations = operations.concat(b);
316
+ }
317
+ }
318
+
319
+ if (operations.length === 0) return;
320
+
321
+ // TODO(matsko): add documentation
322
+ return function startAnimation(callback) {
323
+ const runners = [];
324
+ if (operations.length) {
325
+ forEach(operations, (animateFn) => {
326
+ runners.push(animateFn());
327
+ });
328
+ }
329
+
330
+ if (runners.length) {
331
+ $$AnimateRunner.all(runners, callback);
332
+ } else {
333
+ callback();
334
+ }
335
+
336
+ return function endFn(reject) {
337
+ forEach(runners, (runner) => {
338
+ if (reject) {
339
+ runner.cancel();
340
+ } else {
341
+ runner.end();
342
+ }
343
+ });
344
+ };
345
+ };
346
+ }
347
+ };
348
+
349
+ function lookupAnimations(classes) {
350
+ classes = isArray(classes) ? classes : classes.split(" ");
351
+ const matches = [];
352
+ const flagMap = {};
353
+ for (let i = 0; i < classes.length; i++) {
354
+ const klass = classes[i];
355
+ const animationFactory =
356
+ $animateProvider.$$registeredAnimations[klass];
357
+ if (animationFactory && !flagMap[klass]) {
358
+ matches.push($injector.get(animationFactory));
359
+ flagMap[klass] = true;
360
+ }
361
+ }
362
+ return matches;
363
+ }
364
+ },
365
+ ];
366
+ },
367
+ ];