From 5515a5b4d64ff986dc14db50874d0dc4031a2034 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Fri, 29 Nov 2024 12:27:59 +0200 Subject: [PATCH 1/2] RED-10563: fixed key actions not prevented when input is focused. --- .../annotations-list/annotations-list.component.ts | 3 ++- .../components/file-header/file-header.component.ts | 6 +++--- .../file-workload/file-workload.component.ts | 10 +++------- .../pdf-viewer/services/document-viewer.service.ts | 5 +++-- apps/red-ui/src/app/utils/functions.ts | 10 +++++++++- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts b/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts index 1b5deaff9..5bd7b034c 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts @@ -16,6 +16,7 @@ import { HighlightsSeparatorComponent } from '../highlights-separator/highlights import { AnnotationWrapperComponent } from '../annotation-wrapper/annotation-wrapper.component'; import { AnnotationReferencesListComponent } from '../annotation-references-list/annotation-references-list.component'; import { Clipboard } from '@angular/cdk/clipboard'; +import { isTargetInput } from '@utils/functions'; @Component({ selector: 'redaction-annotations-list', @@ -68,7 +69,7 @@ export class AnnotationsListComponent extends HasScrollbarDirective { console.log('Selected Annotation:', annotation); } - if (($event?.target as IqserEventTarget)?.localName === 'input') { + if (isTargetInput($event)) { return; } diff --git a/apps/red-ui/src/app/modules/file-preview/components/file-header/file-header.component.ts b/apps/red-ui/src/app/modules/file-preview/components/file-header/file-header.component.ts index d1b164b70..d401ac67f 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/file-header/file-header.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/file-header/file-header.component.ts @@ -50,6 +50,7 @@ import { ALL_HOTKEYS } from '../../utils/constants'; import { AnnotationDrawService } from '../../../pdf-viewer/services/annotation-draw.service'; import { FileManagementService } from '@services/files/file-management.service'; import { MatDialog } from '@angular/material/dialog'; +import { isTargetInput, isTargetTextArea } from '@utils/functions'; @Component({ selector: 'redaction-file-header', @@ -178,7 +179,6 @@ export class FileHeaderComponent implements OnInit, AfterViewInit, OnDetach, OnD this.fullScreen = false; } } - @Bind() handleKeyEvent($event: KeyboardEvent) { if (this._router.url.indexOf('/file/') < 0) { @@ -212,7 +212,7 @@ export class FileHeaderComponent implements OnInit, AfterViewInit, OnDetach, OnD if (!$event.ctrlKey && !$event.metaKey && ['f', 'F'].includes($event.key)) { // if you type in an input, don't toggle full-screen - if ($event.target instanceof HTMLInputElement || $event.target instanceof HTMLTextAreaElement) { + if (isTargetInput($event) || isTargetTextArea($event)) { return; } this.toggleFullScreen(); @@ -220,7 +220,7 @@ export class FileHeaderComponent implements OnInit, AfterViewInit, OnDetach, OnD } if (['h', 'H'].includes($event.key)) { - if ($event.target instanceof HTMLInputElement || $event.target instanceof HTMLTextAreaElement) { + if (isTargetInput($event) || isTargetTextArea($event)) { return; } this._ngZone.run(() => { diff --git a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts index e7e0199c0..850108023 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts @@ -59,7 +59,7 @@ import { PageExclusionComponent } from '../page-exclusion/page-exclusion.compone import { PagesComponent } from '../pages/pages.component'; import { ReadonlyBannerComponent } from '../readonly-banner/readonly-banner.component'; import { DocumentInfoComponent } from '../document-info/document-info.component'; -import { getLast } from '@utils/functions'; +import { getLast, isTargetInput } from '@utils/functions'; import { ALL_ANNOTATIONS_PAGE } from '../../utils/constants'; const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape']; @@ -251,11 +251,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On handleKeyEvent($event: KeyboardEvent): void { const multiSelectServiceInactive = untracked(this.multiSelectService.inactive); - if ( - !ALL_HOTKEY_ARRAY.includes($event.key) || - this._dialog.openDialogs.length || - ($event.target as IqserEventTarget).localName === 'input' - ) { + if (!ALL_HOTKEY_ARRAY.includes($event.key) || this._dialog.openDialogs.length || isTargetInput($event)) { return; } @@ -342,7 +338,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On } preventKeyDefault($event: KeyboardEvent): void { - if (COMMAND_KEY_ARRAY.includes($event.key) && !(($event.target as any).localName === 'input')) { + if (COMMAND_KEY_ARRAY.includes($event.key) && !isTargetInput($event)) { $event.preventDefault(); } } diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/document-viewer.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/document-viewer.service.ts index 88fbff253..a7b6be744 100644 --- a/apps/red-ui/src/app/modules/pdf-viewer/services/document-viewer.service.ts +++ b/apps/red-ui/src/app/modules/pdf-viewer/services/document-viewer.service.ts @@ -14,6 +14,7 @@ import { PdfViewer } from './pdf-viewer.service'; import Color = Core.Annotations.Color; import DocumentViewer = Core.DocumentViewer; import Quad = Core.Math.Quad; +import { isTargetInput } from '@utils/functions'; @Injectable() export class REDDocumentViewer { @@ -71,12 +72,12 @@ export class REDDocumentViewer { return fromEvent(this.#document, 'keyUp').pipe( tap(stopAndPreventIfNotAllowed), filter($event => { - if (($event.target as HTMLElement)?.tagName?.toLowerCase() === 'input') { + if (isTargetInput($event)) { if ($event.key === 'Escape') { return true; } } - return ($event.target as HTMLElement)?.tagName?.toLowerCase() !== 'input'; + return isTargetInput($event); }), filter($event => $event.key.startsWith('Arrow') || ['f', 'h', 'H', 'Escape', 'Shift'].includes($event.key)), tap(stopAndPrevent), diff --git a/apps/red-ui/src/app/utils/functions.ts b/apps/red-ui/src/app/utils/functions.ts index ea763c79a..405a3e629 100644 --- a/apps/red-ui/src/app/utils/functions.ts +++ b/apps/red-ui/src/app/utils/functions.ts @@ -1,5 +1,5 @@ import { ITrackable } from '@iqser/common-ui'; -import type { List } from '@iqser/common-ui/lib/utils'; +import type { IqserEventTarget, List } from '@iqser/common-ui/lib/utils'; import type { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { Dayjs } from 'dayjs'; import { AbstractControl } from '@angular/forms'; @@ -149,3 +149,11 @@ export function urlFileId() { export function formControlToSignal(control: AbstractControl) { return toSignal(control.valueChanges, { initialValue: control.value }); } + +export function isTargetInput(event: Event) { + return (event?.target as IqserEventTarget)?.localName === 'input'; +} + +export function isTargetTextArea(event: Event) { + return (event?.target as IqserEventTarget)?.localName === 'textarea'; +} From 8c47a8b75855b9091425237e9b07fbc65141b753 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Fri, 29 Nov 2024 12:38:17 +0200 Subject: [PATCH 2/2] RED-10563: grouped key events and extracted the target check. --- .../file-header/file-header.component.ts | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/file-header/file-header.component.ts b/apps/red-ui/src/app/modules/file-preview/components/file-header/file-header.component.ts index d401ac67f..bf616ec5f 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/file-header/file-header.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/file-header/file-header.component.ts @@ -210,29 +210,26 @@ export class FileHeaderComponent implements OnInit, AfterViewInit, OnDetach, OnD this._changeRef.markForCheck(); } + if ($event.key === 'F5') { + window.location.reload(); + } + + if (isTargetInput($event) || isTargetTextArea($event)) { + return; + } + if (!$event.ctrlKey && !$event.metaKey && ['f', 'F'].includes($event.key)) { - // if you type in an input, don't toggle full-screen - if (isTargetInput($event) || isTargetTextArea($event)) { - return; - } this.toggleFullScreen(); return; } if (['h', 'H'].includes($event.key)) { - if (isTargetInput($event) || isTargetTextArea($event)) { - return; - } this._ngZone.run(() => { window.focus(); this._helpModeService.activateHelpMode(false); }); return; } - - if ($event.key === 'F5') { - window.location.reload(); - } } #openFullScreen() {