From 50fdf1597eb2f51d20b6bc7855e0abba528891d9 Mon Sep 17 00:00:00 2001 From: "ala'n (Alexey Stsefanovich)" Date: Wed, 14 Feb 2024 20:49:59 +0100 Subject: [PATCH] fix(core): lazy update and alternative re-size control for `uip-preview` --- src/core/preview/preview.tsx | 18 +++++++++++++++--- src/core/processors/templates.ts | 4 +++- 2 files changed, 18 insertions(+), 4 deletions(-) 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}
+ `);