From c3a2b2360e3bd2cae3375ef3960d3d9528cd3e40 Mon Sep 17 00:00:00 2001
From: jojohoch <joachim.hoch@iqb.hu-berlin.de>
Date: Mon, 14 Mar 2022 10:39:45 +0100
Subject: [PATCH] [player] Fix position of floating marking bar

Replace custom pointer events with native pointer events
---
 .../marking-bar/marking-button.component.ts   |  9 +----
 .../components/ui-elements/text.component.ts  |  7 ++--
 .../element-text-group.component.html         | 19 ++++------
 .../element-text-group.component.ts           | 15 +++-----
 .../floating-marking-bar.component.html       |  2 +-
 .../floating-marking-bar.component.ts         |  3 +-
 .../src/app/services/native-event.service.ts  | 38 ++++---------------
 7 files changed, 29 insertions(+), 64 deletions(-)

diff --git a/projects/common/components/marking-bar/marking-button.component.ts b/projects/common/components/marking-bar/marking-button.component.ts
index 208978aaa..969aea651 100644
--- a/projects/common/components/marking-bar/marking-button.component.ts
+++ b/projects/common/components/marking-bar/marking-button.component.ts
@@ -10,8 +10,7 @@ import {
             [style.border-color]="selected ? 'black' : color"
             mat-mini-fab
             [style.background-color]="color"
-            (mousedown)="emitSelectedChanged($event)"
-            (touchstart)="emitSelectedChanged($event)">
+            (pointerdown)="emitSelectedChanged()">
       <mat-icon *ngIf="mode === 'mark'"
                 class="marking-icon">border_color
       </mat-icon>
@@ -36,11 +35,7 @@ export class MarkingButtonComponent {
     color: string,
   }>();
 
-  emitSelectedChanged(event: TouchEvent | MouseEvent): void {
-    if (event instanceof TouchEvent && event.cancelable) {
-      event.preventDefault();
-    }
-    event.stopPropagation();
+  emitSelectedChanged(): void {
     this.selected = !this.selected;
     this.selectedChanged.emit({ selected: this.selected, mode: this.mode, color: this.color });
   }
diff --git a/projects/common/components/ui-elements/text.component.ts b/projects/common/components/ui-elements/text.component.ts
index 5c8ce8021..3b5d05de5 100644
--- a/projects/common/components/ui-elements/text.component.ts
+++ b/projects/common/components/ui-elements/text.component.ts
@@ -30,8 +30,7 @@ import { TextElement, ValueChangeElement } from '../../interfaces/elements';
              [style.font-style]="elementModel.styling.italic ? 'italic' : ''"
              [style.text-decoration]="elementModel.styling.underline ? 'underline' : ''"
              [innerHTML]="savedText || elementModel.text | safeResourceHTML"
-             (touchstart)="emitStartSelection($event)"
-             (mousedown)="emitStartSelection($event)">
+             (pointerdown)="emitStartSelection($event)">
         </div>
     </div>
   `,
@@ -54,7 +53,7 @@ export class TextComponent extends ElementComponent {
   @Input() elementModel!: TextElement;
   @Input() savedText!: string;
   @Output() elementValueChanged = new EventEmitter<ValueChangeElement>();
-  @Output() startSelection = new EventEmitter<MouseEvent | TouchEvent>();
+  @Output() startSelection = new EventEmitter<PointerEvent>();
   @Output() applySelection = new EventEmitter<{
     active: boolean,
     mode: 'mark' | 'delete',
@@ -66,7 +65,7 @@ export class TextComponent extends ElementComponent {
 
   @ViewChild('textContainerRef') textContainerRef!: ElementRef;
 
-  emitStartSelection(event: TouchEvent | MouseEvent): void {
+  emitStartSelection(event: PointerEvent): void {
     if (this.elementModel.highlightableYellow ||
       this.elementModel.highlightableTurquoise ||
       this.elementModel.highlightableOrange) {
diff --git a/projects/player/src/app/components/element-text-group/element-text-group.component.html b/projects/player/src/app/components/element-text-group/element-text-group.component.html
index eea635cb1..a1704e063 100644
--- a/projects/player/src/app/components/element-text-group/element-text-group.component.html
+++ b/projects/player/src/app/components/element-text-group/element-text-group.component.html
@@ -1,18 +1,15 @@
-<div class="inline-container" cdkOverlayOrigin #overlayOrigin="cdkOverlayOrigin">
-  <aspect-text
-      #elementComponent
-      [elementModel]="elementModel | cast: TextElement"
-      [savedText]="initialValue"
-      (applySelection)="applySelection($event, elementComponent)"
-      (startSelection)="startSelection($event, elementComponent)"
-      (elementValueChanged)="unitStateService.changeElementValue($event)">
-  </aspect-text>
-</div>
+<aspect-text
+    #elementComponent
+    [elementModel]="elementModel | cast: TextElement"
+    [savedText]="initialValue"
+    (applySelection)="applySelection($event, elementComponent)"
+    (startSelection)="startSelection($event, elementComponent)"
+    (elementValueChanged)="unitStateService.changeElementValue($event)">
+</aspect-text>
 
 <aspect-floating-marking-bar
     *ngIf="elementModel.type === 'text'"
     [elementComponent]="elementComponent"
-    [overlayOrigin]="overlayOrigin"
     [isMarkingBarOpen]="isMarkingBarOpen"
     [textComponentRect]="textComponentRect"
     [textComponentContainerScrollTop]="textComponentContainerScrollTop"
diff --git a/projects/player/src/app/components/element-text-group/element-text-group.component.ts b/projects/player/src/app/components/element-text-group/element-text-group.component.ts
index 6eb67fc94..f999a4a8d 100644
--- a/projects/player/src/app/components/element-text-group/element-text-group.component.ts
+++ b/projects/player/src/app/components/element-text-group/element-text-group.component.ts
@@ -64,14 +64,11 @@ export class ElementTextGroupComponent extends ElementGroupDirective implements
     }
   }
 
-  startSelection(pointerDown: MouseEvent | TouchEvent, elementComponent: TextComponent): void {
+  startSelection(pointerDown: PointerEvent, elementComponent: TextComponent): void {
     this.isMarkingBarOpen = false;
     this.nativeEventService.pointerUp
       .pipe(takeUntil(this.ngUnsubscribe), first())
-      .subscribe((pointerUp: TouchEvent | MouseEvent) => {
-        if (pointerUp.cancelable) {
-          pointerUp.preventDefault();
-        }
+      .subscribe((pointerUp: PointerEvent) => {
         this.stopSelection(
           this.getClientPointFromEvent(pointerUp),
           pointerUp.ctrlKey,
@@ -110,9 +107,9 @@ export class ElementTextGroupComponent extends ElementGroupDirective implements
     }
   }
 
-  private getClientPointFromEvent = (event: MouseEvent | TouchEvent): { clientX: number, clientY: number } => ({
-    clientX: (event instanceof MouseEvent) ? event.clientX : event.changedTouches[0].clientX,
-    clientY: (event instanceof MouseEvent) ? event.clientY : event.changedTouches[0].clientY
+  private getClientPointFromEvent = (event: PointerEvent): { clientX: number, clientY: number } => ({
+    clientX: event.clientX,
+    clientY: event.clientY
   });
 
   private openMarkingBar(
@@ -120,7 +117,7 @@ export class ElementTextGroupComponent extends ElementGroupDirective implements
     downPosition: { clientX: number, clientY: number },
     elementComponent: TextComponent
   ) {
-    this.markingBarPosition.left = downPosition.clientY > mouseUp.clientY ? downPosition.clientX : mouseUp.clientX;
+    this.markingBarPosition.left = downPosition.clientX > mouseUp.clientX ? downPosition.clientX : mouseUp.clientX;
     this.markingBarPosition.top = downPosition.clientY > mouseUp.clientY ? downPosition.clientY : mouseUp.clientY;
     this.textComponentContainerScrollTop =
       elementComponent.domElement.closest('.fixed-size-content')?.scrollTop || 0;
diff --git a/projects/player/src/app/components/floating-marking-bar/floating-marking-bar.component.html b/projects/player/src/app/components/floating-marking-bar/floating-marking-bar.component.html
index 007152522..34005a08d 100644
--- a/projects/player/src/app/components/floating-marking-bar/floating-marking-bar.component.html
+++ b/projects/player/src/app/components/floating-marking-bar/floating-marking-bar.component.html
@@ -3,7 +3,7 @@
       elementModel.highlightableTurquoise ||
       elementModel.highlightableOrange"
     cdkConnectedOverlay
-    [cdkConnectedOverlayOrigin]="overlayOrigin"
+    [cdkConnectedOverlayOrigin]="elementComponent"
     [cdkConnectedOverlayPositions]="positions"
     [cdkConnectedOverlayOpen]="isMarkingBarOpen">
   <div class="marking-bar-container"
diff --git a/projects/player/src/app/components/floating-marking-bar/floating-marking-bar.component.ts b/projects/player/src/app/components/floating-marking-bar/floating-marking-bar.component.ts
index 43356536a..4d4be56ff 100644
--- a/projects/player/src/app/components/floating-marking-bar/floating-marking-bar.component.ts
+++ b/projects/player/src/app/components/floating-marking-bar/floating-marking-bar.component.ts
@@ -1,7 +1,7 @@
 import {
   Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges
 } from '@angular/core';
-import { CdkOverlayOrigin, ConnectedPosition } from '@angular/cdk/overlay';
+import { ConnectedPosition } from '@angular/cdk/overlay';
 import { ElementComponent } from '../../../../../common/directives/element-component.directive';
 import { TextComponent } from '../../../../../common/components/ui-elements/text.component';
 import { TextElement } from '../../../../../common/interfaces/elements';
@@ -13,7 +13,6 @@ import { TextElement } from '../../../../../common/interfaces/elements';
 })
 export class FloatingMarkingBarComponent implements OnInit, OnChanges {
   @Input() elementComponent!: ElementComponent;
-  @Input() overlayOrigin!: CdkOverlayOrigin;
   @Input() isMarkingBarOpen!: boolean;
   @Input() position!: { top: number, left: number };
   @Input() textComponentRect!: DOMRect;
diff --git a/projects/player/src/app/services/native-event.service.ts b/projects/player/src/app/services/native-event.service.ts
index 07bd9cb8a..52a7fe551 100644
--- a/projects/player/src/app/services/native-event.service.ts
+++ b/projects/player/src/app/services/native-event.service.ts
@@ -10,8 +10,8 @@ import { mergeMap } from 'rxjs/operators';
 })
 export class NativeEventService {
   private _focus = new Subject<boolean>();
-  private _pointerUp = new Subject<MouseEvent | TouchEvent>();
-  private _pointerDown = new Subject<MouseEvent | TouchEvent>();
+  private _pointerDown = new Subject<PointerEvent>();
+  private _pointerUp = new Subject<PointerEvent>();
   private _resize = new Subject<number>();
 
   constructor(@Inject(DOCUMENT) private document: Document) {
@@ -23,33 +23,11 @@ export class NativeEventService {
         () => this._focus.next(document.hasFocus())// Do something with the event here
       );
 
-    from(['mouseup', 'touchend'])
-      .pipe(
-        mergeMap(event => fromEvent(window, event))
-      )
-      .subscribe(
-        (event: Event) => {
-          if (event instanceof TouchEvent) {
-            this._pointerUp.next(event as TouchEvent);
-          } else {
-            this._pointerUp.next(event as MouseEvent);
-          }
-        }
-      );
+    fromEvent(window, 'pointerup')
+      .subscribe(event => this._pointerUp.next(event as PointerEvent));
 
-    from(['mousedown', 'touchstart'])
-      .pipe(
-        mergeMap(event => fromEvent(window, event))
-      )
-      .subscribe(
-        (event: Event) => {
-          if (event instanceof TouchEvent) {
-            this._pointerDown.next(event as TouchEvent);
-          } else {
-            this._pointerDown.next(event as MouseEvent);
-          }
-        }
-      );
+    fromEvent(window, 'pointerdown')
+      .subscribe(event => this._pointerDown.next(event as PointerEvent));
 
     fromEvent(window, 'resize')
       .subscribe(() => this._resize.next(window.innerWidth));
@@ -59,11 +37,11 @@ export class NativeEventService {
     return this._focus.asObservable();
   }
 
-  get pointerUp(): Observable<MouseEvent | TouchEvent> {
+  get pointerUp(): Observable<PointerEvent> {
     return this._pointerUp.asObservable();
   }
 
-  get pointerDown(): Observable<MouseEvent | TouchEvent> {
+  get pointerDown(): Observable<PointerEvent> {
     return this._pointerDown.asObservable();
   }
 
-- 
GitLab