From b2608ca1e87e98ae4c92b6fd89aa4c14d8165746 Mon Sep 17 00:00:00 2001
From: jojohoch <joachim.hoch@iqb.hu-berlin.de>
Date: Mon, 22 Nov 2021 14:39:06 +0100
Subject: [PATCH] Set buttons of element components to type button

Setting on type button avoids that click events are evaluated from
the surrounding form
---
 .../control-bar/control-bar.component.html    | 13 +++---
 .../control-bar/control-bar.component.ts      | 16 ++------
 .../text-field.component.ts                   | 22 +++++-----
 .../element-components/text.component.ts      | 41 +++++++++----------
 .../french-keyboard.component.html            |  5 ++-
 .../french-keyboard.component.ts              |  4 +-
 .../src/app/components/key/key.component.html |  8 ++--
 .../src/app/components/key/key.component.ts   |  6 ---
 8 files changed, 52 insertions(+), 63 deletions(-)

diff --git a/projects/common/element-components/control-bar/control-bar.component.html b/projects/common/element-components/control-bar/control-bar.component.html
index 871462c72..ef2bbc943 100644
--- a/projects/common/element-components/control-bar/control-bar.component.html
+++ b/projects/common/element-components/control-bar/control-bar.component.html
@@ -2,23 +2,25 @@
      [class.hint-border]="showHint">
   <ng-container *ngIf="elementModel.startControl">
     <button *ngIf="!playing || !elementModel.pauseControl"
+            type="button"
             mat-button
             class="control-button"
             [class.enabled-control]="!disabled && active && dependencyDissolved"
             [class.active-control]="playing"
             [disabled]="disabled || !active || !dependencyDissolved"
-            (click)="play($event)">
+            (click)="play()">
       <mat-icon>play_arrow</mat-icon>
     </button>
   </ng-container>
   <ng-container *ngIf="elementModel.pauseControl">
     <button *ngIf="playing"
+            type="button"
             mat-button
             class="control-button"
             [class.enabled-control]="!disabled && active && dependencyDissolved"
             [class.active-control]="pausing"
             [disabled]="disabled || !active || !dependencyDissolved"
-            (click)="pause($event)">
+            (click)="pause()">
       <mat-icon>pause</mat-icon>
     </button>
   </ng-container>
@@ -40,19 +42,20 @@
   <ng-container *ngIf="elementModel.showRestTime">
     <div *ngIf="!restTimeMode"
          class="time mat-typography"
-         (click)="toggleTime($event)">
+         (click)="toggleTime()">
       {{currentTime | playerTimeFormat}} / {{duration | playerTimeFormat }}
     </div>
     <div *ngIf="restTimeMode"
          class="time mat-typography"
-         (click)="toggleTime($event)">
+         (click)="toggleTime()">
       -{{currentRestTime | playerTimeFormat}}
     </div>
   </ng-container>
   <ng-container *ngIf="elementModel.volumeControl">
     <button mat-button
+            type="button"
             class="control-button enabled-control"
-            (click)="toggleVolume($event)">
+            (click)="toggleVolume()">
       <mat-icon *ngIf="!player.muted">volume_up</mat-icon>
       <mat-icon *ngIf="player.muted">volume_off</mat-icon>
     </button>
diff --git a/projects/common/element-components/control-bar/control-bar.component.ts b/projects/common/element-components/control-bar/control-bar.component.ts
index 50c752a47..8971a1ffa 100644
--- a/projects/common/element-components/control-bar/control-bar.component.ts
+++ b/projects/common/element-components/control-bar/control-bar.component.ts
@@ -80,16 +80,12 @@ export class ControlBarComponent implements OnInit, OnChanges, OnDestroy {
     }
   }
 
-  play(event: MouseEvent): void {
+  play(): void {
     this._play();
-    event.stopPropagation();
-    event.preventDefault();
   }
 
-  pause(event: MouseEvent): void {
+  pause(): void {
     this.player.pause();
-    event.stopPropagation();
-    event.preventDefault();
   }
 
   onTimeChange(event: MatSliderChange): void {
@@ -100,21 +96,17 @@ export class ControlBarComponent implements OnInit, OnChanges, OnDestroy {
     this.player.volume = event.value ? event.value : 0;
   }
 
-  toggleTime(event: MouseEvent): void {
+  toggleTime(): void {
     this.restTimeMode = !this.restTimeMode;
-    event.stopPropagation();
-    event.preventDefault();
   }
 
-  toggleVolume(event: MouseEvent): void {
+  toggleVolume(): void {
     if (this.player.volume) {
       this.lastVolume = this.player.volume;
       this.player.volume = 0;
     } else {
       this.player.volume = this.lastVolume;
     }
-    event.stopPropagation();
-    event.preventDefault();
   }
 
   private checkValidState(runCounter: number): boolean {
diff --git a/projects/common/element-components/text-field.component.ts b/projects/common/element-components/text-field.component.ts
index a446aaf36..23099218a 100644
--- a/projects/common/element-components/text-field.component.ts
+++ b/projects/common/element-components/text-field.component.ts
@@ -1,4 +1,6 @@
-import { Component, EventEmitter, Input, Output } from '@angular/core';
+import {
+  Component, EventEmitter, Input, Output
+} from '@angular/core';
 import { ValidatorFn, Validators } from '@angular/forms';
 import { FormElementComponent } from '../form-element-component.directive';
 import { TextFieldElement } from '../models/text-field-element';
@@ -25,8 +27,10 @@ import { TextFieldElement } from '../models/text-field-element';
              [readonly]="elementModel.readOnly"
              (focus)="elementModel.inputAssistancePreset !== 'none' ? onFocusChanged.emit(input) : null"
              (blur)="elementModel.inputAssistancePreset !== 'none' ? onFocusChanged.emit(null): null">
-      <button *ngIf="elementModel.clearable" matSuffix mat-icon-button aria-label="Clear"
-              (click)="onClearButtonClick($event)">
+      <button *ngIf="elementModel.clearable"
+              type="button"
+              matSuffix mat-icon-button aria-label="Clear"
+              (click)="this.elementFormControl.setValue('')">
         <mat-icon>close</mat-icon>
       </button>
       <mat-error *ngIf="elementFormControl.errors">
@@ -51,8 +55,10 @@ import { TextFieldElement } from '../models/text-field-element';
              [pattern]="elementModel.pattern"
              (focus)="elementModel.inputAssistancePreset !== 'none' ? onFocusChanged.emit(input) : null"
              (blur)="elementModel.inputAssistancePreset !== 'none' ? onFocusChanged.emit(null): null">
-      <button *ngIf="elementModel.clearable" matSuffix mat-icon-button aria-label="Clear"
-              (click)="onClearButtonClick($event)">
+      <button *ngIf="elementModel.clearable"
+              type="button"
+              matSuffix mat-icon-button aria-label="Clear"
+              (click)="this.elementFormControl.setValue('')">
         <mat-icon>close</mat-icon>
       </button>
       <mat-error *ngIf="elementFormControl.errors">
@@ -68,12 +74,6 @@ export class TextFieldComponent extends FormElementComponent {
   @Input() elementModel!: TextFieldElement;
   @Output() onFocusChanged = new EventEmitter<HTMLElement | null>();
 
-  onClearButtonClick(event: MouseEvent) : void {
-    this.elementFormControl.setValue('');
-    event.preventDefault();
-    event.stopPropagation();
-  }
-
   get validators(): ValidatorFn[] {
     const validators: ValidatorFn[] = [];
     if (this.elementModel.required) {
diff --git a/projects/common/element-components/text.component.ts b/projects/common/element-components/text.component.ts
index 2a42b30b1..fae93df0e 100644
--- a/projects/common/element-components/text.component.ts
+++ b/projects/common/element-components/text.component.ts
@@ -13,27 +13,36 @@ import { ValueChangeElement } from '../models/uI-element';
       <div *ngIf="elementModel.interaction !== 'none'"
            class="marking-bar">
         <ng-container *ngIf="elementModel.interaction === 'highlightable'">
-          <button class="marking-button" mat-mini-fab [style.background-color]="'yellow'"
-                  (click)="onMarkingButtonClick($event, { mode: 'mark', color:'yellow', element: container })">
+          <button type="button"
+                  class="marking-button"
+                  mat-mini-fab [style.background-color]="'yellow'"
+                  (click)="applySelection.emit({ mode: 'mark', color:'yellow', element: container })">
             <mat-icon>border_color</mat-icon>
           </button>
-          <button class="marking-button" mat-mini-fab [style.background-color]="'turquoise'"
-                  (click)="onMarkingButtonClick($event, { mode: 'mark', color: 'turquoise', element: container })">
+          <button type="button"
+                  class="marking-button"
+                  mat-mini-fab [style.background-color]="'turquoise'"
+                  (click)="applySelection.emit({ mode: 'mark', color: 'turquoise', element: container })">
             <mat-icon>border_color</mat-icon>
           </button>
-          <button class="marking-button" mat-mini-fab [style.background-color]="'orange'"
-                  (click)="onMarkingButtonClick($event, { mode: 'mark', color: 'orange', element: container })">
+          <button type="button"
+                  class="marking-button"
+                  mat-mini-fab [style.background-color]="'orange'"
+                  (click)="applySelection.emit({ mode: 'mark', color: 'orange', element: container })">
             <mat-icon>border_color</mat-icon>
           </button>
         </ng-container>
         <ng-container *ngIf="elementModel.interaction === 'underlinable'">
-          <button class="marking-button" mat-mini-fab [style.background-color]="'white'"
-                  (click)="onMarkingButtonClick($event, { mode: 'underline', color: 'black', element: container })">
+          <button type="button"
+                  class="marking-button"
+                  mat-mini-fab [style.background-color]="'white'"
+                  (click)="applySelection.emit({ mode: 'underline', color: 'black', element: container })">
             <mat-icon>format_underlined</mat-icon>
           </button>
         </ng-container>
-        <button class="marking-button" [style.background-color]="'lightgrey'" mat-mini-fab
-                (click)="onMarkingButtonClick($event, { mode: 'delete', color: 'none', element: container })">
+        <button type="button"
+                class="marking-button" [style.background-color]="'lightgrey'" mat-mini-fab
+                (click)="applySelection.emit({ mode: 'delete', color: 'none', element: container })">
           <mat-icon>clear</mat-icon>
         </button>
       </div>
@@ -72,16 +81,4 @@ export class TextComponent extends ElementComponent {
   }>();
 
   @ViewChild('container') containerDiv!: ElementRef;
-
-  onMarkingButtonClick(
-    event: MouseEvent, markingValues: {
-      mode: 'mark' | 'underline' | 'delete',
-      color: string;
-      element: HTMLElement;
-    }
-  ) : void {
-    this.applySelection.emit(markingValues);
-    event.preventDefault();
-    event.stopPropagation();
-  }
 }
diff --git a/projects/player/src/app/components/french-keyboard/french-keyboard.component.html b/projects/player/src/app/components/french-keyboard/french-keyboard.component.html
index ac12dbbcf..9560fdf3f 100644
--- a/projects/player/src/app/components/french-keyboard/french-keyboard.component.html
+++ b/projects/player/src/app/components/french-keyboard/french-keyboard.component.html
@@ -3,7 +3,10 @@
     <app-key [key]="key"></app-key>
   </ng-container>
 </div>
-<button class="keyboard_capslock" mat-mini-fab (click)="toggleCharacterCase($event)">
+<button
+    type="button"
+    class="keyboard_capslock"
+    mat-mini-fab (click)="toggleCharacterCase()">
   <mat-icon *ngIf="lowerCharacters">keyboard_arrow_up</mat-icon>
   <mat-icon *ngIf="!lowerCharacters">keyboard_capslock</mat-icon>
 </button>
diff --git a/projects/player/src/app/components/french-keyboard/french-keyboard.component.ts b/projects/player/src/app/components/french-keyboard/french-keyboard.component.ts
index 501800a51..ff549625e 100644
--- a/projects/player/src/app/components/french-keyboard/french-keyboard.component.ts
+++ b/projects/player/src/app/components/french-keyboard/french-keyboard.component.ts
@@ -23,14 +23,12 @@ export class FrenchKeyboardComponent implements OnInit {
     this.lowerCharacters = true;
   }
 
-  toggleCharacterCase(event: MouseEvent): void {
+  toggleCharacterCase(): void {
     this.lowerCharacters = !this.lowerCharacters;
     if (this.lowerCharacters) {
       this.rows = this.lowerCharacterRows;
     } else {
       this.rows = this.upperCharacterRows;
     }
-    event.preventDefault();
-    event.stopPropagation();
   }
 }
diff --git a/projects/player/src/app/components/key/key.component.html b/projects/player/src/app/components/key/key.component.html
index 1c6f78792..ccac06710 100644
--- a/projects/player/src/app/components/key/key.component.html
+++ b/projects/player/src/app/components/key/key.component.html
@@ -1,4 +1,6 @@
-<button mat-mini-fab
-        class="key"
-        (click)="onClick($event)">{{key}}
+<button
+    type="button"
+    mat-mini-fab
+    class="key"
+    (click)="keyboardService.enterKey(key);">{{key}}
 </button>
diff --git a/projects/player/src/app/components/key/key.component.ts b/projects/player/src/app/components/key/key.component.ts
index f01d44dd0..c8eb95a4a 100644
--- a/projects/player/src/app/components/key/key.component.ts
+++ b/projects/player/src/app/components/key/key.component.ts
@@ -10,10 +10,4 @@ export class KeyComponent {
   @Input() key!: string;
 
   constructor(public keyboardService: KeyboardService) { }
-
-  onClick(event: MouseEvent): void {
-    this.keyboardService.enterKey(this.key);
-    event.preventDefault();
-    event.stopPropagation();
-  }
 }
-- 
GitLab