diff --git a/projects/common/element-components/text-area.component.ts b/projects/common/element-components/text-area.component.ts index 7a8cf9347710ec3707c10fc17b0785df1648e6df..a1e6387459edc69e9776add9d2f64529ead5c2d8 100644 --- a/projects/common/element-components/text-area.component.ts +++ b/projects/common/element-components/text-area.component.ts @@ -23,8 +23,8 @@ import { TextAreaElement } from '../models/text-area-element'; [style.min-width.%]="100" [style.line-height.%]="elementModel.lineHeight" [style.resize]="elementModel.resizeEnabled ? 'both' : 'none'" - (focus)="onFocus.emit(input)" - (blur)="onBlur.emit(input)"> + (focus)="elementModel.inputAssistancePreset !== 'none' ? onFocus.emit(input) : null" + (blur)="elementModel.inputAssistancePreset !== 'none' ? onBlur.emit(input): null"> </textarea> <mat-error *ngIf="elementFormControl.errors"> {{elementFormControl.errors | errorTransform: elementModel}} diff --git a/projects/player/src/app/components/element-container/element-container.component.ts b/projects/player/src/app/components/element-container/element-container.component.ts index 4e0193397c61ececb9c351ae36bb92be82ac6b61..19759eb43bd0b87876c6925352c38af140944d70 100644 --- a/projects/player/src/app/components/element-container/element-container.component.ts +++ b/projects/player/src/app/components/element-container/element-container.component.ts @@ -1,5 +1,5 @@ import { - Component, OnInit, Input, ComponentFactoryResolver, ViewChild, ViewContainerRef, QueryList + Component, OnInit, Input, ComponentFactoryResolver, ViewChild, ViewContainerRef } from '@angular/core'; import { FormBuilder, FormControl, FormGroup, ValidatorFn @@ -8,8 +8,6 @@ import { takeUntil } from 'rxjs/operators'; import { Subject } from 'rxjs'; import * as ElementFactory from '../../../../../common/util/element.factory'; import { KeyboardService } from '../../services/keyboard.service'; -import { TextFieldComponent } from '../../../../../common/element-components/text-field.component'; -import { TextAreaComponent } from '../../../../../common/element-components/text-area.component'; import { FormService } from '../../services/form.service'; import { UnitStateService } from '../../services/unit-state.service'; import { MarkingService } from '../../services/marking.service'; @@ -18,9 +16,7 @@ import { UIElement, ValueChangeElement } from '../../../../../common/models/uI-element'; -import { TextFieldElement } from '../../../../../common/models/text-field-element'; import { FormElementComponent } from '../../../../../common/form-element-component.directive'; -import { ElementComponent } from '../../../../../common/element-component.directive'; import { CompoundElementComponent } from '../../../../../common/element-components/compound-elements/compound-element.directive'; import { TextElement } from '../../../../../common/models/text-element'; @@ -31,6 +27,7 @@ import { VeronaPostService } from '../../services/verona-post.service'; import { MediaPlayerElementComponent } from '../../../../../common/media-player-element-component.directive'; import { MediaPlayerService } from '../../services/media-player.service'; import { TextComponent } from '../../../../../common/element-components/text.component'; +import { TextFieldElement } from '../../../../../common/models/text-field-element'; @Component({ selector: 'app-element-container', @@ -67,6 +64,42 @@ export class ElementContainerComponent implements OnInit { const elementComponent = this.elementComponentContainer.createComponent(elementComponentFactory).instance; elementComponent.elementModel = this.restoreUnitStateValue(this.elementModel); + this.registerElement(elementComponent); + this.subscribeCompoundChildren(elementComponent); + this.subscribeStartSelection(elementComponent); + this.subscribeApplySelection(elementComponent); + this.subscribeMediaStatusChanged(elementComponent); + this.subscribeNavigationRequested(elementComponent); + this.subscribeElementValueChanged(elementComponent); + this.subscribeForKeyboardEvents(elementComponent); + + const elementForm = this.formBuilder.group({}); + if (elementComponent instanceof FormElementComponent) { + elementComponent.parentForm = elementForm; + this.subscribeSetValidators(elementComponent, elementForm); + this.registerFormGroup(elementForm); + this.formService.registerFormControl({ + id: this.elementModel.id, + formControl: new FormControl((this.elementModel as InputElement).value), + formGroup: elementForm + }); + } else if (elementComponent instanceof CompoundElementComponent) { + elementComponent.parentForm = elementForm; + elementComponent.getFormElementModelChildren() + .forEach((element: InputElement) => { + this.registerFormGroup(elementForm); + this.formService.registerFormControl({ + id: element.id, + formControl: new FormControl(element.value), + formGroup: elementForm + }); + }); + } else if (elementComponent instanceof MediaPlayerElementComponent) { + this.mediaPlayerService.registerMediaElement(elementComponent); + } + } + + private registerElement(elementComponent: any): void { if (elementComponent.domElement) { this.unitStateService.registerElement( this.initUnitStateValue(elementComponent.elementModel), @@ -74,23 +107,9 @@ export class ElementContainerComponent implements OnInit { this.pageIndex ); } + } - if (elementComponent.childrenAdded) { - elementComponent.childrenAdded - .pipe(takeUntil(this.ngUnsubscribe)) - .subscribe((children: QueryList<ElementComponent>) => { - children.forEach(child => { - if (child.domElement) { - this.unitStateService.registerElement( - this.initUnitStateValue(child.elementModel), - child.domElement, - this.pageIndex - ); - } - }); - }); - } - + private subscribeStartSelection(elementComponent: any): void { if (elementComponent.startSelection) { elementComponent.startSelection .pipe(takeUntil(this.ngUnsubscribe)) @@ -101,25 +120,47 @@ export class ElementContainerComponent implements OnInit { } }); } + } - if (elementComponent.mediaPlayStatusChanged) { - elementComponent.mediaPlayStatusChanged + private subscribeCompoundChildren(elementComponent: any): void { + if (elementComponent.startSelection) { + elementComponent.startSelection .pipe(takeUntil(this.ngUnsubscribe)) - .subscribe((playStatus: string | null) => { - this.mediaPlayerService.broadCastPlayChanges(playStatus); + .subscribe((mouseEvent: MouseEvent) => { + const selection = window.getSelection(); + if (mouseEvent.ctrlKey && selection?.rangeCount) { + selection.removeAllRanges(); + } }); } + } + private subscribeApplySelection(elementComponent: any): void { if (elementComponent.applySelection) { elementComponent.applySelection .pipe(takeUntil(this.ngUnsubscribe)) .subscribe((selection: - { mode: 'mark' | 'underline' | 'delete', color: string; element: HTMLElement; clear: boolean }) => { + { mode: 'mark' | 'underline' | 'delete', + color: string; + element: HTMLElement; + clear: boolean }) => { this.markingService .applySelection(selection.mode, selection.color, selection.element, elementComponent as TextComponent); }); } + } + + private subscribeMediaStatusChanged(elementComponent: any): void { + if (elementComponent.mediaPlayStatusChanged) { + elementComponent.mediaPlayStatusChanged + .pipe(takeUntil(this.ngUnsubscribe)) + .subscribe((playStatus: string | null) => { + this.mediaPlayerService.broadCastPlayChanges(playStatus); + }); + } + } + private subscribeNavigationRequested(elementComponent: any): void { if (elementComponent.navigationRequested) { elementComponent.navigationRequested .pipe(takeUntil(this.ngUnsubscribe)) @@ -127,7 +168,9 @@ export class ElementContainerComponent implements OnInit { this.veronaPostService.sendVopUnitNavigationRequestedNotification(target); }); } + } + private subscribeElementValueChanged(elementComponent: any): void { if (elementComponent.elementValueChanged) { elementComponent.elementValueChanged .pipe(takeUntil(this.ngUnsubscribe)) @@ -135,7 +178,9 @@ export class ElementContainerComponent implements OnInit { this.unitStateService.changeElementValue(playbackTimeChanged); }); } + } + private subscribeSetValidators(elementComponent: any, elementForm: FormGroup): void { if (elementComponent.setValidators) { elementComponent.setValidators .pipe(takeUntil(this.ngUnsubscribe)) @@ -147,39 +192,27 @@ export class ElementContainerComponent implements OnInit { }); }); } + } - const elementForm = this.formBuilder.group({}); - if (elementComponent instanceof FormElementComponent) { - elementComponent.parentForm = elementForm; - this.registerFormGroup(elementForm); - this.formService.registerFormControl({ - id: this.elementModel.id, - formControl: new FormControl((this.elementModel as InputElement).value), - formGroup: elementForm - }); + private subscribeForKeyboardEvents(elementComponent: any): void { + if (elementComponent.onFocus) { + elementComponent.onFocus + .pipe(takeUntil(this.ngUnsubscribe)) + .subscribe((focussedInputControl: HTMLElement): void => { + const inputElement = this.elementModel.type === 'text-area' ? + focussedInputControl as HTMLTextAreaElement : + focussedInputControl as HTMLInputElement; + this.keyboardLayout = (this.elementModel as TextFieldElement).inputAssistancePreset; + this.isKeyboardOpen = this.keyboardService.openKeyboard(inputElement); + }); + } - if (this.elementModel.inputAssistancePreset !== 'none' && - (this.elementModel.type === 'text-field' || this.elementModel.type === 'text-area')) { - this.keyboardLayout = (this.elementModel as TextFieldElement).inputAssistancePreset; - if (this.elementModel.type === 'text-field') { - this.initEventsForKeyboard(elementComponent as TextFieldComponent); - } else { - this.initEventsForKeyboard(elementComponent as TextAreaComponent); - } - } - } else if (elementComponent instanceof CompoundElementComponent) { - elementComponent.parentForm = elementForm; - elementComponent.getFormElementModelChildren() - .forEach((element: InputElement) => { - this.registerFormGroup(elementForm); - this.formService.registerFormControl({ - id: element.id, - formControl: new FormControl(element.value), - formGroup: elementForm - }); + if (elementComponent.onBlur) { + elementComponent.onBlur + .pipe(takeUntil(this.ngUnsubscribe)) + .subscribe((): void => { + this.isKeyboardOpen = this.keyboardService.closeKeyboard(); }); - } else if (elementComponent instanceof MediaPlayerElementComponent) { - this.mediaPlayerService.registerMediaElement(elementComponent); } } @@ -228,23 +261,6 @@ export class ElementContainerComponent implements OnInit { }); } - private initEventsForKeyboard(elementComponent: TextFieldComponent | TextAreaComponent): void { - elementComponent.onFocus - .pipe(takeUntil(this.ngUnsubscribe)) - .subscribe((focussedInputControl: HTMLElement): void => { - const inputElement = this.elementModel.type === 'text-area' ? - focussedInputControl as HTMLTextAreaElement : - focussedInputControl as HTMLInputElement; - this.isKeyboardOpen = this.keyboardService.openKeyboard(inputElement); - }); - - elementComponent.onBlur - .pipe(takeUntil(this.ngUnsubscribe)) - .subscribe((): void => { - this.isKeyboardOpen = this.keyboardService.closeKeyboard(); - }); - } - ngOnDestroy(): void { this.ngUnsubscribe.next(); this.ngUnsubscribe.complete();