From a3e857a7f0f8b170cd7a89f251e62010de6f0b17 Mon Sep 17 00:00:00 2001
From: jojohoch <joachim.hoch@iqb.hu-berlin.de>
Date: Thu, 19 Dec 2024 18:04:07 +0100
Subject: [PATCH] [player] Consolidate respnses for text elements in 'word'
 nmarking mode

---
 docs/release-notes-player.md                  |  4 ++++
 .../src/app/classes/markable-support.ts       | 15 +++++++++++-
 ...ment-model-element-code-mapping.service.ts | 24 ++++++++++++-------
 3 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/docs/release-notes-player.md b/docs/release-notes-player.md
index ee7edd466..6d5a81482 100644
--- a/docs/release-notes-player.md
+++ b/docs/release-notes-player.md
@@ -1,5 +1,9 @@
 Player
 ======
+## 2.6.4
+### Fehlerbehebungen
+- Fasst aufeinanderfolgende markierte Wörter in den Antwortdaten von Texten zu Bereichen zusammen  
+
 ## 2.6.0
 ### Neue Funktionen
 - Unterstützt Verona API 6.0
diff --git a/projects/player/src/app/classes/markable-support.ts b/projects/player/src/app/classes/markable-support.ts
index b03c4b36a..f3f61d183 100644
--- a/projects/player/src/app/classes/markable-support.ts
+++ b/projects/player/src/app/classes/markable-support.ts
@@ -25,12 +25,25 @@ export class MarkableSupport {
 
   createMarkables(savedMarks: string[], elementComponent: TextComponent): void {
     const nodes = MarkableSupport.getNodes(elementComponent.textContainerRef.nativeElement.childNodes);
-    const markablesContainers = MarkableSupport.getMarkablesContainers(nodes, savedMarks);
+    const markablesContainers = MarkableSupport
+      .getMarkablesContainers(nodes, MarkableSupport.expandSavedMarks(savedMarks));
     const markables = markablesContainers
       .flatMap((markablesContainer: MarkablesContainer) => markablesContainer.markables);
     this.createComponents(markablesContainers, elementComponent, markables);
   }
 
+  private static expandSavedMarks(savedMarks: string[]): string[] {
+    return savedMarks.flatMap(range => {
+      const [start, end, color] = range.split('-');
+      const startIndex = parseInt(start, 10);
+      const endIndex = parseInt(end, 10);
+      return Array.from({ length: endIndex - startIndex + 1 }, (_, i) => {
+        const currentIdx = startIndex + i;
+        return `${currentIdx}-${currentIdx}-${color}`;
+      });
+    });
+  }
+
   private createComponents(markablesContainers: MarkablesContainer[],
                            elementComponent: TextComponent,
                            markables: Markable[]): void {
diff --git a/projects/player/src/app/services/element-model-element-code-mapping.service.ts b/projects/player/src/app/services/element-model-element-code-mapping.service.ts
index 616c0cb4b..e53144c95 100644
--- a/projects/player/src/app/services/element-model-element-code-mapping.service.ts
+++ b/projects/player/src/app/services/element-model-element-code-mapping.service.ts
@@ -101,7 +101,7 @@ export class ElementModelElementCodeMappingService {
         }
         if (options && (options.markingMode === 'word' || options.markingMode === 'range')) {
           return ElementModelElementCodeMappingService
-            .getMarkedMarkables(elementModelValue as Markable[]);
+            .getMarkedMarkablesInSelectionFormat(elementModelValue as Markable[]);
         }
         return [];
       case 'radio':
@@ -119,14 +119,22 @@ export class ElementModelElementCodeMappingService {
     return this.dragNDropValueObjects.find(dropListValue => dropListValue.alias === alias);
   }
 
-  static getMarkedMarkables(markables: Markable[]): string[] {
+  static getMarkedMarkablesInSelectionFormat(markables: Markable[]): string[] {
     return markables
       .filter((markable: Markable) => !!markable.color)
-      .map((markable: Markable) => ElementModelElementCodeMappingService
-        .mapToTextSelectionFormat(markable, markable.color));
-  }
-
-  private static mapToTextSelectionFormat(markable: Markable, color: string | null): string {
-    return `${markable.id}-${markable.id}-${color}`;
+      .reduce((acc: [number, number, (string | null)][], markable: Markable) => {
+        const [start, end, color] = [markable.id, markable.id, markable.color];
+        const lastEntry = acc[acc.length - 1];
+        if (lastEntry) {
+          const [lastStart, lastEnd, lastColor] = lastEntry;
+          if (lastColor === color && +lastEnd + 1 === +start) {
+            acc[acc.length - 1] = [lastStart, end, color];
+            return acc;
+          }
+        }
+        acc.push([start, end, color]);
+        return acc;
+      }, [])
+      .map(e => `${e[0]}-${e[1]}-${e[2]}`);
   }
 }
-- 
GitLab