From 5b2f9e2aec0ac470c704d8539d258133e07e1a49 Mon Sep 17 00:00:00 2001 From: Tomas Rimkus Date: Fri, 27 Sep 2024 18:59:59 +0200 Subject: [PATCH] fix: image source after drag and drop (#1470) --- .../editor-resizable/editor-resizable.abstract.ts | 14 +++++++++++++- .../iframe-editor/iframe-editor.component.ts | 9 ++++++++- .../image-editor/image-editor.component.html | 2 +- .../image-editor/image-editor.component.ts | 15 +++++++++------ .../editor/extensions/tiptap-node-view/index.ts | 5 +++-- 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/projects/editor/components/editor-resizable/editor-resizable.abstract.ts b/projects/editor/components/editor-resizable/editor-resizable.abstract.ts index 4c093ed9c..038ad0d41 100644 --- a/projects/editor/components/editor-resizable/editor-resizable.abstract.ts +++ b/projects/editor/components/editor-resizable/editor-resizable.abstract.ts @@ -1,5 +1,6 @@ -import {Directive} from '@angular/core'; +import {type ChangeDetectorRef, Directive} from '@angular/core'; import {TuiNodeViewNg} from '@taiga-ui/editor/extensions/tiptap-node-view'; +import type {NodeViewProps} from '@tiptap/core'; export interface TuiEditorResizableContainer { height?: number | string | null; @@ -10,6 +11,8 @@ export interface TuiEditorResizableContainer { export abstract class AbstractTuiEditorResizable< T extends TuiEditorResizableContainer, > extends TuiNodeViewNg { + protected abstract readonly changeDetector: ChangeDetectorRef; + private localNode!: NodeViewProps['node']; protected currentHeight = 0; protected currentWidth = 0; @@ -18,6 +21,15 @@ export abstract class AbstractTuiEditorResizable< height: number, ]): void; + public get node(): NodeViewProps['node'] { + return this.localNode; + } + + public set node(value: NodeViewProps['node']) { + this.localNode = value; + this.changeDetector.markForCheck(); + } + protected get attrs(): T { return (this.node?.attrs as T) || {src: ''}; } diff --git a/projects/editor/extensions/iframe-editor/iframe-editor.component.ts b/projects/editor/extensions/iframe-editor/iframe-editor.component.ts index 5d45c6f3f..c09536a6b 100644 --- a/projects/editor/extensions/iframe-editor/iframe-editor.component.ts +++ b/projects/editor/extensions/iframe-editor/iframe-editor.component.ts @@ -1,4 +1,10 @@ -import {ChangeDetectionStrategy, Component, ElementRef, inject} from '@angular/core'; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + ElementRef, + inject, +} from '@angular/core'; import type {SafeResourceUrl} from '@angular/platform-browser'; import {DomSanitizer} from '@angular/platform-browser'; import {tuiPure} from '@taiga-ui/cdk'; @@ -23,6 +29,7 @@ export class TuiIframeEditor extends AbstractTuiEditorResizable = inject(ElementRef); protected readonly options = inject(TUI_IFRAME_EDITOR_OPTIONS); + protected readonly changeDetector = inject(ChangeDetectorRef); public updateSize([width, height]: readonly [width: number, height: number]): void { this.currentWidth = Math.max( diff --git a/projects/editor/extensions/image-editor/image-editor.component.html b/projects/editor/extensions/image-editor/image-editor.component.html index be87d9de0..07dd580eb 100644 --- a/projects/editor/extensions/image-editor/image-editor.component.html +++ b/projects/editor/extensions/image-editor/image-editor.component.html @@ -29,7 +29,7 @@ [alt]="alt" [attr.width]="width" [class.ProseMirror-selectednode]="focused" - [src]="src" + [src]="getBypassedSrc(attrs.src)" [style.max-width.px]="maxWidth" [style.min-width.px]="minWidth" [title]="title" diff --git a/projects/editor/extensions/image-editor/image-editor.component.ts b/projects/editor/extensions/image-editor/image-editor.component.ts index 122b3c07e..f7669ce19 100644 --- a/projects/editor/extensions/image-editor/image-editor.component.ts +++ b/projects/editor/extensions/image-editor/image-editor.component.ts @@ -1,10 +1,12 @@ -import type {AfterViewInit, OnInit} from '@angular/core'; import { + type AfterViewInit, ChangeDetectionStrategy, + ChangeDetectorRef, Component, DestroyRef, ElementRef, inject, + type OnInit, ViewChild, } from '@angular/core'; import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; @@ -70,6 +72,7 @@ export class TuiImageEditor protected readonly options = inject(TUI_EDITOR_OPTIONS); protected readonly imageOptions = inject(TUI_IMAGE_EDITOR_OPTIONS); + protected readonly changeDetector = inject(ChangeDetectorRef); public override get height(): number | string | null { return null; @@ -100,11 +103,6 @@ export class TuiImageEditor this.notifyUpdate(); } - @tuiPure - protected get src(): SafeResourceUrl { - return this.sanitizer.bypassSecurityTrustResourceUrl(this.attrs.src); - } - protected get dragHandle(): '' | null { return this.attrs.draggable ?? null; } @@ -117,6 +115,11 @@ export class TuiImageEditor return this.attrs.title ?? ''; } + @tuiPure + protected getBypassedSrc(src: string): SafeResourceUrl { + return this.sanitizer.bypassSecurityTrustResourceUrl(src); + } + protected currentTargetIsFocused(node: Node): void { this.focused = this.el.nativeElement.contains(node); diff --git a/projects/editor/extensions/tiptap-node-view/index.ts b/projects/editor/extensions/tiptap-node-view/index.ts index 5448574eb..5cf7ec996 100644 --- a/projects/editor/extensions/tiptap-node-view/index.ts +++ b/projects/editor/extensions/tiptap-node-view/index.ts @@ -66,9 +66,8 @@ export class TuiComponentRenderer { * Tiptap's {@link https://tiptap.dev/guide/node-views NodeView} from angular component. * It contains compulsory properties which component will get externally while NodeView's rendering. */ -export class TuiNodeViewNg implements NodeViewProps { +export abstract class TuiNodeViewNg implements NodeViewProps { public declare editor: NodeViewProps['editor']; - public declare node: NodeViewProps['node']; public declare decorations: NodeViewProps['decorations']; public declare selected: NodeViewProps['selected']; public declare extension: NodeViewProps['extension']; @@ -79,6 +78,8 @@ export class TuiNodeViewNg implements NodeViewProps { public declare HTMLAttributes: Record; public declare innerDecorations: DecorationSource; public declare view: EditorView; + public abstract get node(): NodeViewProps['node']; + public abstract set node(value: NodeViewProps['node']); } export interface TuiNodeViewRendererOptions extends NodeViewRendererOptions {