libs/core/src/lib/services/taly-content-render.service.ts
Bridges page content render-readiness to the frame so it paints the surrounding sections (footer, actions, small print) only once content has rendered, avoiding Cumulative Layout Shift (CLS).
Several Building Block pages can be alive at the same time — the routed page plus the
projected frame-header-actions and frame-global-sidebar-content pages — so readiness
is tracked per source and only reported as ready once every registered source is ready.
Provided by FrameComponent, so the frame and the Building Block pages projected into it
(routed page, header-actions, global-sidebar) resolve the same instance via the element
injector. Pages rendered outside a frame inject it optionally and simply skip reporting.
No results matching.
Properties |
Methods |
| registerSource |
registerSource()
|
|
Register a content source. It starts as not-ready, so registering holds back the frame until the source reports otherwise. Returns a key used to update or remove it.
Returns :
ContentRenderSourceKey
|
| setSourceReady | |||||||||
setSourceReady(key: ContentRenderSourceKey, ready: boolean)
|
|||||||||
|
Parameters :
Returns :
void
|
| unregisterSource | ||||||
unregisterSource(key: ContentRenderSourceKey)
|
||||||
|
Parameters :
Returns :
void
|
| contentRenderReady$ |
Type : unknown
|
Default value : this._contentRenderReady$.pipe(distinctUntilChanged())
|
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
export type ContentRenderSourceKey = symbol;
/**
* Bridges page content render-readiness to the frame so it paints the surrounding sections
* (footer, actions, small print) only once content has rendered, avoiding Cumulative Layout
* Shift (CLS).
*
* Several Building Block pages can be alive at the same time — the routed page plus the
* projected `frame-header-actions` and `frame-global-sidebar-content` pages — so readiness
* is tracked per source and only reported as ready once every registered source is ready.
*
* Provided by `FrameComponent`, so the frame and the Building Block pages projected into it
* (routed page, header-actions, global-sidebar) resolve the same instance via the element
* injector. Pages rendered outside a frame inject it optionally and simply skip reporting.
*/
@Injectable()
export class TalyContentRenderService {
private _sourceReadiness = new Map<ContentRenderSourceKey, boolean>();
private _contentRenderReady$ = new BehaviorSubject<boolean>(true);
contentRenderReady$ = this._contentRenderReady$.pipe(distinctUntilChanged());
/**
* Register a content source. It starts as not-ready, so registering holds back the frame
* until the source reports otherwise. Returns a key used to update or remove it.
*/
registerSource(): ContentRenderSourceKey {
const key = Symbol('content-render-source');
this._sourceReadiness.set(key, false);
this._emitReadiness();
return key;
}
setSourceReady(key: ContentRenderSourceKey, ready: boolean): void {
if (!this._sourceReadiness.has(key)) {
return;
}
this._sourceReadiness.set(key, ready);
this._emitReadiness();
}
unregisterSource(key: ContentRenderSourceKey): void {
if (this._sourceReadiness.delete(key)) {
this._emitReadiness();
}
}
private _emitReadiness(): void {
const allReady = Array.from(this._sourceReadiness.values()).every(Boolean);
this._contentRenderReady$.next(allReady);
}
}