diff --git a/src/core/preview/preview.tsx b/src/core/preview/preview.tsx index f864c4f0..dedefee1 100644 --- a/src/core/preview/preview.tsx +++ b/src/core/preview/preview.tsx @@ -9,6 +9,7 @@ import {UIPPlugin} from '../base/plugin'; import {UIPRenderingTemplatesService} from '../processors/templates'; import {UIPJSRenderingPreprocessors, UIPHTMLRenderingPreprocessors} from '../processors/rendering'; +import type {UIPChangeEvent} from '../base/model.change'; import type {ESLIntersectionEvent} from '@exadel/esl/modules/esl-event-listener/core'; /** @@ -24,6 +25,8 @@ export class UIPPreview extends UIPPlugin { /** Marker to use iframe isolated rendering */ @attr({parser: parseBoolean, serializer: toBooleanAttribute}) public isolation: boolean; + /** Marker to use iframe isolated rendering */ + @attr({parser: parseBoolean, serializer: toBooleanAttribute}) public forceUpdate: boolean; /** Template to use for isolated rendering */ @attr({defaultValue: 'default'}) public isolationTemplate: string; @@ -73,6 +76,12 @@ export class UIPPreview extends UIPPlugin { } } + protected update(e?: UIPChangeEvent): void { + if (!this.isolation) return this.writeContent(); + if (!e || e.jsChanges.length || this.forceUpdate) this.writeContentIsolated(); + this._onIframeLoad(); + } + /** Writes the content directly to the inner area (non-isolated frame) */ protected writeContent(): void { this.$inner.innerHTML = UIPHTMLRenderingPreprocessors.preprocess(this.model!.html); @@ -97,8 +106,11 @@ export class UIPPreview extends UIPPlugin { if (this._iframeResizeRAF) cancelAnimationFrame(this._iframeResizeRAF); // Addition loop fallback for iframe removal if (this.$iframe.parentElement !== this.$inner) return; + const $document = this.$iframe.contentWindow?.document; + const $root = $document?.querySelector('[uip-content-root]') || $document?.body; + if (!$root) return; // Reflect iframe height with inner content - this.$iframe.style.height = `${this.$iframe.contentWindow?.document.body.scrollHeight}px`; + this.$iframe.style.height = `${$root.scrollHeight}px`; this._iframeResizeRAF = requestAnimationFrame(this.startIframeResizeLoop.bind(this)); } @@ -140,9 +152,9 @@ export class UIPPreview extends UIPPlugin { /** Updates preview content from the model state changes */ @listen({event: 'uip:change', target: ($this: UIPPreview) => $this.$root}) - protected _onRootStateChange(): void { + protected _onRootStateChange(e?: UIPChangeEvent): void { this.$container.style.minHeight = `${this.$inner.offsetHeight}px`; - this.isolation ? this.writeContentIsolated() : this.writeContent(); + this.update(e); afterNextRender(() => this.$container.style.minHeight = '0px'); skipOneRender(() => { diff --git a/src/core/processors/templates.ts b/src/core/processors/templates.ts index ab392f1c..819f558b 100644 --- a/src/core/processors/templates.ts +++ b/src/core/processors/templates.ts @@ -35,6 +35,8 @@ UIPRenderingTemplatesService.add('default', ` - {content} + +
{content}
+ `);