@mui/internal-docs-infra
Version:
MUI Infra - internal documentation creation tools.
306 lines (298 loc) • 12.2 kB
JavaScript
/**
* Pure function to get available transforms from effective code data.
*
* Variant-level `transforms` is a manifest produced by `splitTransformsForEmbed`
* (or by the legacy `Transforms` shape with deltas, for back-compat). Only
* entries that produced a real source delta are reported here — rename-only
* entries (manifest entries with `hasDelta: false`, kept around so the
* runtime can still apply the rename based on user preference) are filtered
* out so the transform toggle stays hidden when nothing meaningful changes.
*
* @param effectiveCode - The effective code object containing all variants
* @param selectedVariantKey - The currently selected variant key
* @returns Array of available transform keys (toggle-visible only)
*/
export function getAvailableTransforms(effectiveCode, selectedVariantKey) {
return collectTransformKeys(effectiveCode, selectedVariantKey, {
onlyWithDelta: true
});
}
/**
* Like `getAvailableTransforms` but also includes rename-only entries
* (manifest entries with `hasDelta: false`). Used by the transform
* resolution path so a stored preference can still apply a rename even
* when its toggle is hidden because no actual delta exists.
*
* @param effectiveCode - The effective code object containing all variants
* @param selectedVariantKey - The currently selected variant key
* @returns Array of all applicable transform keys
*/
export function getApplicableTransforms(effectiveCode, selectedVariantKey) {
return collectTransformKeys(effectiveCode, selectedVariantKey, {
onlyWithDelta: false
});
}
function collectTransformKeys(effectiveCode, selectedVariantKey, {
onlyWithDelta
}) {
const transforms = new Set();
if (!effectiveCode || !selectedVariantKey) {
return [];
}
const variantCode = effectiveCode[selectedVariantKey];
if (!variantCode || typeof variantCode !== 'object') {
return [];
}
const add = entries => {
if (!entries) {
return;
}
for (const [transformKey, entry] of Object.entries(entries)) {
if (!entry) {
continue;
}
if (!onlyWithDelta) {
transforms.add(transformKey);
continue;
}
const inlineDelta = !!entry.delta && typeof entry.delta === 'object' && Object.keys(entry.delta).length > 0;
if (entry.hasDelta || inlineDelta) {
transforms.add(transformKey);
}
}
};
if ('transforms' in variantCode) {
add(variantCode.transforms);
}
if ('extraFiles' in variantCode && variantCode.extraFiles) {
for (const fileData of Object.values(variantCode.extraFiles)) {
if (fileData && typeof fileData === 'object' && 'transforms' in fileData) {
add(fileData.transforms);
}
}
}
return Array.from(transforms);
}
/**
* Determines whether applying `transformKey` to `variant` would introduce
* `.collapse` placeholders into the rendered hast tree — i.e. whether the
* swap is layout-affecting and must run through the coordinated barrier.
*
* Reads the precomputed `hasCollapse` / `hasCollapseInFocus` flags
* stored on each transform entry by the pipeline (`diffHast` sets them
* directly, `splitTransformsForEmbed` propagates them onto the
* manifest). No tree walking or delta decompression happens at runtime.
*
* The `mode` option controls *which* file's transform entry is consulted:
*
* - `'selected'` (default) — Consults only the transform map for the
* file identified by `selectedFileName` (or `variant.transforms`
* when `selectedFileName === variant.fileName`). When
* `selectedFileName` is omitted, treats the variant's main file
* (`variant.fileName`) as the selection.
* - `'all'` — Iterates every transform map on the variant
* (`variant.transforms` + each `extraFiles[*].transforms`) and
* returns `true` if any one has `hasCollapse: true`. Useful for
* callers that render multiple files simultaneously and need to
* coordinate a swap whenever *any* file would shift.
* - `'focus'` — Like `'selected'`, but consults
* `hasCollapseInFocus` instead of `hasCollapse` whenever
* `expanded === false`. Lets consumers skip the coordinated
* barrier for transforms whose `.collapse` insertion lands
* outside the initially-visible region of a collapsed code block.
*
* Falls back to a conservative phase 1 classification for legacy
* payloads that carry `hasDelta: true` without the precomputed flag —
* i.e. transforms produced by an older build that predates
* `hasCollapse`, or constructed by a direct caller bypassing the
* pipeline. For `hasCollapseInFocus`, entries that lack the field fall
* back to the value of `hasCollapse` (matching the embed-side default).
*
* Returns `false` when every consulted entry has `hasCollapse: false`
* (or `hasCollapseInFocus: false` in focus mode while collapsed), is
* rename-only, is absent, or the variant is `null`.
*
* @param variant - The variant whose transforms to inspect.
* @param transformKey - The transform key to classify, or `null`.
* @param opts - Optional mode + selected-file + expanded context.
*/
export function transformHasCollapsePlaceholder(variant, transformKey, opts) {
if (!variant || !transformKey) {
return false;
}
const mode = opts?.mode ?? 'selected';
const expanded = opts?.expanded ?? false;
// `'selected'`/`'focus'` default to the variant's main file when no
// selection is supplied. This lines up with the runtime's "render
// the main file by default" behavior.
let selectedFileName = opts?.selectedFileName;
if (selectedFileName === undefined && mode !== 'all' && 'fileName' in variant) {
selectedFileName = variant.fileName;
}
// In focus mode while collapsed, the relevant precomputed flag is
// the focus-scoped one. Everywhere else we still consult plain
// `hasCollapse`. The `useFocusFlag` decision is taken once up front
// so the per-entry checks stay branch-free.
const useFocusFlag = mode === 'focus' && !expanded;
const checkEntry = entry => {
if (!entry) {
return false;
}
if (useFocusFlag) {
// Prefer the focus-scoped flag; legacy payloads (no
// `hasCollapseInFocus` field) fall through to `hasCollapse`
// which itself falls back to the conservative phase 1
// classification below.
if (entry.hasCollapseInFocus === true) {
return true;
}
if (entry.hasCollapseInFocus === false) {
return false;
}
}
if (entry.hasCollapse === true) {
return true;
}
// Legacy fallback: an older payload carries `hasDelta: true` with
// neither an inline delta nor the precomputed flag. Classify
// conservatively as phase 1 so the swap stays layout-stable.
if (entry.hasCollapse === undefined && entry.hasDelta && !entry.delta) {
return true;
}
return false;
};
// `'all'` mode walks every transform map on the variant.
if (mode === 'all') {
if ('transforms' in variant && variant.transforms) {
if (checkEntry(variant.transforms[transformKey])) {
return true;
}
}
if ('extraFiles' in variant && variant.extraFiles) {
for (const file of Object.values(variant.extraFiles)) {
if (file && typeof file === 'object' && 'transforms' in file && file.transforms) {
if (checkEntry(file.transforms[transformKey])) {
return true;
}
}
}
}
return false;
}
// `'selected'` / `'focus'` consult only the chosen file's transforms.
// Main file is identified by `variant.fileName`; everything else is
// looked up under `extraFiles`. `selectedFileName` is guaranteed to
// be defined here (the default above falls back to `variant.fileName`).
if (selectedFileName === undefined) {
return false;
}
if ('fileName' in variant && selectedFileName === variant.fileName) {
if ('transforms' in variant && variant.transforms) {
return checkEntry(variant.transforms[transformKey]);
}
return false;
}
if ('extraFiles' in variant && variant.extraFiles) {
const file = variant.extraFiles[selectedFileName];
if (file && typeof file === 'object' && 'transforms' in file && file.transforms) {
return checkEntry(file.transforms[transformKey]);
}
}
return false;
}
/**
* Description of a single transform entry that carries
* `hasCollapseInFocus: true`. Returned by
* `findCollapseInFocusTransforms` so callers can produce actionable
* error messages without re-walking the variant tree.
*/
/**
* Walk every variant on `effectiveCode` and collect transform entries
* whose precomputed `hasCollapseInFocus` flag is `true` — i.e. the
* collapse placeholder introduced by the transform lands inside the
* focus region that is visible while the surrounding code block is
* un-expanded.
*
* Used by `useCode`'s `strictCollapseInFocus` option to throw with a
* pointer to the offending variant/file/transform so the demo author
* can narrow the `@focus` region (or the transform's edit range) until
* the placeholder lands outside the visible window.
*
* Walks main files (`variant.transforms`) and `extraFiles[*].transforms`.
* Returns an empty array when no entry has the flag set.
*/
export function findCollapseInFocusTransforms(effectiveCode) {
const offenders = [];
const collectFromMap = (variantName, fileName, transforms) => {
if (!transforms) {
return;
}
for (const [transformKey, entry] of Object.entries(transforms)) {
if (entry?.hasCollapseInFocus === true) {
offenders.push({
variantName,
fileName,
transformKey
});
}
}
};
for (const [variantName, variant] of Object.entries(effectiveCode)) {
if (!variant || typeof variant !== 'object') {
continue;
}
if ('transforms' in variant && variant.transforms) {
const fileName = 'fileName' in variant && variant.fileName || '<main>';
collectFromMap(variantName, fileName, variant.transforms);
}
if ('extraFiles' in variant && variant.extraFiles) {
for (const [fileName, file] of Object.entries(variant.extraFiles)) {
if (file && typeof file === 'object' && 'transforms' in file) {
collectFromMap(variantName, fileName, file.transforms);
}
}
}
}
return offenders;
}
/**
* Decide whether the rendered `<Pre>` should emit highlighted spans on
* this render. Three gates compose:
*
* 1. `highlightReady` — the render-side readiness gate published by
* `CodeHighlighterClient`. `false` while the highlight trigger
* (`hydration` / `idle` / `visible`) hasn't fired yet *or* the
* sync `parseCode` pass hasn't resolved. The precomputed HAST on
* the published `code` would render highlighted spans on first
* paint otherwise — defeating the deferred trigger. Treated as
* `true` when undefined so legacy/test consumers without a
* surrounding context default to rendering highlighted.
* 2. `deferHighlight` — the narrower pipeline-level signal published
* while the incoming variant's parse / transform deltas are still
* in flight. Always wins: if the tree isn't ready, highlighting
* can't happen.
* 3. `pendingBootstrap` — set while a stored-preference variant swap
* is queued behind the initial mount. Suppresses the *outgoing*
* tree's highlighting so we don't burn cycles painting spans the
* user is about to swap away from.
*
* The bootstrap gate is skipped when `highlightAfter === 'init'`:
* - the precomputed HAST already carries the spans (no "wasted work"),
* and
* - leaving it on causes the *incoming* variant to render as plain
* text for the render between `pendingBootstrap` flipping and the
* bootstrap commit landing, producing a visible flash of unhighlighted
* code on first-paint variant swaps.
*/
export function shouldHighlightForRender(args) {
if (args.deferHighlight) {
return false;
}
if (args.highlightReady === false) {
return false;
}
if (args.highlightAfter === 'init') {
return true;
}
return !args.pendingBootstrap;
}