From dc8c2eac91ad716117ed3f867bb87f806bf0999b Mon Sep 17 00:00:00 2001 From: sdarbinyan Date: Mon, 13 Jul 2026 09:31:04 +0400 Subject: [PATCH] fix(project-editor): keep html-editor surface always in DOM The @if/@else toggle between the contentEditable surface and the code textarea broke the static ViewChild('surface') query: Angular never resolves a static query for an element inside a conditional block, so surface stayed undefined and every keystroke threw in emitChange(). Render both elements always and toggle visibility with [hidden] instead, and add an ngAfterViewInit sync as a safety net for the initial html input on the first change-detection pass. --- .../marketplace-html-editor.component.html | 30 +++++++++---------- .../marketplace-html-editor.component.ts | 18 +++++++++-- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/app/features/project-editor/components/html-editor/marketplace-html-editor.component.html b/src/app/features/project-editor/components/html-editor/marketplace-html-editor.component.html index 57e8f4d..39e744a 100644 --- a/src/app/features/project-editor/components/html-editor/marketplace-html-editor.component.html +++ b/src/app/features/project-editor/components/html-editor/marketplace-html-editor.component.html @@ -6,19 +6,19 @@ - @if (showCode()) { - - } @else { -
- } + + +
diff --git a/src/app/features/project-editor/components/html-editor/marketplace-html-editor.component.ts b/src/app/features/project-editor/components/html-editor/marketplace-html-editor.component.ts index c0df2f2..85b1bcf 100644 --- a/src/app/features/project-editor/components/html-editor/marketplace-html-editor.component.ts +++ b/src/app/features/project-editor/components/html-editor/marketplace-html-editor.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, OnChanges, Output, SimpleChanges, ViewChild, signal } from '@angular/core'; +import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, OnChanges, Output, SimpleChanges, ViewChild, signal } from '@angular/core'; export interface HtmlEditorToolbarCommand { id: string; @@ -28,7 +28,7 @@ export const HTML_EDITOR_TOOLBAR: HtmlEditorToolbarCommand[] = [ styleUrls: ['./marketplace-html-editor.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -export class MarketplaceHtmlEditorComponent implements OnChanges { +export class MarketplaceHtmlEditorComponent implements OnChanges, AfterViewInit { @Input() html = ''; @Output() htmlChange = new EventEmitter(); @ViewChild('surface', { static: true }) surface!: ElementRef; @@ -38,7 +38,19 @@ export class MarketplaceHtmlEditorComponent implements OnChanges { readonly codeValue = signal(''); ngOnChanges(changes: SimpleChanges): void { - if (changes['html'] && this.surface && this.surface.nativeElement.innerHTML !== (this.html || '')) { + if (changes['html']) { + this.syncSurfaceFromInput(); + } + } + + ngAfterViewInit(): void { + // Safety net: on the very first change detection pass, ngOnChanges can run + // before the static ViewChild is resolved, so re-sync once the view is ready. + this.syncSurfaceFromInput(); + } + + private syncSurfaceFromInput(): void { + if (this.surface && this.surface.nativeElement.innerHTML !== (this.html || '')) { this.surface.nativeElement.innerHTML = this.html || ''; } }