@ngutil/aria 0.0.69 → 0.0.71

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.
@@ -1,12 +1,12 @@
1
1
  import { DOCUMENT } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
3
  import { inject, NgZone, Injectable, Inject, ElementRef, effect, Directive, input, computed, signal, untracked, NgModule } from '@angular/core';
4
- import { merge, fromEvent, map, share, filter, shareReplay, startWith, throttleTime, switchMap, timer, take, distinctUntilChanged, combineLatest, BehaviorSubject, of, debounceTime, Observable, EMPTY, from, tap, concatMap, scan, takeWhile, finalize, Subject, animationFrames } from 'rxjs';
4
+ import { merge, fromEvent, map, share, filter, shareReplay, startWith, throttleTime, switchMap, timer, take, distinctUntilChanged, combineLatest, BehaviorSubject, of, debounceTime, Observable, EMPTY, from, tap, Subject, connect, scan, takeWhile, finalize, animationFrames } from 'rxjs';
5
5
  import { FocusTrapFactory } from '@angular/cdk/a11y';
6
6
  import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
7
7
  import { focusable, isFocusable } from 'tabbable';
8
- import { coerceElement, Destructible, isElementInput, deepClone, coerceBoolAttr } from '@ngutil/common';
9
- import { flatten, clamp } from 'lodash';
8
+ import { coerceElement, Destructible, isElementInput, __zone_symbol__, isFalsy, isTruthy, deepClone, coerceBoolAttr } from '@ngutil/common';
9
+ import { clamp } from 'lodash-es';
10
10
 
11
11
  const EVENT_OPTIONS$1 = {
12
12
  capture: true,
@@ -356,167 +356,463 @@ function eventToKeystroke(event) {
356
356
  };
357
357
  }
358
358
 
359
- function stateToEvent(state, type) {
360
- return {
361
- type: type,
362
- origin: state.origin,
363
- target: state.target,
364
- pointerType: state.pointerType,
365
- phase: state.phase,
366
- pointers: state.pointers
367
- };
368
- }
369
359
  const Listeners = {
370
360
  mousedown: {
371
- target: "element" /* ListenerTarget.Element */,
372
361
  pointerType: "mouse" /* GesturePointerType.Mouse */,
373
362
  phase: "start" /* GesturePhase.Start */,
374
363
  options: { capture: true, passive: false }
375
364
  },
376
365
  mousemove: {
377
- target: "document" /* ListenerTarget.Document */,
378
366
  pointerType: "mouse" /* GesturePointerType.Mouse */,
379
367
  phase: "moving" /* GesturePhase.Moving */,
380
368
  options: { capture: true, passive: false }
381
369
  },
382
370
  mouseup: {
383
- target: "document" /* ListenerTarget.Document */,
384
371
  pointerType: "mouse" /* GesturePointerType.Mouse */,
385
372
  phase: "end" /* GesturePhase.End */,
386
- options: { capture: true, passive: true }
373
+ options: { capture: true, passive: false }
387
374
  },
388
375
  touchstart: {
389
- target: "element" /* ListenerTarget.Element */,
390
376
  pointerType: "touch" /* GesturePointerType.Touch */,
391
377
  phase: "start" /* GesturePhase.Start */,
392
378
  options: { capture: true, passive: false }
393
379
  },
394
380
  touchmove: {
395
- target: "document" /* ListenerTarget.Document */,
396
381
  pointerType: "touch" /* GesturePointerType.Touch */,
397
382
  phase: "moving" /* GesturePhase.Moving */,
398
383
  options: { capture: true, passive: false }
399
384
  },
400
385
  touchend: {
401
- target: "document" /* ListenerTarget.Document */,
402
386
  pointerType: "touch" /* GesturePointerType.Touch */,
403
387
  phase: "end" /* GesturePhase.End */,
404
388
  options: { capture: true, passive: false }
405
389
  },
406
390
  touchcancel: {
407
- target: "document" /* ListenerTarget.Document */,
408
391
  pointerType: "touch" /* GesturePointerType.Touch */,
409
392
  phase: "end" /* GesturePhase.End */,
410
- options: { capture: true, passive: true }
393
+ options: { capture: true, passive: false }
411
394
  }
395
+ // ,
396
+ // contextmenu: {
397
+ // pointerType: GesturePointerType.Mouse,
398
+ // phase: GesturePhase.Start,
399
+ // options: { capture: true, passive: false }
400
+ // }
412
401
  };
413
402
 
414
- const TypeMap = {
415
- ["start" /* GesturePhase.Start */]: "dragging-start",
416
- ["moving" /* GesturePhase.Moving */]: "dragging-move",
417
- ["end" /* GesturePhase.End */]: "dragging-end"
418
- };
419
- const Dragging = {
420
- name: "dragging",
421
- listeners: ["mousedown", "mousemove", "mouseup", "touchstart", "touchmove", "touchend", "touchcancel"],
422
- priority: 0,
423
- handler: events => events.pipe(filter(state => !state.pending || state.pending.length === 0), tap(state => state.preventDefault()), map(state => stateToEvent(state, TypeMap[state.phase])))
424
- };
403
+ class Gesture {
404
+ constructor(name, listeners, options = {}) {
405
+ this.name = name;
406
+ // TODO maybe global option
407
+ this.distanceInclusion = 10;
408
+ // TODO maybe global option
409
+ this.timeWithin = 300;
410
+ this.priority = 0;
411
+ 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)));
418
+ Object.assign(this, options);
419
+ this.filterListeners = listeners.filter(v => this.filterPointerTypes.includes(Listeners[v].pointerType));
420
+ }
421
+ /**
422
+ * Transform input event, to gesture event
423
+ * ! important, dont rely on this object state, because not always create a new object
424
+ */
425
+ handle(events) {
426
+ return events.pipe(tap(event => (event.type = this.name)));
427
+ }
428
+ }
425
429
 
426
- class GesturesService {
427
- #document = inject(DOCUMENT);
428
- #zone = inject(NgZone);
429
- #listeners = new Map();
430
- watch(el, ...gestures) {
431
- return this.#zone.runOutsideAngular(() => {
432
- const listeners = flatten(gestures.map(v => v.listeners || []));
433
- const { trigger, watch } = this.#getListeners(coerceElement(el), listeners);
434
- let pointerType;
435
- return trigger.pipe(filter(state => {
436
- if (pointerType == null) {
437
- pointerType = state.pointerType;
438
- }
439
- return pointerType === state.pointerType;
440
- }), concatMap(v => this.#zone.runOutsideAngular(() => {
441
- const watching = watch[pointerType].pipe(startWith(v), scan((state, curr) => updatePointers({ ...state, ...curr }), {}), takeWhile(state => state.phase !== "end" /* GesturePhase.End */, true), share());
442
- return merge(...gestures.map(v => v.handler(watching)));
443
- })));
430
+ const DRAG_LISTENERS = [
431
+ "mousedown",
432
+ "mousemove",
433
+ "mouseup",
434
+ "touchstart",
435
+ "touchmove",
436
+ "touchend",
437
+ "touchcancel"
438
+ ];
439
+ class GestureDragImpl extends Gesture {
440
+ constructor(options) {
441
+ super("gesture-drag", DRAG_LISTENERS, { includeScrollDistance: true, ...options });
442
+ if (this.horizontal == null && this.vertical == null) {
443
+ this.horizontal = true;
444
+ this.vertical = true;
445
+ }
446
+ }
447
+ capture(events) {
448
+ return events.pipe(map(state => {
449
+ if (state.pointers.length !== 1) {
450
+ return 2 /* GestureCaptureState.Skip */;
451
+ }
452
+ if (Math.abs(state.pointers[0].distance.x) > this.distanceInclusion) {
453
+ return this.horizontal ? 3 /* GestureCaptureState.Maybe */ : 2 /* GestureCaptureState.Skip */;
454
+ }
455
+ if (Math.abs(state.pointers[0].distance.y) > this.distanceInclusion) {
456
+ return this.vertical ? 3 /* GestureCaptureState.Maybe */ : 2 /* GestureCaptureState.Skip */;
457
+ }
458
+ return 1 /* GestureCaptureState.Pending */;
459
+ }));
460
+ }
461
+ handle(events) {
462
+ const updater = this.horizontal && this.vertical
463
+ ? updateAnyDirection
464
+ : this.horizontal
465
+ ? updateHorizontalOnly
466
+ : updateVerticalOnly;
467
+ return super.handle(events).pipe(tap(updater));
468
+ }
469
+ }
470
+ function updateVerticalOnly(event) {
471
+ const pointer = event.pointers[0];
472
+ pointer.distance.x = 0;
473
+ pointer.direction.x = 0;
474
+ pointer.current.x = pointer.start.x;
475
+ updateEvent(event, updateByScrollDistanceVertical);
476
+ }
477
+ function updateHorizontalOnly(event) {
478
+ console.log("updateHorizontalOnly");
479
+ const pointer = event.pointers[0];
480
+ pointer.distance.y = 0;
481
+ pointer.direction.y = 0;
482
+ pointer.current.y = pointer.start.y;
483
+ updateEvent(event, updateByScrollDistanceHorizontal);
484
+ }
485
+ function updateAnyDirection(event) {
486
+ updateEvent(event, updateByScrollDistanceBoth);
487
+ }
488
+ function updateEvent(event, scrollUpdate) {
489
+ event.moveBy = { ...event.pointers[0].distance };
490
+ scrollUpdate(event);
491
+ }
492
+ function updateByScrollDistanceVertical(event) {
493
+ const sd = event.scrollDistance;
494
+ if (sd == null) {
495
+ return;
496
+ }
497
+ event.moveBy.y += sd.y;
498
+ }
499
+ function updateByScrollDistanceHorizontal(event) {
500
+ const sd = event.scrollDistance;
501
+ if (sd == null) {
502
+ return;
503
+ }
504
+ event.moveBy.x += sd.x;
505
+ }
506
+ function updateByScrollDistanceBoth(event) {
507
+ const sd = event.scrollDistance;
508
+ if (sd == null) {
509
+ return;
510
+ }
511
+ event.moveBy.x += sd.x;
512
+ event.moveBy.y += sd.y;
513
+ }
514
+ function gestureDrag(options) {
515
+ return new GestureDragImpl(options);
516
+ }
517
+ const GestureDarg = gestureDrag();
518
+ const GestureDargHorizontal = gestureDrag({ horizontal: true, vertical: false });
519
+ const GestureDargVertical = gestureDrag({ horizontal: false, vertical: true });
520
+
521
+ class GestureLongTapImpl extends Gesture {
522
+ constructor(options) {
523
+ super("gesture-longtap", ["touchstart", "touchmove", "touchend", "touchcancel"], {
524
+ filterPointerTypes: ["touch" /* GesturePointerType.Touch */],
525
+ ...options
444
526
  });
445
527
  }
446
- #getListeners(inputEl, listeners) {
447
- const triggers = [];
448
- const watches = {};
449
- for (const name of listeners) {
450
- const conf = Listeners[name];
451
- const container = conf.phase === "start" /* GesturePhase.Start */
452
- ? triggers
453
- : (watches[conf.pointerType] = watches[conf.pointerType] || []);
454
- if (container.indexOf(name) === -1) {
455
- container.push(name);
528
+ capture(events) {
529
+ 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) {
531
+ return 2 /* GestureCaptureState.Skip */;
456
532
  }
457
- }
458
- if (triggers.length === 0) {
459
- throw Error("Missing start events");
460
- }
461
- const observable = (names) => {
462
- if (names.length === 0) {
463
- return of();
533
+ if (event.phase === "end" /* GesturePhase.End */ && event.elapsed > this.timeWithin) {
534
+ return 2 /* GestureCaptureState.Skip */;
464
535
  }
465
- else if (names.length === 1) {
466
- return this.#getListener(inputEl, names[0]);
536
+ const distance = event.pointers[0].distance;
537
+ if (Math.abs(distance.x) < this.distanceInclusion && Math.abs(distance.y) < this.distanceInclusion) {
538
+ // maybe is ok event.phase === GesturePhase.End
539
+ return timeWithin !== null ? 4 /* GestureCaptureState.Instant */ : 1 /* GestureCaptureState.Pending */;
467
540
  }
468
541
  else {
469
- return merge(...names.map(v => this.#getListener(inputEl, v)));
542
+ return 2 /* GestureCaptureState.Skip */;
470
543
  }
471
- };
472
- return {
473
- trigger: observable(triggers),
474
- watch: {
475
- ["mouse" /* GesturePointerType.Mouse */]: observable(watches["mouse" /* GesturePointerType.Mouse */]),
476
- ["touch" /* GesturePointerType.Touch */]: observable(watches["touch" /* GesturePointerType.Touch */])
544
+ }));
545
+ }
546
+ handle(events) {
547
+ return super.handle(events.pipe(filter(event => event.phase === "start" /* GesturePhase.Start */ || event.phase === "end" /* GesturePhase.End */)));
548
+ }
549
+ }
550
+ function gestureLongTap(options) {
551
+ return new GestureLongTapImpl(options);
552
+ }
553
+ const GestureLongTap = gestureLongTap();
554
+
555
+ class GestureTapImpl extends Gesture {
556
+ constructor(options) {
557
+ super("gesture-tap", ["touchstart", "touchmove", "touchend", "touchcancel", "mousedown", "mousemove", "mouseup"], {
558
+ filterPointerTypes: ["mouse" /* GesturePointerType.Mouse */, "touch" /* GesturePointerType.Touch */],
559
+ ...options
560
+ });
561
+ }
562
+ // TODO
563
+ capture(events) {
564
+ return events.pipe(map(event => {
565
+ if (event.pointers.length !== 1) {
566
+ return 2 /* GestureCaptureState.Skip */;
477
567
  }
478
- };
568
+ const distance = event.pointers[0].distance;
569
+ if (Math.abs(distance.x) < this.distanceInclusion && Math.abs(distance.y) < this.distanceInclusion) {
570
+ return event.phase === "end" /* GesturePhase.End */ ? 4 /* GestureCaptureState.Instant */ : 1 /* GestureCaptureState.Pending */;
571
+ }
572
+ else {
573
+ return 2 /* GestureCaptureState.Skip */;
574
+ }
575
+ }));
576
+ }
577
+ handle(events) {
578
+ return super.handle(events.pipe(filter(event => event.phase === "start" /* GesturePhase.Start */ || event.phase === "end" /* GesturePhase.End */)));
479
579
  }
480
- #getListener(inputEl, name) {
481
- return this.#zone.runOutsideAngular(() => {
482
- const target = Listeners[name].target;
483
- const targetObj = target === "document" ? this.#document : inputEl;
484
- let targetListeners = this.#listeners.get(targetObj);
485
- if (targetListeners == null) {
486
- targetListeners = new Map();
487
- this.#listeners.set(targetObj, targetListeners);
580
+ }
581
+ function gestureTap(options) {
582
+ return new GestureTapImpl(options);
583
+ }
584
+ const GestureTap = gestureTap();
585
+
586
+ const ADD_EVENT_LISTENER = __zone_symbol__("addEventListener");
587
+ const REMOVE_EVENT_LISTENER = __zone_symbol__("removeEventListener");
588
+ const DISPATCH_EVENT = __zone_symbol__("dispatchEvent");
589
+ const SCROLL_LISTENER_OPTIONS = { passive: true };
590
+ class GestureService {
591
+ #zone = inject(NgZone);
592
+ #document = inject(DOCUMENT);
593
+ #watchers = [];
594
+ #trigger = new Subject();
595
+ #moving = merge(...Object.keys(Listeners)
596
+ .filter(name => Listeners[name].phase === "moving" /* GesturePhase.Moving */)
597
+ .map(name => this.#listen(name, Listeners[name]))).pipe(share());
598
+ #end = merge(...Object.keys(Listeners)
599
+ .filter(name => Listeners[name].phase === "end" /* GesturePhase.End */)
600
+ .map(name => this.#listen(name, Listeners[name]))).pipe(share());
601
+ #eventStream = merge(this.#moving, this.#end).pipe(share());
602
+ #begin = new Observable((dst) => {
603
+ let pointerType;
604
+ return this.#trigger
605
+ .pipe(filter(event => {
606
+ if (pointerType == null) {
607
+ pointerType = event.pointerType;
488
608
  }
489
- let listener = targetListeners.get(name);
490
- if (listener == null) {
491
- const { phase, pointerType, options } = Listeners[name];
492
- const passive = options?.passive;
493
- listener = fromEvent(targetObj, name, options).pipe(finalize(() => {
494
- targetListeners.delete(name);
495
- }), map(origin => ({
496
- origin,
497
- phase,
498
- pointerType,
499
- preventDefault: passive === false ? origin.preventDefault.bind(origin) : noop
500
- })));
501
- if (phase === "start" /* GesturePhase.Start */) {
502
- listener = listener.pipe(tap(state => {
503
- ;
504
- state.target = state.origin.target;
505
- }));
609
+ return event.pointerType === pointerType;
610
+ }), connect(events => merge(events,
611
+ // reset pointerType on end, after 200ms, because touchend is maybe followed by a mouse event
612
+ this.#end.pipe(debounceTime(200), tap(() => {
613
+ pointerType = undefined;
614
+ this.#enableTouchAction();
615
+ }), filter(() => false)))),
616
+ // Select active watchers
617
+ map(event => {
618
+ const eventTarget = event.target;
619
+ let includeScrollDistance = false;
620
+ const gestures = this.#watchers
621
+ .filter(({ gesture, el }) => gesture.filterByEvent(event) &&
622
+ (el === eventTarget || ("contains" in el && el.contains(eventTarget))))
623
+ .reduce((gestures, { gesture }) => {
624
+ if (!gestures.has(gesture)) {
625
+ includeScrollDistance = includeScrollDistance || gesture.includeScrollDistance;
626
+ gestures.set(gesture, 0 /* GestureCaptureState.Unchecked */);
506
627
  }
507
- listener = listener.pipe(share());
508
- targetListeners.set(name, listener);
628
+ return gestures;
629
+ }, new Map());
630
+ return { startEvent: event, gestures, includeScrollDistance };
631
+ }), filter(({ gestures }) => gestures.size > 0), tap(this.#disableTouchAction)
632
+ // finalize(() => console.log("FINALIZE BEGIN"))
633
+ )
634
+ .subscribe(dst);
635
+ });
636
+ #gesture = this.#begin.pipe(switchMap(({ startEvent, gestures, includeScrollDistance }) => {
637
+ const pointerType = startEvent.pointerType;
638
+ const startAt = startEvent.origin.timeStamp;
639
+ const dispatchEvent = startEvent.target[DISPATCH_EVENT].bind(startEvent.target);
640
+ const eventStreamInit = this.#eventStream.pipe(startWith(startEvent), filter(event => event.pointerType === pointerType));
641
+ const eventStreamSource = !includeScrollDistance
642
+ ? eventStreamInit
643
+ : combineLatest([
644
+ eventStreamInit,
645
+ this.#scrollDistance(startEvent.target).pipe(startWith({ x: 0, y: 0 }))
646
+ ]).pipe(map(([src, distance]) => {
647
+ ;
648
+ src.scrollDistance = distance;
649
+ return src;
650
+ }));
651
+ const eventStream = eventStreamSource.pipe(scan((state, curr) => updatePointers({
652
+ ...state,
653
+ ...curr,
654
+ elapsed: curr.origin.timeStamp - startAt
655
+ }), startEvent), takeWhile(event => event.phase !== "end" /* GesturePhase.End */, true),
656
+ // finalize(() => console.log("FINALIZE WATCH")),
657
+ share());
658
+ const captureState = eventStream.pipe(connect(src => {
659
+ 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));
661
+ })
662
+ // ,finalize(() => console.log("FINALIZE CAPTURE"))
663
+ );
664
+ const selectGesture = captureState.pipe(map(state => {
665
+ const partitions = {};
666
+ for (const [gesture, captureState] of state.gestures) {
667
+ const partition = (partitions[captureState] ??= []);
668
+ partition.push(gesture);
509
669
  }
510
- return listener;
511
- });
670
+ if (partitions[4 /* GestureCaptureState.Instant */] != null) {
671
+ return {
672
+ gesture: partitions[4 /* GestureCaptureState.Instant */].sort(sortByPripority)[0],
673
+ events: state.events
674
+ };
675
+ }
676
+ // while not all gestures return from Gesture.capture
677
+ if (partitions[0 /* GestureCaptureState.Unchecked */] != null) {
678
+ return null;
679
+ }
680
+ // while has pending, the capture is continued
681
+ if (partitions[1 /* GestureCaptureState.Pending */] != null) {
682
+ return null;
683
+ }
684
+ // no pendig & has maybe
685
+ if (partitions[3 /* GestureCaptureState.Maybe */] != null) {
686
+ return {
687
+ gesture: partitions[3 /* GestureCaptureState.Maybe */].sort(sortByPripority)[0],
688
+ events: state.events
689
+ };
690
+ }
691
+ // no pending & no maybe & no terminate
692
+ // so, nothign matched
693
+ return { events: state.events };
694
+ }), takeWhile(isFalsy, true), filter(isTruthy), takeWhile(v => v.gesture != null, false)
695
+ // finalize(() => console.log("FINALIZE SELECT"))
696
+ );
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 })))
698
+ // finalize(() => console.log("GESTURE FINALIZE")),
699
+ )),
700
+ // finalize(() => console.log("FINALIZE RESULT")),
701
+ finalize(this.#enableTouchAction));
702
+ }), share());
703
+ constructor() {
704
+ const triggers = merge(...Object.keys(Listeners)
705
+ .filter(name => Listeners[name].phase === "start" /* GesturePhase.Start */)
706
+ .map(name => this.#listen(name, Listeners[name])));
707
+ triggers.pipe(takeUntilDestroyed()).subscribe(this.#trigger);
708
+ }
709
+ listen(el, ...gestures) {
710
+ return new Observable((dst) => this.#zone.runOutsideAngular(() => {
711
+ const element = coerceElement(el);
712
+ const next = dst.next.bind(dst);
713
+ for (const gesture of gestures) {
714
+ element[ADD_EVENT_LISTENER](gesture.name, next);
715
+ dst.add(element[REMOVE_EVENT_LISTENER].bind(element, gesture.name, next));
716
+ }
717
+ dst.add(this.watch(element, ...gestures).subscribe());
718
+ }));
512
719
  }
513
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: GesturesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
514
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: GesturesService, providedIn: "root" }); }
720
+ watch(el, ...gestures) {
721
+ return new Observable((dst) => this.#zone.runOutsideAngular(() => {
722
+ const element = coerceElement(el);
723
+ const watchers = gestures.map(gesture => {
724
+ return { gesture, el: element };
725
+ });
726
+ this.#add(watchers);
727
+ dst.add(this.#gesture.subscribe(dst));
728
+ return () => {
729
+ this.#remove(watchers);
730
+ };
731
+ }));
732
+ }
733
+ #add(watchers) {
734
+ this.#watchers = this.#watchers.concat(watchers);
735
+ }
736
+ #remove(watchers) {
737
+ this.#watchers = this.#watchers.filter(v => !watchers.includes(v));
738
+ }
739
+ #listen(name, config) {
740
+ const { phase, pointerType, options } = config;
741
+ const toResult = phase === "start" /* GesturePhase.Start */
742
+ ? (origin) => ({
743
+ origin,
744
+ phase,
745
+ pointerType,
746
+ target: origin.target
747
+ })
748
+ : (origin) => {
749
+ if (origin.cancelable) {
750
+ origin.preventDefault();
751
+ }
752
+ return { origin, phase, pointerType };
753
+ };
754
+ return new Observable((dst) => this.#zone.runOutsideAngular(() => {
755
+ const listener = (origin) => {
756
+ if (origin.defaultPrevented) {
757
+ return;
758
+ }
759
+ dst.next(toResult(origin));
760
+ };
761
+ // console.log("addEventListener", name)
762
+ this.#document[ADD_EVENT_LISTENER](name, listener, options);
763
+ return () => {
764
+ // console.log("removeEventListener", name)
765
+ this.#document[REMOVE_EVENT_LISTENER](name, listener, options);
766
+ };
767
+ }));
768
+ }
769
+ #scrollDistance(element) {
770
+ const scrollPosition = () => {
771
+ let x = 0;
772
+ let y = 0;
773
+ let p = element;
774
+ do {
775
+ x += p.scrollLeft ?? 0;
776
+ y += p.scrollTop ?? 0;
777
+ p = p.parentNode;
778
+ } while (p != null);
779
+ return { x, y };
780
+ };
781
+ return new Observable((dst) => this.#zone.runOutsideAngular(() => {
782
+ const initial = scrollPosition();
783
+ const listener = () => {
784
+ const current = scrollPosition();
785
+ dst.next({ x: current.x - initial.x, y: current.y - initial.y });
786
+ };
787
+ this.#document[ADD_EVENT_LISTENER]("scroll", listener, SCROLL_LISTENER_OPTIONS);
788
+ return () => {
789
+ this.#document[REMOVE_EVENT_LISTENER]("scroll", listener, SCROLL_LISTENER_OPTIONS);
790
+ };
791
+ }));
792
+ }
793
+ #lastTouchAction;
794
+ #disableTouchAction = () => {
795
+ if (this.#lastTouchAction == null) {
796
+ this.#lastTouchAction = window.getComputedStyle(this.#document.body).touchAction;
797
+ this.#document.body.style.touchAction = "none";
798
+ }
799
+ };
800
+ #enableTouchAction = () => {
801
+ if (this.#lastTouchAction != null) {
802
+ this.#document.body.style.touchAction = this.#lastTouchAction;
803
+ this.#lastTouchAction = undefined;
804
+ }
805
+ };
806
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: GestureService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
807
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: GestureService, providedIn: "root" }); }
515
808
  }
516
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: GesturesService, decorators: [{
809
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: GestureService, decorators: [{
517
810
  type: Injectable,
518
811
  args: [{ providedIn: "root" }]
519
- }] });
812
+ }], ctorParameters: () => [] });
813
+ function sortByPripority(a, b) {
814
+ return b.priority - a.priority;
815
+ }
520
816
  function pointersFromEvent(event) {
521
817
  if (event instanceof MouseEvent) {
522
818
  return [
@@ -558,9 +854,6 @@ function updatePointers(state) {
558
854
  function direction(prev, curr) {
559
855
  return curr > prev ? 1 : curr < prev ? -1 : 0;
560
856
  }
561
- // const svc = new GesturesService()
562
- // const w = svc.watch(document.createElement("div"), DragAndDrop)
563
- function noop() { }
564
857
 
565
858
  const COMPILE_CACHE = {};
566
859
  function compile(selector) {
@@ -1217,5 +1510,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.6", ngImpor
1217
1510
  * Generated bundle index. Do not edit.
1218
1511
  */
1219
1512
 
1220
- export { AbstractUiState, ActivityService, BusyDirective, DisabledDirective, Dragging, FocusService, FocusState, FocusTrap, Focusable, GesturesService, KeystrokeService, Listeners, NOTSET, ProgressSegmentRef, ProgressState, ReadonlyDirective, UiState, UiStateModule, stateToEvent };
1513
+ export { AbstractUiState, ActivityService, BusyDirective, DisabledDirective, FocusService, FocusState, FocusTrap, Focusable, Gesture, GestureDarg, GestureDargHorizontal, GestureDargVertical, GestureDragImpl, GestureLongTap, GestureLongTapImpl, GestureService, GestureTap, GestureTapImpl, KeystrokeService, Listeners, NOTSET, ProgressSegmentRef, ProgressState, ReadonlyDirective, UiState, UiStateModule, gestureDrag, gestureLongTap, gestureTap };
1221
1514
  //# sourceMappingURL=ngutil-aria.mjs.map