diff --git a/projects/tui-editor/abstract/editor-adapter.abstract.ts b/projects/tui-editor/abstract/editor-adapter.abstract.ts index f8b810349..2c8159e20 100644 --- a/projects/tui-editor/abstract/editor-adapter.abstract.ts +++ b/projects/tui-editor/abstract/editor-adapter.abstract.ts @@ -98,4 +98,5 @@ export abstract class AbstractTuiEditor { abstract setFileLink(preview: TuiEditorAttachedFile): void; abstract setYoutubeVideo(options: TuiYoutubeOptions): void; abstract setIframe(options: TuiEditableIframe): void; + abstract getHTML(): string; } diff --git a/projects/tui-editor/components/editor/editor.component.ts b/projects/tui-editor/components/editor/editor.component.ts index ad8fddf85..3964a9cf1 100644 --- a/projects/tui-editor/components/editor/editor.component.ts +++ b/projects/tui-editor/components/editor/editor.component.ts @@ -7,6 +7,7 @@ import { EventEmitter, Inject, Input, + NgZone, OnDestroy, Optional, Output, @@ -24,11 +25,12 @@ import { TuiBooleanHandler, TuiFocusableElementAccessor, TuiStringHandler, + tuiZonefree, } from '@taiga-ui/cdk'; import {TUI_ANIMATIONS_DEFAULT_DURATION} from '@taiga-ui/core'; import {AbstractTuiEditor} from '@tinkoff/tui-editor/abstract'; import {TuiToolbarComponent} from '@tinkoff/tui-editor/components/toolbar'; -import {defaultEditorTools} from '@tinkoff/tui-editor/constants'; +import {defaultEditorTools, TUI_EDITOR_RESIZE_EVENT} from '@tinkoff/tui-editor/constants'; import { TuiTiptapEditorDirective, TuiTiptapEditorService, @@ -48,8 +50,8 @@ import { TuiSelectionState, } from '@tinkoff/tui-editor/utils'; import {Editor} from '@tiptap/core'; -import {Observable} from 'rxjs'; -import {delay, takeUntil} from 'rxjs/operators'; +import {fromEvent, Observable} from 'rxjs'; +import {delay, takeUntil, throttleTime} from 'rxjs/operators'; import {TUI_EDITOR_PROVIDERS} from './editor.providers'; @@ -105,6 +107,7 @@ export class TuiEditorComponent @Inject(TUI_EDITOR_VALUE_TRANSFORMER) transformer: AbstractTuiValueTransformer | null, @Inject(TUI_EDITOR_OPTIONS) readonly options: TuiEditorOptions, + @Inject(NgZone) private readonly zone: NgZone, ) { super(control, cdr, transformer); @@ -116,6 +119,7 @@ export class TuiEditorComponent ); this.patchContentEditableElement(); + this.listenResizeEvents(); }); } @@ -284,4 +288,13 @@ export class TuiEditorComponent String(this.options.spellcheck), ); } + + private listenResizeEvents(): void { + this.el?.nativeElement && + fromEvent(this.el?.nativeElement, TUI_EDITOR_RESIZE_EVENT) + .pipe(throttleTime(0), tuiZonefree(this.zone), takeUntil(this.destroy$)) + .subscribe(() => + this.editorService.valueChange$.next(this.editorService.getHTML()), + ); + } } diff --git a/projects/tui-editor/constants/default-events.ts b/projects/tui-editor/constants/default-events.ts new file mode 100644 index 000000000..e07a6844a --- /dev/null +++ b/projects/tui-editor/constants/default-events.ts @@ -0,0 +1 @@ +export const TUI_EDITOR_RESIZE_EVENT = `tui_editor_resize` as const; diff --git a/projects/tui-editor/constants/index.ts b/projects/tui-editor/constants/index.ts index 10e5d819c..821b3ce9a 100644 --- a/projects/tui-editor/constants/index.ts +++ b/projects/tui-editor/constants/index.ts @@ -1,5 +1,6 @@ export * from './default-editor-colors'; export * from './default-editor-tools'; +export * from './default-events'; export * from './default-font-options-handler'; export * from './default-html5-media-attributes'; export * from './default-link-options-handler'; diff --git a/projects/tui-editor/directives/tiptap-editor/tiptap-editor.service.ts b/projects/tui-editor/directives/tiptap-editor/tiptap-editor.service.ts index c3e31ee00..91864677e 100644 --- a/projects/tui-editor/directives/tiptap-editor/tiptap-editor.service.ts +++ b/projects/tui-editor/directives/tiptap-editor/tiptap-editor.service.ts @@ -51,13 +51,12 @@ export class TuiTiptapEditorService extends AbstractTuiEditor { this.editor = editor; const update = (): void => { - this.stateChange$.next(); - const content = editor.getHTML(); const json = editor.getJSON().content; const value: string = tuiIsEmptyParagraph(json) ? `` : content; this.valueChange$.next(value); + this.stateChange$.next(); }; editor.on(`transaction`, update.bind(this)); @@ -412,4 +411,8 @@ export class TuiTiptapEditorService extends AbstractTuiEditor { ): void { this.editor.commands.toggleMark(typeOrName, attributes, options); } + + getHTML(): string { + return this.getOriginTiptapEditor().getHTML() ?? ``; + } } diff --git a/projects/tui-editor/extensions/iframe-editor/iframe-editor.component.ts b/projects/tui-editor/extensions/iframe-editor/iframe-editor.component.ts index 4dbef91f1..22f84e928 100644 --- a/projects/tui-editor/extensions/iframe-editor/iframe-editor.component.ts +++ b/projects/tui-editor/extensions/iframe-editor/iframe-editor.component.ts @@ -1,7 +1,8 @@ -import {ChangeDetectionStrategy, Component, Inject} from '@angular/core'; +import {ChangeDetectionStrategy, Component, ElementRef, Inject} from '@angular/core'; import {DomSanitizer, SafeResourceUrl} from '@angular/platform-browser'; import {TuiDestroyService} from '@taiga-ui/cdk'; import {AbstractTuiEditorResizable} from '@tinkoff/tui-editor/components/editor-resizable'; +import {TUI_EDITOR_RESIZE_EVENT} from '@tinkoff/tui-editor/constants'; import { TUI_IFRAME_EDITOR_OPTIONS, @@ -24,6 +25,7 @@ export class TuiIframeEditorComponent extends AbstractTuiEditorResizable, ) { super(); } @@ -42,7 +44,8 @@ export class TuiIframeEditorComponent extends AbstractTuiEditorResizable