@angular-wave/angular.ts 0.0.57 → 0.0.59

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@angular-wave/angular.ts",
3
3
  "license": "MIT",
4
- "version": "0.0.57",
4
+ "version": "0.0.59",
5
5
  "type": "module",
6
6
  "main": "dist/angular-ts.esm.js",
7
7
  "browser": "dist/angular-ts.umd.js",
@@ -25,7 +25,7 @@
25
25
  /* The starting CSS styles for the enter animation */
26
26
  .fade.ng-enter {
27
27
  transition: 0.5s linear all;
28
- background-color: white;
28
+ background-color: unset;
29
29
  opacity: 0;
30
30
  }
31
31
 
@@ -44,12 +44,18 @@
44
44
  /* The finishing CSS styles for the leave animation */
45
45
  .fade.ng-leave.ng-leave-active {
46
46
  opacity: 0;
47
- background-color: white;
47
+ background-color: unset;
48
48
  }
49
49
  </style>
50
50
  </head>
51
51
  <body ng-app="test">
52
- <div ng-if="bool" class="fade" data-animate="true">Fade me in out</div>
52
+ <div ng-if="bool" id="data-animate" class="fade" data-animate="true">
53
+ Fade me in out
54
+ </div>
55
+ <div ng-if="bool" id="animate" class="fade" animate="true">
56
+ Fade me in out
57
+ </div>
58
+ <div ng-if="bool" id="no-animate" class="fade">Fade me in out</div>
53
59
  <button ng-click="bool=true">Fade In!</button>
54
60
  <button ng-click="bool=false">Fade Out!</button>
55
61
  </body>
@@ -144,6 +144,16 @@ export function $AnimateCssProvider() {
144
144
  "$$animateCache",
145
145
  "$$rAFScheduler",
146
146
  "$$animateQueue",
147
+
148
+ /**
149
+ *
150
+ * @param {*} $$AnimateRunner
151
+ * @param {*} $timeout
152
+ * @param {*} $$animateCache
153
+ * @param {import("./raf-scheduler").RafScheduler} $$rAFScheduler
154
+ * @param {*} $$animateQueue
155
+ * @returns
156
+ */
147
157
  function (
148
158
  $$AnimateRunner,
149
159
  $timeout,
@@ -275,7 +285,7 @@ export function $AnimateCssProvider() {
275
285
  }
276
286
 
277
287
  const restoreStyles = {};
278
- const node = getDomNode(element);
288
+ const node = /** @type {HTMLElement} */ (getDomNode(element));
279
289
  if (!node || !node.parentNode || !$$animateQueue.enabled()) {
280
290
  return closeAndReturnNoopAnimator();
281
291
  }
@@ -0,0 +1,44 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>AngularTS Test Runner</title>
6
+
7
+ <link rel="shortcut icon" type="image/png" href="/images/favicon.ico" />
8
+ <script type="module" src="/src/index.js"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/animejs@3.2.2/lib/anime.min.js"></script>
10
+ <script>
11
+ document.addEventListener("DOMContentLoaded", () => {
12
+ window.angular.module("test", ["ngAnimate"]).animation(".colorful", [
13
+ function () {
14
+ return {
15
+ addClass: function (element, className, doneFn) {
16
+ anime({
17
+ targets: element[0],
18
+ translateX: parseInt(className),
19
+ });
20
+ },
21
+ removeClass: function (element, className, doneFn) {},
22
+ setClass: function (element, className, removedClass, doneFn) {
23
+ anime({
24
+ targets: element[0],
25
+ translateX: parseInt(className),
26
+ });
27
+ },
28
+ };
29
+ },
30
+ ]);
31
+ });
32
+ </script>
33
+
34
+ <style></style>
35
+ </head>
36
+ <body ng-app="test">
37
+ <div ng-class="location" class="colorful">
38
+ this box is moody {{ location }}
39
+ </div>
40
+ <button ng-click="location='0'">Change to red</button>
41
+ <button ng-click="location='150'">Change to blue</button>
42
+ <button ng-click="location='300'">Change to green</button>
43
+ </body>
44
+ </html>
@@ -35,6 +35,15 @@ export function $$AnimationProvider() {
35
35
  "$$AnimateRunner",
36
36
  "$$rAFScheduler",
37
37
  "$$animateCache",
38
+ /**
39
+ *
40
+ * @param {*} $rootScope
41
+ * @param {*} $injector
42
+ * @param {*} $$AnimateRunner
43
+ * @param {import("./raf-scheduler").RafScheduler} $$rAFScheduler
44
+ * @param {*} $$animateCache
45
+ * @returns
46
+ */
38
47
  function (
39
48
  $rootScope,
40
49
  $injector,
@@ -305,7 +314,6 @@ export function $$AnimationProvider() {
305
314
  }
306
315
  }
307
316
  }
308
-
309
317
  $$rAFScheduler(finalAnimations);
310
318
  });
311
319
 
@@ -0,0 +1,10 @@
1
+ import { test, expect } from "@playwright/test";
2
+
3
+ test("raf-scheduler unit tests contain no errors", async ({ page }) => {
4
+ await page.goto("src/animations/raf-scheduler.html");
5
+ await page.content();
6
+
7
+ await expect(page.locator(".jasmine-overall-result")).toHaveText(
8
+ /0 failures/,
9
+ );
10
+ });
@@ -0,0 +1,18 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>AngularTS Test Runner</title>
6
+
7
+ <link rel="shortcut icon" type="image/png" href="/images/favicon.ico" />
8
+ <link rel="stylesheet" href="/jasmine/jasmine-5.1.2/jasmine.css" />
9
+ <script src="/jasmine/jasmine-5.1.2/jasmine.js"></script>
10
+ <script src="/jasmine/jasmine-5.1.2/jasmine-html.js"></script>
11
+ <script src="/jasmine/jasmine-5.1.2/boot0.js"></script>
12
+ <script src="/jasmine/jasmine-5.1.2/boot1.js"></script>
13
+ <script type="module" src="/src/animations/raf-scheduler.spec.js"></script>
14
+ </head>
15
+ <body>
16
+ <div id="dummy"></div>
17
+ </body>
18
+ </html>
@@ -1,49 +1,72 @@
1
- export const $$rAFSchedulerFactory = [
2
- () => {
3
- let queue;
4
- let cancelFn;
5
-
6
- function nextTick() {
7
- if (!queue.length) return;
8
-
9
- const items = queue.shift();
10
- items.forEach((i) => i());
11
-
12
- if (!cancelFn) {
13
- window.requestAnimationFrame(() => {
14
- if (!cancelFn) nextTick();
15
- });
16
- }
17
- }
1
+ /**
2
+ * @typedef {Function} RafSchedulerFunction
3
+ * @typedef {Object} RafSchedulerObject
4
+ * @property {Function} waitUntilQuiet - Function to wait until the animation frame is quiet.
5
+ * @typedef {RafSchedulerObject & RafSchedulerFunction} RafScheduler
6
+ */
18
7
 
19
- function scheduler(tasks) {
20
- // we make a copy since RAFScheduler mutates the state
21
- // of the passed in array variable and this would be difficult
22
- // to track down on the outside code
23
- queue = queue.concat(tasks);
24
- nextTick();
25
- }
8
+ /**
9
+ * Creates a requestAnimationFrame scheduler.
10
+ * @returns {RafScheduler} The scheduler object.
11
+ */
12
+ export function $$rAFSchedulerFactory() {
13
+ /**
14
+ * @type {Array<Array<Function>>}
15
+ */
16
+ let queue = [];
17
+ /**
18
+ * @type {number|null}
19
+ */
20
+ let cancelFn = null;
26
21
 
27
- queue = scheduler.queue = [];
22
+ /**
23
+ * Processes the next tick of the animation frame.
24
+ */
25
+ function nextTick() {
26
+ if (!queue.length) return;
28
27
 
29
- /* waitUntilQuiet does two things:
30
- * 1. It will run the FINAL `fn` value only when an uncanceled RAF has passed through
31
- * 2. It will delay the next wave of tasks from running until the quiet `fn` has run.
32
- *
33
- * The motivation here is that animation code can request more time from the scheduler
34
- * before the next wave runs. This allows for certain DOM properties such as classes to
35
- * be resolved in time for the next animation to run.
36
- */
37
- scheduler.waitUntilQuiet = (fn) => {
38
- if (cancelFn) cancelFn();
28
+ const items = queue.shift();
29
+ items.forEach((i) => i());
39
30
 
40
- cancelFn = window.requestAnimationFrame(() => {
31
+ if (!cancelFn) {
32
+ window.requestAnimationFrame(() => {
41
33
  cancelFn = null;
42
- fn();
43
34
  nextTick();
44
35
  });
45
- };
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Adds tasks to the queue and schedules the next tick.
41
+ * @param {Array<Function>} tasks - The tasks to be added to the queue.
42
+ */
43
+ function scheduler(tasks) {
44
+ // Make a copy since RAFScheduler mutates the state
45
+ // of the passed in array variable and this would be difficult
46
+ // to track down on the outside code
47
+ queue = queue.concat(tasks);
48
+ nextTick();
49
+ }
50
+
51
+ queue = scheduler.queue = [];
52
+
53
+ /**
54
+ * Waits until the animation frame is quiet before running the provided function.
55
+ * Cancels any previous animation frame requests.
56
+ * @param {Function} fn - The function to run when the animation frame is quiet.
57
+ */
58
+ scheduler.waitUntilQuiet = (fn) => {
59
+ if (cancelFn !== null) {
60
+ window.cancelAnimationFrame(cancelFn);
61
+ cancelFn = null;
62
+ }
63
+
64
+ cancelFn = window.requestAnimationFrame(() => {
65
+ cancelFn = null;
66
+ fn();
67
+ nextTick();
68
+ });
69
+ };
46
70
 
47
- return scheduler;
48
- },
49
- ];
71
+ return scheduler;
72
+ }
@@ -0,0 +1,92 @@
1
+ import { $$rAFSchedulerFactory } from "./raf-scheduler";
2
+
3
+ describe("$$rAFSchedulerFactory", function () {
4
+ let scheduler;
5
+ let rAFCallbacks;
6
+ let originalRequestAnimationFrame;
7
+ let originalCancelAnimationFrame;
8
+
9
+ beforeEach(function () {
10
+ rAFCallbacks = [];
11
+ scheduler = $$rAFSchedulerFactory();
12
+
13
+ originalRequestAnimationFrame = window.requestAnimationFrame;
14
+ originalCancelAnimationFrame = window.cancelAnimationFrame;
15
+
16
+ spyOn(window, "requestAnimationFrame").and.callFake(function (cb) {
17
+ const id = rAFCallbacks.length;
18
+ rAFCallbacks.push(cb);
19
+ return id;
20
+ });
21
+
22
+ spyOn(window, "cancelAnimationFrame").and.callFake(function (id) {
23
+ rAFCallbacks[id] = null;
24
+ });
25
+ });
26
+
27
+ afterEach(function () {
28
+ window.requestAnimationFrame = originalRequestAnimationFrame;
29
+ window.cancelAnimationFrame = originalCancelAnimationFrame;
30
+ });
31
+
32
+ function flushRAF() {
33
+ const callbacks = rAFCallbacks.slice();
34
+ rAFCallbacks.length = 0;
35
+ callbacks.forEach((cb) => cb && cb());
36
+ }
37
+
38
+ it("should schedule tasks and process them", function () {
39
+ const task1 = jasmine.createSpy("task1");
40
+ const task2 = jasmine.createSpy("task2");
41
+
42
+ scheduler([[task1, task2]]);
43
+
44
+ expect(task1).toHaveBeenCalled();
45
+ expect(task2).toHaveBeenCalled();
46
+ });
47
+
48
+ it("should process tasks in the correct order", function () {
49
+ const callOrder = [];
50
+ const task1 = function () {
51
+ callOrder.push("task1");
52
+ };
53
+ const task2 = function () {
54
+ callOrder.push("task2");
55
+ };
56
+
57
+ scheduler([[task1, task2]]);
58
+
59
+ expect(callOrder).toEqual(["task1", "task2"]);
60
+ });
61
+
62
+ it("should wait until quiet before running the final function", function () {
63
+ const quietFn = jasmine.createSpy("quietFn");
64
+ const task1 = jasmine.createSpy("task1");
65
+
66
+ scheduler([[task1]]);
67
+ scheduler.waitUntilQuiet(quietFn);
68
+
69
+ expect(quietFn).not.toHaveBeenCalled();
70
+
71
+ flushRAF();
72
+
73
+ expect(task1).toHaveBeenCalled();
74
+ expect(quietFn).toHaveBeenCalled();
75
+ });
76
+
77
+ it("should cancel the previous animation frame when scheduling a new waitUntilQuiet", function () {
78
+ const quietFn1 = jasmine.createSpy("quietFn1");
79
+ const quietFn2 = jasmine.createSpy("quietFn2");
80
+
81
+ scheduler.waitUntilQuiet(quietFn1);
82
+ scheduler.waitUntilQuiet(quietFn2);
83
+
84
+ expect(quietFn1).not.toHaveBeenCalled();
85
+ expect(quietFn2).not.toHaveBeenCalled();
86
+
87
+ flushRAF();
88
+
89
+ expect(quietFn1).not.toHaveBeenCalled();
90
+ expect(quietFn2).toHaveBeenCalled();
91
+ });
92
+ });
@@ -14,7 +14,7 @@ import { Parser } from "./parser";
14
14
  */
15
15
 
16
16
  /**
17
- * @typedef {function } CompiledExpressionFunction
17
+ * @typedef {function} CompiledExpressionFunction
18
18
  * @param {import('../scope/scope').Scope} context - An object against which any expressions embedded in the strings are evaluated against (typically a scope object).
19
19
  * @param {object} [locals] - local variables context object, useful for overriding values in `context`.
20
20
  * @param {any} [assign]
@@ -0,0 +1,65 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>AngularTS Playwright test template</title>
6
+
7
+ <link rel="shortcut icon" type="image/png" href="/images/favicon.ico" />
8
+ <script type="module" src="/src/index.js"></script>
9
+ <script>
10
+ document.addEventListener("DOMContentLoaded", () => {
11
+ window.angular
12
+ .module("test", ["ngAnimate"])
13
+ .directive("svgContainer", () => ({
14
+ template: "<svg ng-transclude></svg>",
15
+ replace: true,
16
+ transclude: true,
17
+ }));
18
+ });
19
+ </script>
20
+
21
+ <style>
22
+ .fade {
23
+ background-color: red;
24
+ }
25
+ /* The starting CSS styles for the enter animation */
26
+ .fade.ng-enter {
27
+ transition: 0.5s linear all;
28
+ background-color: unset;
29
+ opacity: 0;
30
+ }
31
+
32
+ /* The finishing CSS styles for the enter animation */
33
+ .fade.ng-enter.ng-enter-active {
34
+ opacity: 1;
35
+ background-color: red;
36
+ }
37
+
38
+ /* The starting CSS styles for the leave animation */
39
+ .fade.ng-leave {
40
+ transition: 0.5s linear all;
41
+ opacity: 1;
42
+ }
43
+
44
+ /* The finishing CSS styles for the leave animation */
45
+ .fade.ng-leave.ng-leave-active {
46
+ opacity: 0;
47
+ background-color: unset;
48
+ }
49
+ </style>
50
+ </head>
51
+ <body ng-app="test">
52
+ <div ng-if="bool" id="data-animate" class="fade" data-animate="true">
53
+ Fade me in out
54
+ </div>
55
+ <div ng-if="bool" id="animate" class="fade" animate="true">
56
+ Fade me in out
57
+ </div>
58
+ <div ng-if="bool" id="no-animate" class="fade">Fade me in out</div>
59
+
60
+ <button ng-click="bool=true">Fade In!</button>
61
+ <button ng-click="bool=false">Fade Out!</button>
62
+
63
+ <svg-container><circle id="circle" ng-if="bool"></circle></svg-container>
64
+ </body>
65
+ </html>
@@ -3,6 +3,12 @@ import { getBlockNodes } from "../../shared/jqlite/jqlite";
3
3
  import { hasAnimate } from "../../shared/utils";
4
4
 
5
5
  ngIfDirective.$inject = ["$animate"];
6
+ /**
7
+ *
8
+ * TODO // Add type for animate service
9
+ * @param {*} $animate
10
+ * @returns {import("../../types").Directive}
11
+ */
6
12
  export function ngIfDirective($animate) {
7
13
  return {
8
14
  multiElement: true,
@@ -10,6 +16,9 @@ export function ngIfDirective($animate) {
10
16
  priority: 600,
11
17
  terminal: true,
12
18
  restrict: "A",
19
+ /**
20
+ * TODO add type for $transclude service
21
+ */
13
22
  link($scope, $element, $attr, _ctrl, $transclude) {
14
23
  /** @type {{clone: import("../../shared/jqlite/jqlite").JQLite }} */
15
24
  let block;
@@ -275,128 +275,5 @@ describe("ngIf", () => {
275
275
  );
276
276
  });
277
277
  });
278
-
279
- // TODO ANIMATIONS
280
- // describe("and animations", () => {
281
- // let body = document.getElementById("dummy");
282
- // let element;
283
- // let $rootElement;
284
-
285
- // function html(content) {
286
- // $rootElement.html(content);
287
- // element = $rootElement.children().eq(0);
288
- // return element;
289
- // }
290
-
291
- // afterEach(() => {
292
- // dealoc(body);
293
- // dealoc(element);
294
- // });
295
-
296
- // // beforeEach(
297
- // // module(
298
- // // ($animateProvider, $provide) =>
299
- // // function ($animate) {
300
- // // $animate.enabled(true);
301
- // // },
302
- // // ),
303
- // // );
304
-
305
- // it("should fire off the enter animation", () => {
306
- // body.innerHTML =
307
- // "<div>" + '<div ng-if="value"><div>Hi</div></div>' + "</div>";
308
-
309
- // let item;
310
- // const $scope = $rootScope.$new();
311
- // element = $compile(body)($scope);
312
-
313
- // $rootScope.$digest();
314
- // $scope.$apply("value = true");
315
-
316
- // item = $animate.queue.shift();
317
- // expect(item.event).toBe("enter");
318
- // expect(item.element.text()).toBe("Hi");
319
-
320
- // expect(element.children().length).toBe(1);
321
- // });
322
-
323
- // it("should fire off the leave animation", () => {
324
- // let item;
325
- // const $scope = $rootScope.$new();
326
- // element = $compile(
327
- // html("<div>" + '<div ng-if="value"><div>Hi</div></div>' + "</div>"),
328
- // )($scope);
329
- // $scope.$apply("value = true");
330
-
331
- // item = $animate.queue.shift();
332
- // expect(item.event).toBe("enter");
333
- // expect(item.element.text()).toBe("Hi");
334
-
335
- // expect(element.children().length).toBe(1);
336
- // $scope.$apply("value = false");
337
-
338
- // item = $animate.queue.shift();
339
- // expect(item.event).toBe("leave");
340
- // expect(item.element.text()).toBe("Hi");
341
-
342
- // expect(element.children().length).toBe(0);
343
- // });
344
-
345
- // it("should destroy the previous leave animation if a new one takes place", () => {
346
- // module(($provide) => {
347
- // $provide.decorator("$animate", ($delegate, $$q) => {
348
- // const emptyPromise = $$q.defer().promise;
349
- // emptyPromise.done = () => {};
350
-
351
- // $delegate.leave = function () {
352
- // return emptyPromise;
353
- // };
354
- // return $delegate;
355
- // });
356
- // });
357
- // inject(($compile, $rootScope, $animate) => {
358
- // let item;
359
- // const $scope = $rootScope.$new();
360
- // element = $compile(
361
- // html("<div>" + '<div ng-if="value">Yo</div>' + "</div>"),
362
- // )($scope);
363
-
364
- // $scope.$apply("value = true");
365
-
366
- // let destroyed;
367
- // const inner = element.children(0);
368
- // inner.on("$destroy", () => {
369
- // destroyed = true;
370
- // });
371
-
372
- // $scope.$apply("value = false");
373
-
374
- // $scope.$apply("value = true");
375
-
376
- // $scope.$apply("value = false");
377
-
378
- // expect(destroyed).toBe(true);
379
- // });
380
- // });
381
-
382
- // it("should work with svg elements when the svg container is transcluded", () => {
383
- // // module(($compileProvider) => {
384
- // // $compileProvider.directive("svgContainer", () => ({
385
- // // template: "<svg ng-transclude></svg>",
386
- // // replace: true,
387
- // // transclude: true,
388
- // // });
389
- // // });
390
-
391
- // element = $compile(
392
- // '<svg-container><circle ng-if="flag"></circle></svg-container>',
393
- // )($rootScope);
394
- // $rootScope.flag = true;
395
- // $rootScope.$apply();
396
-
397
- // const circle = element.find("circle");
398
- // expect(circle[0].toString()).toMatch(/SVG/);
399
- // });
400
- // });
401
278
  });
402
279
  });