Merge pull request #9567 from vvlladd28/bug/markdown/detect-changes

Fixed updated value in markdown input component and refactoring this component
This commit is contained in:
Igor Kulikov 2023-11-07 16:36:07 +02:00 committed by GitHub
commit cbca05b2cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -14,11 +14,23 @@
/// limitations under the License. /// limitations under the License.
/// ///
import { Component, ElementRef, forwardRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; import {
ChangeDetectorRef,
Component,
ElementRef,
forwardRef,
Input,
OnDestroy,
OnInit,
ViewChild,
ViewEncapsulation
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Ace } from 'ace-builds'; import { Ace } from 'ace-builds';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { getAce } from '@shared/models/ace/ace.models'; import { getAce } from '@shared/models/ace/ace.models';
import { ResizeObserver } from '@juggle/resize-observer';
import { coerceBoolean } from '@shared/decorators/coercion';
import { CancelAnimationFrame, RafService } from '@core/services/raf.service';
@Component({ @Component({
selector: 'tb-markdown-editor', selector: 'tb-markdown-editor',
@ -30,7 +42,8 @@ import { getAce } from '@shared/models/ace/ace.models';
useExisting: forwardRef(() => MarkdownEditorComponent), useExisting: forwardRef(() => MarkdownEditorComponent),
multi: true multi: true
} }
] ],
encapsulation: ViewEncapsulation.None
}) })
export class MarkdownEditorComponent implements OnInit, ControlValueAccessor, OnDestroy { export class MarkdownEditorComponent implements OnInit, ControlValueAccessor, OnDestroy {
@ -42,11 +55,13 @@ export class MarkdownEditorComponent implements OnInit, ControlValueAccessor, On
@Input() helpId: string; @Input() helpId: string;
@Input()
@coerceBoolean()
required: boolean;
@ViewChild('markdownEditor', {static: true}) @ViewChild('markdownEditor', {static: true})
markdownEditorElmRef: ElementRef; markdownEditorElmRef: ElementRef;
private markdownEditor: Ace.Editor;
editorMode = true; editorMode = true;
fullscreen = false; fullscreen = false;
@ -54,22 +69,15 @@ export class MarkdownEditorComponent implements OnInit, ControlValueAccessor, On
markdownValue: string; markdownValue: string;
renderValue: string; renderValue: string;
ignoreChange = false; private markdownEditor: Ace.Editor;
private ignoreChange = false;
private propagateChange = null; private editorResize$: ResizeObserver;
private editorsResizeCaf: CancelAnimationFrame;
private propagateChange: (value: any) => void = () => {};
private requiredValue: boolean; constructor(private cd: ChangeDetectorRef,
private raf: RafService) {
get required(): boolean {
return this.requiredValue;
}
@Input()
set required(value: boolean) {
this.requiredValue = coerceBooleanProperty(value);
}
constructor() {
} }
ngOnInit(): void { ngOnInit(): void {
@ -100,6 +108,10 @@ export class MarkdownEditorComponent implements OnInit, ControlValueAccessor, On
this.updateView(); this.updateView();
} }
}); });
this.editorResize$ = new ResizeObserver(() => {
this.onAceEditorResize();
});
this.editorResize$.observe(editorElement);
} }
); );
@ -107,6 +119,13 @@ export class MarkdownEditorComponent implements OnInit, ControlValueAccessor, On
} }
ngOnDestroy(): void { ngOnDestroy(): void {
if (this.editorResize$) {
this.editorResize$.disconnect();
}
if (this.editorsResizeCaf) {
this.editorsResizeCaf();
this.editorsResizeCaf = null;
}
if (this.markdownEditor) { if (this.markdownEditor) {
this.markdownEditor.destroy(); this.markdownEditor.destroy();
} }
@ -134,15 +153,6 @@ export class MarkdownEditorComponent implements OnInit, ControlValueAccessor, On
} }
} }
updateView() {
const editorValue = this.markdownEditor.getValue();
if (this.markdownValue !== editorValue) {
this.markdownValue = editorValue;
this.renderValue = this.markdownValue ? this.markdownValue : ' ';
this.propagateChange(this.markdownValue);
}
}
onFullscreen() { onFullscreen() {
if (this.markdownEditor) { if (this.markdownEditor) {
setTimeout(() => { setTimeout(() => {
@ -159,4 +169,25 @@ export class MarkdownEditorComponent implements OnInit, ControlValueAccessor, On
}, 0); }, 0);
} }
} }
private updateView() {
const editorValue = this.markdownEditor.getValue();
if (this.markdownValue !== editorValue) {
this.markdownValue = editorValue;
this.renderValue = this.markdownValue ? this.markdownValue : ' ';
this.propagateChange(this.markdownValue);
this.cd.markForCheck();
}
}
private onAceEditorResize() {
if (this.editorsResizeCaf) {
this.editorsResizeCaf();
this.editorsResizeCaf = null;
}
this.editorsResizeCaf = this.raf.raf(() => {
this.markdownEditor.resize();
this.markdownEditor.renderer.updateFull();
});
}
} }