@ngutil/aria 0.0.71 → 0.0.73

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.
@@ -356,6 +356,7 @@ function eventToKeystroke(event) {
356
356
  };
357
357
  }
358
358
 
359
+ const PHANTOM = Symbol("phantom");
359
360
  const Listeners = {
360
361
  mousedown: {
361
362
  pointerType: "mouse" /* GesturePointerType.Mouse */,
@@ -401,44 +402,74 @@ const Listeners = {
401
402
  };
402
403
 
403
404
  class Gesture {
404
- constructor(name, listeners, options = {}) {
405
+ constructor(name, options = {}) {
405
406
  this.name = name;
406
- // TODO maybe global option
407
+ /**
408
+ * Gestures that depends on move distance, like drag, use this option
409
+ */
407
410
  this.distanceInclusion = 10;
408
- // TODO maybe global option
411
+ /**
412
+ * Gestures thet dependnso on time frame, like longtap, use this option
413
+ */
409
414
  this.timeWithin = 300;
415
+ /**
416
+ * The priority of the gesture
417
+ */
410
418
  this.priority = 0;
419
+ /**
420
+ * Should the gesture include the scroll distance
421
+ */
411
422
  this.includeScrollDistance = false;
412
- this.filterPointerTypes = ["mouse" /* GesturePointerType.Mouse */, "touch" /* GesturePointerType.Touch */];
413
- this.filterMouseButtons = [0];
414
- this.filterByEvent = (event) => this.filterPointerTypes.includes(event.pointerType) &&
415
- // this.filterListeners.includes(event.origin.type as any) &&
416
- (event.pointerType !== "mouse" /* GesturePointerType.Mouse */ ||
417
- (event.origin instanceof MouseEvent && this.filterMouseButtons.includes(event.origin.button)));
423
+ /**
424
+ * The pointer types of the gesture
425
+ */
426
+ this.pointerTypes = ["mouse" /* GesturePointerType.Mouse */, "touch" /* GesturePointerType.Touch */];
427
+ /**
428
+ * The number of pointers of the gesture can handle
429
+ */
430
+ this.pointerCount = 1;
431
+ /**
432
+ * The mouse buttons of the gesture (1 = left, 2 = middle, 3 = right)
433
+ */
434
+ this.mouseButtons = [0];
418
435
  Object.assign(this, options);
419
- this.filterListeners = listeners.filter(v => this.filterPointerTypes.includes(Listeners[v].pointerType));
436
+ this.originTypes = Object.keys(Listeners).filter(v => this.pointerTypes.includes(Listeners[v].pointerType));
420
437
  }
421
438
  /**
422
- * Transform input event, to gesture event
439
+ * Transform input event, to gesture event.
440
+ * The given events is filterde by {@see Gesture#isRelevantEvent}
423
441
  * ! important, dont rely on this object state, because not always create a new object
442
+ * @param events events to transform or filter or leave as is
424
443
  */
425
444
  handle(events) {
426
- return events.pipe(tap(event => (event.type = this.name)));
445
+ return events;
446
+ }
447
+ /**
448
+ * Should this gesture capture the event?
449
+ * @param event event to check
450
+ * @returns true if the gesture should capture the event, false otherwise
451
+ */
452
+ shouldCapture(event) {
453
+ return this.isRelevantEvent(event);
454
+ }
455
+ /**
456
+ * Test if the event is relevant to the gesture.
457
+ * The event is relevant if
458
+ * @param event event to check
459
+ * @returns true if the event is relevant, false otherwise
460
+ */
461
+ isRelevantEvent(event) {
462
+ return (this.pointerTypes.includes(event.pointerType) &&
463
+ this.pointerCount === event.pointers.length &&
464
+ this.originTypes.includes(event.origin.type) &&
465
+ (event.pointerType !== "mouse" /* GesturePointerType.Mouse */ ||
466
+ (event.origin instanceof MouseEvent && this.mouseButtons.includes(event.origin.button))));
427
467
  }
428
468
  }
429
469
 
430
- const DRAG_LISTENERS = [
431
- "mousedown",
432
- "mousemove",
433
- "mouseup",
434
- "touchstart",
435
- "touchmove",
436
- "touchend",
437
- "touchcancel"
438
- ];
439
470
  class GestureDragImpl extends Gesture {
440
471
  constructor(options) {
441
- super("gesture-drag", DRAG_LISTENERS, { includeScrollDistance: true, ...options });
472
+ super("gesture-drag", { includeScrollDistance: true, ...options });
442
473
  if (this.horizontal == null && this.vertical == null) {
443
474
  this.horizontal = true;
444
475
  this.vertical = true;
@@ -446,9 +477,6 @@ class GestureDragImpl extends Gesture {
446
477
  }
447
478
  capture(events) {
448
479
  return events.pipe(map(state => {
449
- if (state.pointers.length !== 1) {
450
- return 2 /* GestureCaptureState.Skip */;
451
- }
452
480
  if (Math.abs(state.pointers[0].distance.x) > this.distanceInclusion) {
453
481
  return this.horizontal ? 3 /* GestureCaptureState.Maybe */ : 2 /* GestureCaptureState.Skip */;
454
482
  }
@@ -464,7 +492,7 @@ class GestureDragImpl extends Gesture {
464
492
  : this.horizontal
465
493
  ? updateHorizontalOnly
466
494
  : updateVerticalOnly;
467
- return super.handle(events).pipe(tap(updater));
495
+ return super.handle(events).pipe(tap((updater)));
468
496
  }
469
497
  }
470
498
  function updateVerticalOnly(event) {
@@ -475,7 +503,6 @@ function updateVerticalOnly(event) {
475
503
  updateEvent(event, updateByScrollDistanceVertical);
476
504
  }
477
505
  function updateHorizontalOnly(event) {
478
- console.log("updateHorizontalOnly");
479
506
  const pointer = event.pointers[0];
480
507
  pointer.distance.y = 0;
481
508
  pointer.direction.y = 0;
@@ -520,14 +547,11 @@ const GestureDargVertical = gestureDrag({ horizontal: false, vertical: true });
520
547
 
521
548
  class GestureLongTapImpl extends Gesture {
522
549
  constructor(options) {
523
- super("gesture-longtap", ["touchstart", "touchmove", "touchend", "touchcancel"], {
524
- filterPointerTypes: ["touch" /* GesturePointerType.Touch */],
525
- ...options
526
- });
550
+ super("gesture-longtap", { pointerTypes: ["touch" /* GesturePointerType.Touch */], ...options });
527
551
  }
528
552
  capture(events) {
529
553
  return combineLatest({ timeWithin: timer(this.timeWithin).pipe(startWith(null)), event: events }).pipe(map(({ timeWithin, event }) => {
530
- if (event.pointers.length !== 1 || event.elapsed > this.timeWithin) {
554
+ if (event.elapsed > this.timeWithin) {
531
555
  return 2 /* GestureCaptureState.Skip */;
532
556
  }
533
557
  if (event.phase === "end" /* GesturePhase.End */ && event.elapsed > this.timeWithin) {
@@ -554,19 +578,22 @@ const GestureLongTap = gestureLongTap();
554
578
 
555
579
  class GestureTapImpl extends Gesture {
556
580
  constructor(options) {
557
- super("gesture-tap", ["touchstart", "touchmove", "touchend", "touchcancel", "mousedown", "mousemove", "mouseup"], {
558
- filterPointerTypes: ["mouse" /* GesturePointerType.Mouse */, "touch" /* GesturePointerType.Touch */],
559
- ...options
560
- });
581
+ super("gesture-tap", options);
561
582
  }
562
- // TODO
563
583
  capture(events) {
564
584
  return events.pipe(map(event => {
565
- if (event.pointers.length !== 1) {
566
- return 2 /* GestureCaptureState.Skip */;
567
- }
568
585
  const distance = event.pointers[0].distance;
569
586
  if (Math.abs(distance.x) < this.distanceInclusion && Math.abs(distance.y) < this.distanceInclusion) {
587
+ // TODO
588
+ // if (event.phase === GesturePhase.End) {
589
+ // if (event.target === event.origin.target || event.target.contains(event.origin.target)) {
590
+ // return GestureCaptureState.Instant
591
+ // } else {
592
+ // return GestureCaptureState.Skip
593
+ // }
594
+ // } else {
595
+ // return GestureCaptureState.Pending
596
+ // }
570
597
  return event.phase === "end" /* GesturePhase.End */ ? 4 /* GestureCaptureState.Instant */ : 1 /* GestureCaptureState.Pending */;
571
598
  }
572
599
  else {
@@ -615,10 +642,11 @@ class GestureService {
615
642
  }), filter(() => false)))),
616
643
  // Select active watchers
617
644
  map(event => {
645
+ updatePointers(event);
618
646
  const eventTarget = event.target;
619
647
  let includeScrollDistance = false;
620
648
  const gestures = this.#watchers
621
- .filter(({ gesture, el }) => gesture.filterByEvent(event) &&
649
+ .filter(({ gesture, el }) => gesture.shouldCapture(event) &&
622
650
  (el === eventTarget || ("contains" in el && el.contains(eventTarget))))
623
651
  .reduce((gestures, { gesture }) => {
624
652
  if (!gestures.has(gesture)) {
@@ -627,13 +655,13 @@ class GestureService {
627
655
  }
628
656
  return gestures;
629
657
  }, new Map());
630
- return { startEvent: event, gestures, includeScrollDistance };
658
+ return { detail: event, gestures, includeScrollDistance };
631
659
  }), filter(({ gestures }) => gestures.size > 0), tap(this.#disableTouchAction)
632
660
  // finalize(() => console.log("FINALIZE BEGIN"))
633
661
  )
634
662
  .subscribe(dst);
635
663
  });
636
- #gesture = this.#begin.pipe(switchMap(({ startEvent, gestures, includeScrollDistance }) => {
664
+ #gesture = this.#begin.pipe(switchMap(({ detail: startEvent, gestures, includeScrollDistance }) => {
637
665
  const pointerType = startEvent.pointerType;
638
666
  const startAt = startEvent.origin.timeStamp;
639
667
  const dispatchEvent = startEvent.target[DISPATCH_EVENT].bind(startEvent.target);
@@ -657,7 +685,7 @@ class GestureService {
657
685
  share());
658
686
  const captureState = eventStream.pipe(connect(src => {
659
687
  const state = { events: [], gestures, includeScrollDistance };
660
- return merge(src.pipe(tap(event => state.events.push(event))), ...Array.from(gestures.keys()).map(gesture => gesture.capture(src.pipe(filter(gesture.filterByEvent))).pipe(takeWhile(result => result !== 2 /* GestureCaptureState.Skip */, true), tap(result => gestures.set(gesture, result))))).pipe(map(() => state));
688
+ return merge(src.pipe(tap(event => state.events.push(event))), ...Array.from(gestures.keys()).map(gesture => gesture.capture(src.pipe(filter(gesture.shouldCapture.bind(gesture)))).pipe(takeWhile(result => result !== 2 /* GestureCaptureState.Skip */, true), tap(result => gestures.set(gesture, result))))).pipe(map(() => state));
661
689
  })
662
690
  // ,finalize(() => console.log("FINALIZE CAPTURE"))
663
691
  );
@@ -694,7 +722,9 @@ class GestureService {
694
722
  }), takeWhile(isFalsy, true), filter(isTruthy), takeWhile(v => v.gesture != null, false)
695
723
  // finalize(() => console.log("FINALIZE SELECT"))
696
724
  );
697
- return selectGesture.pipe(switchMap(({ events, gesture }) => gesture.handle(eventStream.pipe(startWith(...events), filter(gesture.filterByEvent))).pipe(takeWhile(v => v.phase !== "end" /* GesturePhase.End */, true), tap((e) => dispatchEvent(new CustomEvent(e.type, { detail: e, bubbles: true, cancelable: true })))
725
+ return selectGesture.pipe(switchMap(({ events, gesture }) => gesture
726
+ .handle(eventStream.pipe(startWith(...events), filter(gesture.isRelevantEvent.bind(gesture))))
727
+ .pipe(takeWhile(v => v.phase !== "end" /* GesturePhase.End */, true), tap(detail => dispatchEvent(new CustomEvent(gesture.name, { detail, bubbles: true, cancelable: true })))
698
728
  // finalize(() => console.log("GESTURE FINALIZE")),
699
729
  )),
700
730
  // finalize(() => console.log("FINALIZE RESULT")),
@@ -714,10 +744,10 @@ class GestureService {
714
744
  element[ADD_EVENT_LISTENER](gesture.name, next);
715
745
  dst.add(element[REMOVE_EVENT_LISTENER].bind(element, gesture.name, next));
716
746
  }
717
- dst.add(this.watch(element, ...gestures).subscribe());
747
+ dst.add(this.#watch(element, ...gestures).subscribe());
718
748
  }));
719
749
  }
720
- watch(el, ...gestures) {
750
+ #watch(el, ...gestures) {
721
751
  return new Observable((dst) => this.#zone.runOutsideAngular(() => {
722
752
  const element = coerceElement(el);
723
753
  const watchers = gestures.map(gesture => {