From 861feff8447fa8326054dc2d2eabab2b30de0081 Mon Sep 17 00:00:00 2001
From: jojohoch <joachim.hoch@iqb.hu-berlin.de>
Date: Sat, 21 May 2022 13:59:17 +0200
Subject: [PATCH] [player] Refactor TextInputGroupElementComponent with marking
 mar

- rename variables, methods and properties
- reduce attributes for methods
- split code in sun methods
---
 .../text-group-element.component.html         |  8 +--
 .../text-group-element.component.ts           | 59 +++++++++++--------
 .../floating-marking-bar.component.html       | 10 ++--
 .../floating-marking-bar.component.ts         | 59 +++++++++++--------
 4 files changed, 76 insertions(+), 60 deletions(-)

diff --git a/projects/player/src/app/components/elements/text-group-element/text-group-element.component.html b/projects/player/src/app/components/elements/text-group-element/text-group-element.component.html
index d4d6b37ba..42a65e0bb 100644
--- a/projects/player/src/app/components/elements/text-group-element/text-group-element.component.html
+++ b/projects/player/src/app/components/elements/text-group-element/text-group-element.component.html
@@ -2,8 +2,8 @@
     #elementComponent
     [elementModel]="elementModel | cast: TextElement"
     [savedText]="initialValue"
-    (markingDataChanged)="applyMarkingData($event, elementComponent)"
-    (textSelectionStart)="startTextSelection($event, elementComponent)"
+    (markingDataChanged)="applyMarkingData($event)"
+    (textSelectionStart)="startTextSelection($event)"
     (elementValueChanged)="unitStateService.changeElementCodeValue($event)">
 </aspect-text>
 <aspect-floating-marking-bar
@@ -11,6 +11,6 @@
     [isMarkingBarOpen]="isMarkingBarOpen"
     [textComponentRect]="textComponentRect"
     [textComponentContainerScrollTop]="textComponentContainerScrollTop"
-    [position]="markingBarPosition"
-    (markingDataChanged)="applyMarkingDataToText($event.mode, $event.color, elementComponent)">
+    [markingBarPosition]="markingBarPosition"
+    (markingDataChanged)="applyMarkingDataToText($event.mode, $event.color)">
 </aspect-floating-marking-bar>
diff --git a/projects/player/src/app/components/elements/text-group-element/text-group-element.component.ts b/projects/player/src/app/components/elements/text-group-element/text-group-element.component.ts
index dc55959f4..77be0bc5e 100644
--- a/projects/player/src/app/components/elements/text-group-element/text-group-element.component.ts
+++ b/projects/player/src/app/components/elements/text-group-element/text-group-element.component.ts
@@ -9,7 +9,6 @@ import { NativeEventService } from '../../../services/native-event.service';
 import { UnitStateService } from '../../../services/unit-state.service';
 import { ElementGroupDirective } from '../../../directives/element-group.directive';
 import { ElementModelElementCodeMappingService } from '../../../services/element-model-element-code-mapping.service';
-import { ElementComponent } from 'common/directives/element-component.directive';
 import { TextElement } from 'common/models/elements/text/text';
 
 @Component({
@@ -18,7 +17,7 @@ import { TextElement } from 'common/models/elements/text/text';
   styleUrls: ['./text-group-element.component.scss']
 })
 export class TextGroupElementComponent extends ElementGroupDirective implements OnInit, AfterViewInit, OnDestroy {
-  @ViewChild('elementComponent') elementComponent!: ElementComponent;
+  @ViewChild('elementComponent') elementComponent!: TextComponent;
   TextElement!: TextElement;
 
   initialValue: string = '';
@@ -55,72 +54,80 @@ export class TextGroupElementComponent extends ElementGroupDirective implements
   }
 
   applyMarkingData(
-    selection: { active: boolean; mode: 'mark' | 'delete'; color: string; colorName: string | undefined },
-    elementComponent: TextComponent
+    selection: { active: boolean; mode: 'mark' | 'delete'; color: string; colorName: string | undefined }
   ): void {
     if (selection.active) {
       this.selectedColor = selection.color;
       this.selectedMode = selection.mode;
-      this.applyMarkingDataToText(selection.mode, selection.color, elementComponent);
+      this.applyMarkingDataToText(selection.mode, selection.color);
     } else {
       this.selectedColor = null;
       this.selectedMode = null;
     }
   }
 
-  startTextSelection(pointerDown: PointerEvent, elementComponent: TextComponent): void {
+  startTextSelection(pointerDown: PointerEvent): void {
     this.isMarkingBarOpen = false;
     this.nativeEventService.pointerUp
       .pipe(takeUntil(this.ngUnsubscribe), first())
       .subscribe((pointerUp: PointerEvent) => {
         this.stopTextSelection(
-          { clientX: pointerUp.clientX, clientY: pointerUp.clientY },
-          pointerUp.ctrlKey,
-          { clientX: pointerDown.clientX, clientY: pointerDown.clientY },
-          elementComponent
+          {
+            startSelectionX: pointerDown.clientX,
+            startSelectionY: pointerDown.clientY,
+            stopSelectionX: pointerUp.clientX,
+            stopSelectionY: pointerUp.clientY
+          },
+          pointerUp.ctrlKey
         );
       });
   }
 
-  applyMarkingDataToText(mode: 'mark' | 'delete', color: string, elementComponent: TextComponent): void {
+  applyMarkingDataToText(mode: 'mark' | 'delete', color: string): void {
     TextMarkingService
       .applyMarkingDataToText(
         mode,
         color,
-        elementComponent
+        this.elementComponent
       );
     this.isMarkingBarOpen = false;
   }
 
   private stopTextSelection(
-    pointerUpPoint: { clientX: number, clientY: number },
-    ctrlKey: boolean,
-    pointerDownPoint: { clientX: number, clientY: number },
-    elementComponent: TextComponent
+    textSelectionPosition: {
+      stopSelectionX: number, stopSelectionY: number, startSelectionX: number, startSelectionY: number
+    },
+    isControlKeyPressed: boolean // do not allow multiple selections (FF)
   ) {
     const selection = window.getSelection();
     if (selection && TextMarkingService.isSelectionValid(selection) && selection.rangeCount > 0) {
       if (!TextMarkingService
-        .isRangeInside(selection.getRangeAt(0), elementComponent.textContainerRef.nativeElement) || (ctrlKey)) {
+        .isRangeInside(
+          selection.getRangeAt(0), this.elementComponent.textContainerRef.nativeElement
+        ) || (isControlKeyPressed)) {
         selection.removeAllRanges();
       } else if (this.selectedMode && this.selectedColor) {
-        this.applyMarkingDataToText(this.selectedMode, this.selectedColor, elementComponent);
+        this.applyMarkingDataToText(this.selectedMode, this.selectedColor);
       } else if (!this.isMarkingBarOpen) {
-        this.openMarkingBar(pointerUpPoint, pointerDownPoint, elementComponent);
+        this.openMarkingBar(textSelectionPosition);
       }
     }
   }
 
   private openMarkingBar(
-    mouseUp: { clientX: number, clientY: number },
-    downPosition: { clientX: number, clientY: number },
-    elementComponent: TextComponent
+    textSelectionPosition: {
+      stopSelectionX: number, stopSelectionY: number, startSelectionX: number, startSelectionY: number
+    }
   ) {
-    this.markingBarPosition.left = downPosition.clientX > mouseUp.clientX ? downPosition.clientX : mouseUp.clientX;
-    this.markingBarPosition.top = downPosition.clientY > mouseUp.clientY ? downPosition.clientY : mouseUp.clientY;
+    this.markingBarPosition.left =
+      textSelectionPosition.startSelectionX > textSelectionPosition.stopSelectionX ?
+        textSelectionPosition.startSelectionX : textSelectionPosition.stopSelectionX;
+    this.markingBarPosition.top =
+      textSelectionPosition.startSelectionY > textSelectionPosition.stopSelectionY ?
+        textSelectionPosition.startSelectionY : textSelectionPosition.stopSelectionY;
     this.textComponentContainerScrollTop =
-      elementComponent.domElement.closest('.fixed-size-content')?.scrollTop || 0;
-    this.textComponentRect = elementComponent.domElement.getBoundingClientRect();
+      this.elementComponent.domElement.closest('.fixed-size-content')?.scrollTop || 0;
+    this.textComponentRect = this.elementComponent.domElement.getBoundingClientRect();
     this.isMarkingBarOpen = true;
     this.nativeEventService.pointerDown
       .pipe(takeUntil(this.ngUnsubscribe), first())
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 f373bc45e..ff0ace08b 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
@@ -1,16 +1,16 @@
 <ng-template
-    *ngIf="elementModel.highlightableYellow ||
-      elementModel.highlightableTurquoise ||
-      elementModel.highlightableOrange"
+    *ngIf="elementComponent.elementModel.highlightableYellow ||
+      elementComponent.elementModel.highlightableTurquoise ||
+      elementComponent.elementModel.highlightableOrange"
     cdkConnectedOverlay
     [cdkConnectedOverlayOrigin]="elementComponent"
-    [cdkConnectedOverlayPositions]="positions"
+    [cdkConnectedOverlayPositions]="overlayPositions"
     [cdkConnectedOverlayOpen]="isMarkingBarOpen">
   <div class="marking-bar-container"
        (mousedown)="$event.stopPropagation()"
        cdkDrag>
     <aspect-text-marking-bar
-        [elementModel]="elementModel"
+        [elementModel]="elementComponent.elementModel"
         (markingDataChanged)="markingDataChanged.emit($event)">
     </aspect-text-marking-bar>
   </div>
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 d2e5f8983..6ef79ae35 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,20 +1,18 @@
 import {
-  Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges
+  Component, EventEmitter, Input, OnChanges, Output, SimpleChanges
 } from '@angular/core';
 import { ConnectedPosition } from '@angular/cdk/overlay';
-import { ElementComponent } from 'common/directives/element-component.directive';
 import { TextComponent } from 'common/components/text/text.component';
-import { TextElement } from 'common/models/elements/text/text';
 
 @Component({
   selector: 'aspect-floating-marking-bar',
   templateUrl: './floating-marking-bar.component.html',
   styleUrls: ['./floating-marking-bar.component.scss']
 })
-export class FloatingMarkingBarComponent implements OnInit, OnChanges {
-  @Input() elementComponent!: ElementComponent;
+export class FloatingMarkingBarComponent implements OnChanges {
+  @Input() elementComponent!: TextComponent;
   @Input() isMarkingBarOpen!: boolean;
-  @Input() position!: { top: number, left: number };
+  @Input() markingBarPosition!: { top: number, left: number };
   @Input() textComponentRect!: DOMRect;
   @Input() textComponentContainerScrollTop!: number;
 
@@ -25,8 +23,7 @@ export class FloatingMarkingBarComponent implements OnInit, OnChanges {
     colorName: string | undefined;
   }>();
 
-  elementModel!: TextElement;
-  positions: ConnectedPosition[] = [{
+  overlayPositions: ConnectedPosition[] = [{
     originX: 'start',
     originY: 'top',
     overlayX: 'start',
@@ -35,37 +32,49 @@ export class FloatingMarkingBarComponent implements OnInit, OnChanges {
     offsetY: 0
   }];
 
-  ngOnInit(): void {
-    this.elementModel = (this.elementComponent as TextComponent).elementModel;
-  }
 
   ngOnChanges(changes: SimpleChanges): void {
     if (changes.isMarkingBarOpen && this.isMarkingBarOpen) {
-      this.calculatePosition();
+      this.correctMarkingBarPosition();
     }
   }
 
-  private calculateOffset(): number {
+  private getBarWidth(): number {
     return (1 + [
-      this.elementModel.highlightableYellow,
-      this.elementModel.highlightableTurquoise,
-      this.elementModel.highlightableOrange
+      this.elementComponent.elementModel.highlightableYellow,
+      this.elementComponent.elementModel.highlightableTurquoise,
+      this.elementComponent.elementModel.highlightableOrange
     ].filter(element => element).length) * 60;
   }
 
-  private calculatePosition(): void {
-    const viewConstraint = {
+  private correctMarkingBarPosition(): void {
+    const convertMarkingBarPosition = this.convertMarkingBarPositionToTextComponentRect();
+    const barConstraint = this.getBarConstraint();
+    this.overlayPositions[0].offsetX =
+      barConstraint.left < convertMarkingBarPosition.left ? barConstraint.left : convertMarkingBarPosition.left;
+    this.overlayPositions[0].offsetY = barConstraint.top < convertMarkingBarPosition.top ?
+      barConstraint.top - 50 + this.textComponentContainerScrollTop :
+      convertMarkingBarPosition.top + this.textComponentContainerScrollTop;
+  }
+
+  private getViewConstraint(): { top: number, left: number } {
+    return  {
       top: window.innerHeight - this.textComponentRect.top > this.textComponentRect.height ?
         this.textComponentRect.height :
         window.innerHeight - this.textComponentRect.top,
       left: this.textComponentRect.width
     };
-    const barConstraint = { top: viewConstraint.top - 100, left: viewConstraint.left - this.calculateOffset() };
-    const left = this.position.left - this.textComponentRect.left;
-    const top = this.position.top - this.textComponentRect.top + 15;
-    this.positions[0].offsetX = barConstraint.left < left ? barConstraint.left : left;
-    this.positions[0].offsetY = barConstraint.top < top ?
-      barConstraint.top - 50 + this.textComponentContainerScrollTop :
-      top + this.textComponentContainerScrollTop;
+  }
+
+  private getBarConstraint(): { top: number, left: number } {
+    const viewConstraint = this.getViewConstraint();
+    return { top: viewConstraint.top - 100, left: viewConstraint.left - this.getBarWidth() };
+  }
+
+  private convertMarkingBarPositionToTextComponentRect(): { top: number, left: number } {
+    return {
+      left: this.markingBarPosition.left - this.textComponentRect.left,
+      top: this.markingBarPosition.top - this.textComponentRect.top + 15
+    };
   }
 }
-- 
GitLab