9343 lines
350 KiB
JavaScript
9343 lines
350 KiB
JavaScript
/**
|
||||
|
|
* @vue/runtime-vapor v3.6.0-rc.10
|
|||
|
|
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
|||
|
|
* @license MIT
|
|||
|
|
**/
|
|||
|
|
import { Comment as Comment$1, EffectScope, Fragment, NULL_DYNAMIC_COMPONENT, Static, TransitionPropsValidators, VaporSlot, VueElementBase, activate, baseApplyTranslation, baseEmit, baseNormalizePropsOptions, baseResolveTransitionHooks, callPendingCbs, callWithAsyncErrorHandling, callWithErrorHandling, checkTransitionMode, cloneVNode, createAppAPI, createAsyncComponentContext, createCanSetSetupRefChecker, createCommentVNode, createInternalObject, createVNode, currentInstance, currentInstance as currentInstance$1, deactivate, defaultPropGetter, devtoolsComponentAdded, endMeasure, ensureHydrationRenderer, ensureRenderer, ensureValidVNode, expose, filterModelListeners, flushOnAppMount, forceReflow, getAttributeMismatch, getComponentName, getContainerType, getFunctionalFallthrough, getInheritedScopeIds, getTransitionRawChildren, handleError, handleMovedChildren, hasCSSTransform, initFeatureFlags, invalidateMount, invokeDirectiveHook, invokeSlotFallback, invokeVNodeHook, isAsyncWrapper, isEmitListener, isFunctionalFallthroughKey, isHydrating, isHydratingEnabled, isKeepAlive, isMapEqual, isMismatchAllowed, isSetEqual, isTeleportDeferred, isTeleportDisabled, isTemplateNode, isTemplateRefKey, isUnchangedResourceProp, isVNode, isValidHtmlOrSvgAttribute, knownTemplateRefs, leaveCbKey, logMismatchError, markAsyncBoundary, matches, mergeProps, nextUid, normalizeContainer, normalizeRef, normalizeVNode, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onMounted, onScopeDispose, onUpdated, parseEventName, patchClass, patchStyle, performAsyncHydrate, performTransitionEnter, performTransitionLeave, popWarningContext, prepareTransitionLeave, prepareTransitionSwitch, pushWarningContext, queueJob, queuePostFlushCb, queuePostRenderEffect, rawVaporSlotKey, registerHMR, renderSlot, resetShapeFlag, resolveComponent, resolveCssVars, resolveDynamicComponent, resolvePropValue, resolveTeleportTarget, resolveTransitionChild, resolveTransitionProps, restoreCurrentInstance, setCurrentInstance, setCurrentRenderingInstance, setDevtoolsHook, setRef, setTransitionHooks, setVarsOnNode, shallowReactive, shallowRef, shouldSetAsProp, shouldSetAsPropForVueCE, shouldUpdateComponent, simpleSetCurrentInstance, startMeasure, toClassSet, toHandlers, toStyleMap, unregisterHMR, unsafeToTrustedHTML, useAsyncComponentState, useTransitionState, vModelCheckboxInit, vModelCheckboxUpdate, vModelGetValue, vModelSelectInit, vModelSetSelected, vModelTextInit, vModelTextUpdate, vShowHidden, vShowOriginalDisplay, validateProps, warn, warnExtraneousAttributes, warnPropMismatch, watch, withCtx, withKeys, withModifiers, xlinkNS } from "@vue/runtime-dom";
|
|||
|
|
import { EMPTY_ARR, EMPTY_OBJ, NO, NOOP, camelize, canSetValueDirectly, extend, extend as extend$1, getEscapedCssVarName, getGlobalThis, getSequence, hasChanged, hasOwn, includeBooleanAttr, invokeArrayFns, isArray, isForwardedSlot, isFunction, isModelListener, isObject, isOn, isPlainObject, isPromise, isReservedProp, isSpecialBooleanAttr, isString, isSymbol, looseEqual, normalizeClass, normalizeCssVarValue, normalizeStyle, parseStringStyle, remove as remove$1, slotInheritsFallback, slotNotifiesBoundary, stringifyStyle, toDisplayString } from "@vue/shared";
|
|||
|
|
import { Dep, EffectScope as EffectScope$1, ReactiveEffect, activeSub, computed, effectScope, endBatch, getCurrentScope, isReactive, isReadonly, isRef, isShallow, markRaw, onEffectCleanup, onScopeDispose as onScopeDispose$1, proxyRefs, setActiveSub, setCurrentScope, shallowReactive as shallowReactive$1, shallowReadArray, shallowRef as shallowRef$1, startBatch, toRaw, toReactive, toReadonly, trackDep, traverse, triggerDep, unref, watch as watch$1 } from "@vue/reactivity";
|
|||
|
|
//#region packages/runtime-vapor/src/insertionState.ts
|
|||
|
|
let insertionParent;
|
|||
|
|
let insertionAnchor;
|
|||
|
|
let insertionIndex;
|
|||
|
|
/**
|
|||
|
|
* This function is called before a block type that requires insertion
|
|||
|
|
* (component, slot outlet, if, for) is created.
|
|||
|
|
*
|
|||
|
|
* - `anchor` is a Node: insert before this template `<!>` placeholder during
|
|||
|
|
* client render; during hydration the located placeholder unit is the
|
|||
|
|
* block's hydration target.
|
|||
|
|
* - `anchor` is a number: append; the value is the hydration start unit index
|
|||
|
|
* (the count of preceding logical units), omitted by codegen when 0.
|
|||
|
|
* - `anchor` absent: append with no preceding units.
|
|||
|
|
*/
|
|||
|
|
function setInsertionState(parent, anchor) {
|
|||
|
|
insertionParent = parent;
|
|||
|
|
if (typeof anchor === "number") {
|
|||
|
|
insertionAnchor = void 0;
|
|||
|
|
insertionIndex = anchor;
|
|||
|
|
} else {
|
|||
|
|
insertionAnchor = anchor;
|
|||
|
|
insertionIndex = void 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function resetInsertionState() {
|
|||
|
|
insertionParent = insertionAnchor = insertionIndex = void 0;
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/dom/node.ts
|
|||
|
|
const SVG_NS = "http://www.w3.org/2000/svg";
|
|||
|
|
const MATHML_NS = "http://www.w3.org/1998/Math/MathML";
|
|||
|
|
/*@__NO_SIDE_EFFECTS__*/
|
|||
|
|
function createElement(tagName, ns) {
|
|||
|
|
return ns ? document.createElementNS(ns === 1 ? SVG_NS : MATHML_NS, tagName) : document.createElement(tagName);
|
|||
|
|
}
|
|||
|
|
let t;
|
|||
|
|
function parseTemplate(html, ns) {
|
|||
|
|
t = t || document.createElement("template");
|
|||
|
|
if (ns) {
|
|||
|
|
const tag = ns === 1 ? "svg" : "math";
|
|||
|
|
t.innerHTML = `<${tag}>${html}</${tag}>`;
|
|||
|
|
return /* @__PURE__ */ _child(/* @__PURE__ */ _child(t.content));
|
|||
|
|
}
|
|||
|
|
t.innerHTML = html;
|
|||
|
|
return /* @__PURE__ */ _child(t.content);
|
|||
|
|
}
|
|||
|
|
/*@__NO_SIDE_EFFECTS__*/
|
|||
|
|
function createTextNode(value = "") {
|
|||
|
|
return document.createTextNode(value);
|
|||
|
|
}
|
|||
|
|
/*@__NO_SIDE_EFFECTS__*/
|
|||
|
|
function createComment(data) {
|
|||
|
|
return document.createComment(data);
|
|||
|
|
}
|
|||
|
|
/*@__NO_SIDE_EFFECTS__*/
|
|||
|
|
function querySelector(selectors) {
|
|||
|
|
return document.querySelector(selectors);
|
|||
|
|
}
|
|||
|
|
/* @__NO_SIDE_EFFECTS__ */
|
|||
|
|
function parentNode(node) {
|
|||
|
|
return node.parentNode;
|
|||
|
|
}
|
|||
|
|
/*@__NO_SIDE_EFFECTS__*/
|
|||
|
|
function txt(node) {
|
|||
|
|
if (isHydrating$1) {
|
|||
|
|
let n = /* @__PURE__ */ _child(node);
|
|||
|
|
if (!n) return node.appendChild(/* @__PURE__ */ createTextNode());
|
|||
|
|
return n;
|
|||
|
|
}
|
|||
|
|
return /* @__PURE__ */ _child(node);
|
|||
|
|
}
|
|||
|
|
/*@__NO_SIDE_EFFECTS__*/
|
|||
|
|
function child(node, isText) {
|
|||
|
|
if (isHydrating$1) {
|
|||
|
|
const n = locateChildByLogicalIndex(node, 0);
|
|||
|
|
return isText ? resolveBlankTextTarget(n, node) : n;
|
|||
|
|
}
|
|||
|
|
return /* @__PURE__ */ _child(node);
|
|||
|
|
}
|
|||
|
|
/*@__NO_SIDE_EFFECTS__*/
|
|||
|
|
function nthChild(node, i, isText) {
|
|||
|
|
if (isHydrating$1) {
|
|||
|
|
const n = locateChildByLogicalIndex(node, i);
|
|||
|
|
return isText ? resolveBlankTextTarget(n, node) : n;
|
|||
|
|
}
|
|||
|
|
return node.childNodes[i];
|
|||
|
|
}
|
|||
|
|
/*@__NO_SIDE_EFFECTS__*/
|
|||
|
|
function next(node, isText) {
|
|||
|
|
if (isHydrating$1) {
|
|||
|
|
let result = nextLogicalSibling(node);
|
|||
|
|
const parent = node.parentNode;
|
|||
|
|
if (isText) result = resolveBlankTextTarget(result, parent);
|
|||
|
|
if (parent) updateLastLocatedLogicalChild(parent, node, result, 1);
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
return /* @__PURE__ */ _next(node);
|
|||
|
|
}
|
|||
|
|
/*@__NO_SIDE_EFFECTS__*/
|
|||
|
|
function _child(node) {
|
|||
|
|
return node.firstChild;
|
|||
|
|
}
|
|||
|
|
/*@__NO_SIDE_EFFECTS__*/
|
|||
|
|
function _next(node) {
|
|||
|
|
return node.nextSibling;
|
|||
|
|
}
|
|||
|
|
const cachedParents = [];
|
|||
|
|
function setLastLocatedLogicalChild(parent, child, logicalIndex) {
|
|||
|
|
if (parent.$llc === void 0) cachedParents.push(parent);
|
|||
|
|
parent.$llc = child;
|
|||
|
|
parent.$lli = logicalIndex;
|
|||
|
|
}
|
|||
|
|
function releaseLocatorCache() {
|
|||
|
|
for (let i = 0; i < cachedParents.length; i++) cachedParents[i].$llc = void 0;
|
|||
|
|
cachedParents.length = 0;
|
|||
|
|
}
|
|||
|
|
function locateChildByLogicalIndex(parent, logicalIndex) {
|
|||
|
|
let child;
|
|||
|
|
let fromIndex;
|
|||
|
|
if (parent.$llc) {
|
|||
|
|
child = parent.$llc;
|
|||
|
|
fromIndex = parent.$lli;
|
|||
|
|
} else {
|
|||
|
|
child = skipUntrackedAnchors(parent.firstChild);
|
|||
|
|
fromIndex = 0;
|
|||
|
|
}
|
|||
|
|
if (logicalIndex < fromIndex) {
|
|||
|
|
child = skipUntrackedAnchors(parent.firstChild);
|
|||
|
|
fromIndex = 0;
|
|||
|
|
}
|
|||
|
|
while (child) {
|
|||
|
|
if (fromIndex === logicalIndex) {
|
|||
|
|
setLastLocatedLogicalChild(parent, child, logicalIndex);
|
|||
|
|
return child;
|
|||
|
|
}
|
|||
|
|
child = nextLogicalSibling(child);
|
|||
|
|
fromIndex++;
|
|||
|
|
}
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
function updateLastLocatedLogicalChild(parent, from, to, logicalIndexOffset = 0) {
|
|||
|
|
const insertionParent = parent;
|
|||
|
|
if (insertionParent.$llc === from) {
|
|||
|
|
insertionParent.$llc = to;
|
|||
|
|
insertionParent.$lli += logicalIndexOffset;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/renderContext.ts
|
|||
|
|
let currentRenderContext = {
|
|||
|
|
slotOwner: null,
|
|||
|
|
slotBoundary: null,
|
|||
|
|
slotScopeIds: null,
|
|||
|
|
suspense: null
|
|||
|
|
};
|
|||
|
|
function setRenderContext(ctx) {
|
|||
|
|
const prev = currentRenderContext;
|
|||
|
|
currentRenderContext = ctx;
|
|||
|
|
return prev;
|
|||
|
|
}
|
|||
|
|
function withRenderContext(ctx, fn) {
|
|||
|
|
if (ctx === currentRenderContext) return fn();
|
|||
|
|
const prev = setRenderContext(ctx);
|
|||
|
|
try {
|
|||
|
|
return fn();
|
|||
|
|
} finally {
|
|||
|
|
currentRenderContext = prev;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function deriveRenderContext(base, slotOwner, slotBoundary, slotScopeIds, suspense) {
|
|||
|
|
return slotOwner === base.slotOwner && slotBoundary === base.slotBoundary && slotScopeIds === base.slotScopeIds && suspense === base.suspense ? base : {
|
|||
|
|
slotOwner,
|
|||
|
|
slotBoundary,
|
|||
|
|
slotScopeIds,
|
|||
|
|
suspense
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
function deriveSlotOwner(base, slotOwner) {
|
|||
|
|
return deriveRenderContext(base, slotOwner, base.slotBoundary, base.slotScopeIds, base.suspense);
|
|||
|
|
}
|
|||
|
|
function deriveSlotBoundary(base, slotBoundary) {
|
|||
|
|
return deriveRenderContext(base, base.slotOwner, slotBoundary, base.slotScopeIds, base.suspense);
|
|||
|
|
}
|
|||
|
|
function deriveSlotScopeIds(base, slotScopeIds) {
|
|||
|
|
return deriveRenderContext(base, base.slotOwner, base.slotBoundary, slotScopeIds, base.suspense);
|
|||
|
|
}
|
|||
|
|
function deriveSuspense(base, suspense) {
|
|||
|
|
return deriveRenderContext(base, base.slotOwner, base.slotBoundary, base.slotScopeIds, suspense);
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/dom/scopeIdStamp.ts
|
|||
|
|
function setElementScopeIds(el, scopeIds) {
|
|||
|
|
for (let i = 0; i < scopeIds.length; i++) el.setAttribute(scopeIds[i], "");
|
|||
|
|
}
|
|||
|
|
function setElementScopeIdsDeep(el, scopeIds) {
|
|||
|
|
setElementScopeIds(el, scopeIds);
|
|||
|
|
let child = el.firstElementChild;
|
|||
|
|
while (child) {
|
|||
|
|
setElementScopeIdsDeep(child, scopeIds);
|
|||
|
|
child = child.nextElementSibling;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Stamped-variant cache: ids are written once per (template prototype × id
|
|||
|
|
* cell) and clones inherit them via cloneNode. Never stale because scope ids
|
|||
|
|
* are compile-time constants; entries are freed with their cell (WeakMap key).
|
|||
|
|
*/
|
|||
|
|
const stampedTemplates = /* @__PURE__ */ new WeakMap();
|
|||
|
|
function cloneStampedTemplate(prototype, scopeIds) {
|
|||
|
|
if (prototype.nodeType !== 1) return prototype.cloneNode(true);
|
|||
|
|
let variants = stampedTemplates.get(prototype);
|
|||
|
|
if (!variants) stampedTemplates.set(prototype, variants = /* @__PURE__ */ new WeakMap());
|
|||
|
|
let stamped = variants.get(scopeIds);
|
|||
|
|
if (!stamped) {
|
|||
|
|
stamped = prototype.cloneNode(true);
|
|||
|
|
setElementScopeIdsDeep(stamped, scopeIds);
|
|||
|
|
variants.set(scopeIds, stamped);
|
|||
|
|
}
|
|||
|
|
return stamped.cloneNode(true);
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/dom/hydration.ts
|
|||
|
|
const START_TAG_RE = /^<([^\s/>]+)/;
|
|||
|
|
let isHydratingEnabled$1 = false;
|
|||
|
|
function setIsHydratingEnabled(value) {
|
|||
|
|
isHydratingEnabled$1 = value;
|
|||
|
|
}
|
|||
|
|
let currentHydrationNode = null;
|
|||
|
|
let isHydrating$1 = false;
|
|||
|
|
function setIsHydrating(value) {
|
|||
|
|
if (!isHydratingEnabled$1 && !isHydrating && !isHydratingEnabled) return false;
|
|||
|
|
try {
|
|||
|
|
return isHydrating$1;
|
|||
|
|
} finally {
|
|||
|
|
isHydrating$1 = value;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
let deferredHydrationBoundaryDepth = 0;
|
|||
|
|
function isInDeferredHydrationBoundary() {
|
|||
|
|
return deferredHydrationBoundaryDepth > 0;
|
|||
|
|
}
|
|||
|
|
function withDeferredHydrationBoundary(fn) {
|
|||
|
|
deferredHydrationBoundaryDepth++;
|
|||
|
|
try {
|
|||
|
|
return fn();
|
|||
|
|
} finally {
|
|||
|
|
deferredHydrationBoundaryDepth--;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function runWithoutHydration(fn) {
|
|||
|
|
const prev = setIsHydrating(false);
|
|||
|
|
try {
|
|||
|
|
return fn();
|
|||
|
|
} finally {
|
|||
|
|
setIsHydrating(prev);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
let isHydratingSlotFallback = false;
|
|||
|
|
function withHydratingSlotFallback(fn) {
|
|||
|
|
const prev = isHydratingSlotFallback;
|
|||
|
|
isHydratingSlotFallback = true;
|
|||
|
|
try {
|
|||
|
|
runWithoutHydration(fn);
|
|||
|
|
} finally {
|
|||
|
|
isHydratingSlotFallback = prev;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
let isOptimized$1 = false;
|
|||
|
|
let hydrationDepth = 0;
|
|||
|
|
let liveCursors = 0;
|
|||
|
|
function performHydration(fn, setup, cleanup) {
|
|||
|
|
if (!isOptimized$1) {
|
|||
|
|
adoptTemplate = adoptTemplateImpl;
|
|||
|
|
locateHydrationNode = locateHydrationNodeImpl;
|
|||
|
|
parseAdoptTarget = parseAdoptTargetImpl;
|
|||
|
|
Comment.prototype.$fe = void 0;
|
|||
|
|
Node.prototype.$llc = void 0;
|
|||
|
|
Node.prototype.$lli = void 0;
|
|||
|
|
Node.prototype.$vha = 0;
|
|||
|
|
Node.prototype.$rcn = void 0;
|
|||
|
|
isOptimized$1 = true;
|
|||
|
|
}
|
|||
|
|
const prev = setIsHydrating(true);
|
|||
|
|
const prevHydrationNode = currentHydrationNode;
|
|||
|
|
currentHydrationNode = null;
|
|||
|
|
hydrationDepth++;
|
|||
|
|
try {
|
|||
|
|
setup();
|
|||
|
|
return fn();
|
|||
|
|
} finally {
|
|||
|
|
cleanup();
|
|||
|
|
currentHydrationNode = prevHydrationNode;
|
|||
|
|
setIsHydrating(prev);
|
|||
|
|
if (--hydrationDepth === 0) {
|
|||
|
|
releaseLocatorCache();
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) {
|
|||
|
|
if (liveCursors > 0) warn(`${liveCursors} hydration cursor(s) were never exited. The enclosing scope's resume point is lost, so the cursor will drift. This is likely a Vue internal bug.`);
|
|||
|
|
liveCursors = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function withHydration(container, fn) {
|
|||
|
|
const setup = () => setInsertionState(container);
|
|||
|
|
const cleanup = () => resetInsertionState();
|
|||
|
|
return performHydration(fn, setup, cleanup);
|
|||
|
|
}
|
|||
|
|
function hydrateNode(node, fn) {
|
|||
|
|
const setup = () => setCurrentHydrationNode(node);
|
|||
|
|
const cleanup = () => {};
|
|||
|
|
return performHydration(fn, setup, cleanup);
|
|||
|
|
}
|
|||
|
|
let adoptTemplate;
|
|||
|
|
let locateHydrationNode;
|
|||
|
|
let parseAdoptTarget;
|
|||
|
|
const isRangeStart = (node) => node.nodeType === 8 && (node.data === "[" || node.data === "(");
|
|||
|
|
const isRangeEnd = (node) => node.nodeType === 8 && (node.data === "]" || node.data === ")");
|
|||
|
|
const isComment = (node, data) => node.nodeType === 8 && node.data === data;
|
|||
|
|
function createFragmentClaim() {
|
|||
|
|
return { start: null };
|
|||
|
|
}
|
|||
|
|
/** Consume the fragment start under the cursor for `claim`. */
|
|||
|
|
function claimFragmentStart(claim) {
|
|||
|
|
const node = currentHydrationNode;
|
|||
|
|
if (node && isRangeStart(node)) {
|
|||
|
|
claim.start = node;
|
|||
|
|
setCurrentHydrationNode(node.nextSibling);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function setCurrentHydrationNode(node) {
|
|||
|
|
currentHydrationNode = skipUntrackedAnchors(node);
|
|||
|
|
}
|
|||
|
|
function advanceHydrationNode(node) {
|
|||
|
|
let next = skipUntrackedAnchors(node.nextSibling);
|
|||
|
|
if (next && currentHydrationNode === next) return;
|
|||
|
|
while (!next) {
|
|||
|
|
const parent = node.parentNode;
|
|||
|
|
if (!parent) break;
|
|||
|
|
node = parent;
|
|||
|
|
next = skipUntrackedAnchors(node.nextSibling);
|
|||
|
|
}
|
|||
|
|
if (currentHydrationNode !== next) currentHydrationNode = next;
|
|||
|
|
}
|
|||
|
|
function enterHydrationCursor(claim, isBlankText) {
|
|||
|
|
const cursor = captureHydrationCursor();
|
|||
|
|
locateHydrationNode(claim, isBlankText);
|
|||
|
|
cursor.start = currentHydrationNode;
|
|||
|
|
return cursor;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Capture the outer resume cursor without locating a start node, for dynamic
|
|||
|
|
* wrappers whose inner owner locates the local start later, after the selected
|
|||
|
|
* inner path is known. This avoids consuming insertion state too early.
|
|||
|
|
*/
|
|||
|
|
function captureHydrationCursor() {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) liveCursors++;
|
|||
|
|
return {
|
|||
|
|
start: null,
|
|||
|
|
resume: insertionParent ? currentHydrationNode : void 0
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
function exitHydrationCursor(cursor) {
|
|||
|
|
if (!cursor) return;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) {
|
|||
|
|
if (cursor.exited) {
|
|||
|
|
warn(`Hydration cursor was exited twice. This is likely a Vue internal bug.`);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
cursor.exited = true;
|
|||
|
|
liveCursors--;
|
|||
|
|
}
|
|||
|
|
if (cursor.resume !== void 0) setCurrentHydrationNode(cursor.resume);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Locate the first non-fragment-comment node and locate the next node
|
|||
|
|
* while handling potential fragments.
|
|||
|
|
*/
|
|||
|
|
function adoptTemplateImpl(node, template, adoptChildren = false, ns, target = parseAdoptTargetImpl(template)) {
|
|||
|
|
if (target.type !== 8) node = target.blank ? resolveBlankTextTarget(node, /* @__PURE__ */ parentNode(node)) : resolveHydrationTarget(node);
|
|||
|
|
if (!matchesAdoptTarget(node, target)) node = handleMismatch(node, template, adoptChildren, ns);
|
|||
|
|
advanceHydrationNode(node);
|
|||
|
|
return node;
|
|||
|
|
}
|
|||
|
|
function nextLogicalSibling(node) {
|
|||
|
|
return skipUntrackedAnchors(isRangeStart(node) ? locateEndAnchor(node).nextSibling : isComment(node, "teleport start") ? locateEndAnchor(node, "teleport start", "teleport end").nextSibling : node.nextSibling);
|
|||
|
|
}
|
|||
|
|
/** Advance past anchors that occupy no SSR logical position. */
|
|||
|
|
function skipUntrackedAnchors(node) {
|
|||
|
|
while (node !== null && node.$vha & 2) node = node.nextSibling;
|
|||
|
|
return node;
|
|||
|
|
}
|
|||
|
|
function locateHydrationNodeImpl(claim, isBlankText) {
|
|||
|
|
let node;
|
|||
|
|
if (insertionAnchor) node = insertionAnchor;
|
|||
|
|
else if (insertionParent) {
|
|||
|
|
node = locateChildByLogicalIndex(insertionParent, insertionIndex || 0);
|
|||
|
|
if (!node && isBlankText) {
|
|||
|
|
node = resolveBlankTextTarget(null, insertionParent);
|
|||
|
|
setLastLocatedLogicalChild(insertionParent, node, insertionIndex || 0);
|
|||
|
|
}
|
|||
|
|
} else node = currentHydrationNode;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && !node) throw new Error("No current hydration node was found.\nthis is likely a Vue internal bug.");
|
|||
|
|
resetInsertionState();
|
|||
|
|
setCurrentHydrationNode(node);
|
|||
|
|
if (claim) claimFragmentStart(claim);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* The end anchor of the SSR fragment starting at `node`, or null when `node`
|
|||
|
|
* is not a fragment start.
|
|||
|
|
*/
|
|||
|
|
function locateFragmentEnd(node) {
|
|||
|
|
return node && isRangeStart(node) ? locateEndAnchor(node) : null;
|
|||
|
|
}
|
|||
|
|
function locateEndAnchor(node, open = node.data, close = open === "(" ? ")" : "]") {
|
|||
|
|
if (node.$fe) return node.$fe;
|
|||
|
|
const stack = [node];
|
|||
|
|
while ((node = /* @__PURE__ */ _next(node)) && stack.length > 0) if (node.nodeType === 8) {
|
|||
|
|
if (node.data === open) {
|
|||
|
|
if (node.$fe) node = node.$fe;
|
|||
|
|
else stack.push(node);
|
|||
|
|
} else if (node.data === close) {
|
|||
|
|
const matchingOpen = stack.pop();
|
|||
|
|
matchingOpen.$fe = node;
|
|||
|
|
if (stack.length === 0) return node;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* The close marker of a claimed range once its content hydrated. The cursor
|
|||
|
|
* normally rests on it, so only a mismatch pays for the walk from `start`.
|
|||
|
|
*/
|
|||
|
|
function locateClaimedEnd(start) {
|
|||
|
|
const node = currentHydrationNode;
|
|||
|
|
if (node && isComment(node, start.data === "(" ? ")" : "]") && !isClaimedAnchor(node)) return start.$fe = node;
|
|||
|
|
return locateEndAnchor(start);
|
|||
|
|
}
|
|||
|
|
function handleMismatch(node, template, adoptChildren, ns) {
|
|||
|
|
warnHydrationNodeMismatch(node, template);
|
|||
|
|
if (isRangeStart(node)) removeFragmentNodes(node);
|
|||
|
|
const shouldPreserveAnchor = isClaimedAnchor(node);
|
|||
|
|
const container = /* @__PURE__ */ parentNode(node);
|
|||
|
|
const next = shouldPreserveAnchor ? node : /* @__PURE__ */ _next(node);
|
|||
|
|
if (!shouldPreserveAnchor) remove(node, container);
|
|||
|
|
if (template[0] !== "<") {
|
|||
|
|
const newNode = markRecreatedNode(/* @__PURE__ */ createTextNode(template));
|
|||
|
|
container.insertBefore(newNode, next);
|
|||
|
|
if (!shouldPreserveAnchor) updateLastLocatedLogicalChild(container, node, newNode);
|
|||
|
|
return newNode;
|
|||
|
|
}
|
|||
|
|
const newNode = parseTemplate(template, ns).cloneNode(true);
|
|||
|
|
markRecreatedNode(newNode);
|
|||
|
|
if (newNode.nodeType === 1) {
|
|||
|
|
const descendants = newNode.querySelectorAll("*");
|
|||
|
|
for (let i = 0; i < descendants.length; i++) markRecreatedNode(descendants[i]);
|
|||
|
|
const slotScopeIds = currentRenderContext.slotScopeIds;
|
|||
|
|
if (slotScopeIds) setElementScopeIdsDeep(newNode, slotScopeIds);
|
|||
|
|
}
|
|||
|
|
if (adoptChildren && node.nodeType === 1 && !newNode.firstChild) {
|
|||
|
|
let child = node.firstChild;
|
|||
|
|
while (child) {
|
|||
|
|
const nextChild = child.nextSibling;
|
|||
|
|
newNode.appendChild(child);
|
|||
|
|
child = nextChild;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
container.insertBefore(newNode, next);
|
|||
|
|
if (!shouldPreserveAnchor) updateLastLocatedLogicalChild(container, node, newNode);
|
|||
|
|
return newNode;
|
|||
|
|
}
|
|||
|
|
function parseAdoptTargetImpl(template) {
|
|||
|
|
let type;
|
|||
|
|
let tag = null;
|
|||
|
|
let tagUpper = null;
|
|||
|
|
let blank = false;
|
|||
|
|
if (template[0] !== "<") {
|
|||
|
|
type = 3;
|
|||
|
|
blank = template.trim() === "";
|
|||
|
|
} else if (template[1] === "!") type = 8;
|
|||
|
|
else {
|
|||
|
|
type = 1;
|
|||
|
|
const match = START_TAG_RE.exec(template);
|
|||
|
|
if (match) {
|
|||
|
|
tag = match[1].toLowerCase();
|
|||
|
|
tagUpper = match[1].toUpperCase();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return {
|
|||
|
|
type,
|
|||
|
|
tag,
|
|||
|
|
tagUpper,
|
|||
|
|
blank
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Whether a server-rendered node can be adopted for the given client
|
|||
|
|
* template: the node type must match the template's expected type, and
|
|||
|
|
* element tags must match exactly — a prefix check is not enough
|
|||
|
|
* (e.g. a server `<i>` must not be adopted for a client `<ins>`).
|
|||
|
|
* The uppercase identity compare handles HTML elements without allocating;
|
|||
|
|
* the lowercase fallback covers case-preserving foreign elements (SVG/MathML).
|
|||
|
|
*/
|
|||
|
|
function matchesAdoptTarget(node, target) {
|
|||
|
|
if (node.nodeType !== target.type) return false;
|
|||
|
|
if (target.type !== 1) return true;
|
|||
|
|
return !target.tag || node.tagName === target.tagUpper || node.tagName.toLowerCase() === target.tag;
|
|||
|
|
}
|
|||
|
|
function validateHydrationTarget(node, template) {
|
|||
|
|
if (!matchesAdoptTarget(node, parseAdoptTargetImpl(template))) warnHydrationNodeMismatch(node, template);
|
|||
|
|
}
|
|||
|
|
function hydrateTextNode(node, expected) {
|
|||
|
|
if (node.nodeType !== 3) return false;
|
|||
|
|
const text = node;
|
|||
|
|
if (text.data === expected) return true;
|
|||
|
|
const parent = text.parentElement;
|
|||
|
|
if (parent && !isMismatchAllowed(parent, 0)) {
|
|||
|
|
(process.env.NODE_ENV !== "production" || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && warnHydrationTextMismatch(text, expected);
|
|||
|
|
logMismatchError();
|
|||
|
|
}
|
|||
|
|
text.data = expected;
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
function warnHydrationTextMismatch(node, expected) {
|
|||
|
|
warn(`Hydration text mismatch in`, node.parentNode, `\n - rendered on server: ${JSON.stringify(node.data)}\n - expected on client: ${JSON.stringify(expected)}`);
|
|||
|
|
}
|
|||
|
|
function warnHydrationNodeMismatch(node, expected) {
|
|||
|
|
if (!isMismatchAllowed(node.parentElement, 1)) {
|
|||
|
|
(process.env.NODE_ENV !== "production" || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && warn(`Hydration node mismatch:\n- rendered on server:`, node, node.nodeType === 3 ? `(text)` : isRangeStart(node) ? `(start of fragment)` : ``, `\n- expected on client:`, expected);
|
|||
|
|
logMismatchError();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function removeFragmentNodes(node, endAnchor) {
|
|||
|
|
const parent = /* @__PURE__ */ parentNode(node);
|
|||
|
|
if (!parent) return;
|
|||
|
|
const end = endAnchor || locateEndAnchor(node);
|
|||
|
|
while (true) {
|
|||
|
|
const next = /* @__PURE__ */ _next(node);
|
|||
|
|
if (next && next !== end) remove(next, parent);
|
|||
|
|
else break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function removeHydrationNode(node, close = null) {
|
|||
|
|
const parent = /* @__PURE__ */ parentNode(node);
|
|||
|
|
if (!parent) return;
|
|||
|
|
if (isRangeStart(node)) {
|
|||
|
|
const end = locateEndAnchor(node);
|
|||
|
|
removeFragmentNodes(node, end || void 0);
|
|||
|
|
const endParent = end && /* @__PURE__ */ parentNode(end);
|
|||
|
|
if (end && end !== close && endParent) remove(end, endParent);
|
|||
|
|
} else if (isComment(node, "teleport start")) {
|
|||
|
|
const end = locateEndAnchor(node, "teleport start", "teleport end");
|
|||
|
|
removeFragmentNodes(node, end || void 0);
|
|||
|
|
const endParent = end && /* @__PURE__ */ parentNode(end);
|
|||
|
|
if (end && end !== close && endParent) remove(end, endParent);
|
|||
|
|
}
|
|||
|
|
remove(node, parent);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Removes unclaimed server-rendered nodes and reports a children mismatch.
|
|||
|
|
* Trims `node` alone by default, the rest of `container`'s child list when
|
|||
|
|
* `container` is given, or the logical siblings up to `close` when leaving a
|
|||
|
|
* hydration boundary (which also moves the cursor onto `close`). Range cleanup
|
|||
|
|
* keeps reused hydration anchors in place.
|
|||
|
|
*/
|
|||
|
|
function cleanupHydrationTail(node, container, close = null) {
|
|||
|
|
if (close) {
|
|||
|
|
let cur = node;
|
|||
|
|
let hasRemovableNode = false;
|
|||
|
|
while (cur && cur !== close) {
|
|||
|
|
if (!isClaimedAnchor(cur)) hasRemovableNode = true;
|
|||
|
|
cur = nextLogicalSibling(cur);
|
|||
|
|
}
|
|||
|
|
if (!cur) return;
|
|||
|
|
if (!hasRemovableNode) {
|
|||
|
|
setCurrentHydrationNode(close);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
const mismatchContainer = container || node.parentElement;
|
|||
|
|
if (mismatchContainer instanceof Element) warnHydrationChildrenMismatch(mismatchContainer);
|
|||
|
|
if (!container && !close) {
|
|||
|
|
removeHydrationNode(node);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
let current = node;
|
|||
|
|
while (current && current !== close && (!container || current.parentNode === container)) {
|
|||
|
|
const next = nextLogicalSibling(current);
|
|||
|
|
if (!isClaimedAnchor(current)) removeHydrationNode(current, close);
|
|||
|
|
current = next;
|
|||
|
|
}
|
|||
|
|
if (close) setCurrentHydrationNode(close);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Claim a node as some fragment's insertion anchor standing AT an SSR
|
|||
|
|
* logical position. Claiming a previously untracked anchor promotes it into
|
|||
|
|
* the position stream — a revived deferred branch does this when its runtime
|
|||
|
|
* anchor takes over the logical unit the branch occupies. Use
|
|||
|
|
* `claimUntrackedAnchor` for an anchor that must stay invisible to traversal.
|
|||
|
|
*/
|
|||
|
|
function claimAnchor(node) {
|
|||
|
|
node.$vha = 1;
|
|||
|
|
return node;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Claim a node as an anchor that holds no SSR logical position, so hydration
|
|||
|
|
* traversal steps over it and inserting one mid-pass cannot shift the
|
|||
|
|
* positions the server output defines. See `2`.
|
|||
|
|
*/
|
|||
|
|
function claimUntrackedAnchor(node) {
|
|||
|
|
node.$vha = 3;
|
|||
|
|
return node;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Whether some fragment owns this node as its insertion anchor, whatever its
|
|||
|
|
* origin. Cleanup and mismatch recovery must leave it in place.
|
|||
|
|
*/
|
|||
|
|
function isClaimedAnchor(node) {
|
|||
|
|
return !!node && !!(node.$vha & 1);
|
|||
|
|
}
|
|||
|
|
function markRecreatedNode(node) {
|
|||
|
|
node.$rcn = 1;
|
|||
|
|
return node;
|
|||
|
|
}
|
|||
|
|
function isRecreatedNode(node) {
|
|||
|
|
return !!node && node.$rcn === 1;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* SSR omits empty text nodes. Block owners consume their opening markers
|
|||
|
|
* before template adoption. Preserve any remaining boundary or sibling while
|
|||
|
|
* seeding the missing text at its logical position.
|
|||
|
|
*/
|
|||
|
|
function resolveBlankTextTarget(node, parent) {
|
|||
|
|
node = skipUntrackedAnchors(node);
|
|||
|
|
if (node && node.nodeType === 3) return node;
|
|||
|
|
const text = /* @__PURE__ */ createTextNode();
|
|||
|
|
parent.insertBefore(text, node);
|
|||
|
|
if (node) updateLastLocatedLogicalChild(parent, node, text);
|
|||
|
|
return text;
|
|||
|
|
}
|
|||
|
|
function resolveHydrationTarget(node) {
|
|||
|
|
while (true) {
|
|||
|
|
const flags = node.$vha;
|
|||
|
|
if (flags) {
|
|||
|
|
if (!(flags & 2)) return node;
|
|||
|
|
} else if (!(isRangeStart(node) || isRangeEnd(node) || isComment(node, "teleport start") || isComment(node, "teleport end"))) return node;
|
|||
|
|
const next = node.nextSibling;
|
|||
|
|
if (!next) return node;
|
|||
|
|
node = next;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function warnHydrationChildrenMismatch(container) {
|
|||
|
|
if (container && !isMismatchAllowed(container, 1)) {
|
|||
|
|
(process.env.NODE_ENV !== "production" || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && warn(`Hydration children mismatch on`, container, `\nServer rendered element contains more child nodes than client nodes.`);
|
|||
|
|
logMismatchError();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function enterHydrationBoundary(close) {
|
|||
|
|
return () => trimHydrationBoundary(close);
|
|||
|
|
}
|
|||
|
|
/** Trim the unclaimed SSR nodes left between the cursor and `close`. */
|
|||
|
|
function trimHydrationBoundary(close) {
|
|||
|
|
const node = currentHydrationNode;
|
|||
|
|
if (close && node && node !== close && !(close.compareDocumentPosition(node) & 4)) cleanupHydrationTail(node, void 0, close);
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/vdomInteropState.ts
|
|||
|
|
let isInteropEnabled = false;
|
|||
|
|
function setInteropEnabled() {
|
|||
|
|
isInteropEnabled = true;
|
|||
|
|
}
|
|||
|
|
const interopKey = Symbol(`interop`);
|
|||
|
|
/**
|
|||
|
|
* Carries the live VDOM slots ref on the raw-slots object handed to a vapor
|
|||
|
|
* component mounted from VDOM. Replaces the old overloaded `_` key, which
|
|||
|
|
* elsewhere means SlotFlags (vdom slots) or VaporSlotStability (slot
|
|||
|
|
* functions).
|
|||
|
|
*/
|
|||
|
|
const interopSlotsKey = Symbol(`interopSlots`);
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/componentEmits.ts
|
|||
|
|
/**
|
|||
|
|
* The logic from core isn't too reusable so it's better to duplicate here
|
|||
|
|
*/
|
|||
|
|
function normalizeEmitsOptions(comp) {
|
|||
|
|
const cached = comp.__emitsOptions;
|
|||
|
|
if (cached) return cached;
|
|||
|
|
const raw = comp.emits;
|
|||
|
|
if (!raw) return null;
|
|||
|
|
let normalized;
|
|||
|
|
if (isArray(raw)) {
|
|||
|
|
normalized = {};
|
|||
|
|
for (const key of raw) normalized[key] = null;
|
|||
|
|
} else normalized = raw;
|
|||
|
|
return comp.__emitsOptions = normalized;
|
|||
|
|
}
|
|||
|
|
function emit(instance, event, ...rawArgs) {
|
|||
|
|
const vnode = isInteropEnabled && instance.interopVNode;
|
|||
|
|
baseEmit(instance, vnode ? vnode.props || EMPTY_OBJ : instance.rawValues, defaultPropGetter, event, ...rawArgs);
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/once.ts
|
|||
|
|
/**
|
|||
|
|
* Whether the code running now belongs to a v-once region: slot content or
|
|||
|
|
* fallback rendered by a `<slot v-once>`, or a compiled v-once directive.
|
|||
|
|
* While set, renderEffect runs its function once instead of creating an
|
|||
|
|
* effect. Every component boundary resets it (Vapor setup, vdom mount), and
|
|||
|
|
* deferred work captures it at creation. Call sites test `inOnce` first so
|
|||
|
|
* the common path pays neither the closure nor the call.
|
|||
|
|
*/
|
|||
|
|
let inOnce = false;
|
|||
|
|
function withOnce(fn, value = true) {
|
|||
|
|
if (inOnce === value) return fn();
|
|||
|
|
const prev = inOnce;
|
|||
|
|
try {
|
|||
|
|
inOnce = value;
|
|||
|
|
return fn();
|
|||
|
|
} finally {
|
|||
|
|
inOnce = prev;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/suspense.ts
|
|||
|
|
let isSuspenseEnabled = false;
|
|||
|
|
let currentUnmountSuspense;
|
|||
|
|
function enableSuspense() {
|
|||
|
|
isSuspenseEnabled = true;
|
|||
|
|
}
|
|||
|
|
function setCurrentUnmountSuspense(suspense) {
|
|||
|
|
try {
|
|||
|
|
return currentUnmountSuspense;
|
|||
|
|
} finally {
|
|||
|
|
currentUnmountSuspense = suspense;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Establishes `suspense` as the active unmount pass's boundary around `fn`.
|
|||
|
|
* The single entry point for the ambient: unmountComponent and the interop
|
|||
|
|
* vnode unmount re-enter through this when their explicit argument differs
|
|||
|
|
* from the active pass.
|
|||
|
|
*/
|
|||
|
|
function runWithUnmountSuspense(suspense, fn) {
|
|||
|
|
const prev = setCurrentUnmountSuspense(suspense);
|
|||
|
|
try {
|
|||
|
|
return fn();
|
|||
|
|
} finally {
|
|||
|
|
setCurrentUnmountSuspense(prev);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* The effective boundary for a teardown reached without a parameter channel —
|
|||
|
|
* scope-disposal callbacks and block removal: the active unmount pass's
|
|||
|
|
* boundary when one is set, the caller's fallback otherwise.
|
|||
|
|
*/
|
|||
|
|
function resolveUnmountSuspense(fallback) {
|
|||
|
|
return currentUnmountSuspense === void 0 ? fallback : currentUnmountSuspense;
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/renderEffect.ts
|
|||
|
|
var RenderEffect = class extends ReactiveEffect {
|
|||
|
|
constructor(render, noLifecycle = false) {
|
|||
|
|
super(noLifecycle ? render : void 0);
|
|||
|
|
this.render = render;
|
|||
|
|
const instance = currentInstance;
|
|||
|
|
if (isInteropEnabled && instance && !instance.vapor && !instance.effectCount) instance.effectCount = 1;
|
|||
|
|
this.order = instance ? instance.effectCount++ : 0;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && !this.subs && !isVaporComponent(instance)) warn("renderEffect called without active EffectScope or Vapor instance.");
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && instance && !noLifecycle) {
|
|||
|
|
this.onTrack = instance.rtc ? (e) => invokeArrayFns(instance.rtc, e) : void 0;
|
|||
|
|
this.onTrigger = instance.rtg ? (e) => invokeArrayFns(instance.rtg, e) : void 0;
|
|||
|
|
}
|
|||
|
|
this.i = instance;
|
|||
|
|
this.job = void 0;
|
|||
|
|
this.flags |= 128;
|
|||
|
|
}
|
|||
|
|
createJob() {
|
|||
|
|
const job = () => {
|
|||
|
|
if (!(this.flags & 256) && this.dirty) {
|
|||
|
|
const deferred = isSuspenseEnabled && this.i && this.i.deferredKeepAliveUpdates;
|
|||
|
|
if (deferred) {
|
|||
|
|
if (isDeferredKeepAliveStateLive(deferred)) {
|
|||
|
|
deferred.effects.push(job);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
settleDeferredKeepAliveUpdates(deferred, job);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
this.run();
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
if (this.i) job.i = this.i;
|
|||
|
|
job.flags |= 2;
|
|||
|
|
return this.job = job;
|
|||
|
|
}
|
|||
|
|
fn() {
|
|||
|
|
const instance = this.i;
|
|||
|
|
const scope = this.subs ? this.subs.sub : void 0;
|
|||
|
|
const hasUpdateHooks = instance && (instance.bu || instance.u);
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && instance) startMeasure(instance, `renderEffect`);
|
|||
|
|
const prev = setCurrentInstance(instance, scope);
|
|||
|
|
try {
|
|||
|
|
if (hasUpdateHooks && instance.isMounted && !instance.isUpdating) {
|
|||
|
|
instance.isUpdating = true;
|
|||
|
|
try {
|
|||
|
|
instance.bu && invokeArrayFns(instance.bu);
|
|||
|
|
this.render();
|
|||
|
|
} catch (err) {
|
|||
|
|
instance.isUpdating = false;
|
|||
|
|
throw err;
|
|||
|
|
}
|
|||
|
|
let updateJob = this.updateJob;
|
|||
|
|
if (!updateJob) updateJob = this.updateJob = () => {
|
|||
|
|
instance.isUpdating = false;
|
|||
|
|
instance.u && invokeArrayFns(instance.u);
|
|||
|
|
};
|
|||
|
|
queuePostRenderEffect(updateJob, void 0, instance.suspense);
|
|||
|
|
} else this.render();
|
|||
|
|
} finally {
|
|||
|
|
restoreCurrentInstance(prev);
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && instance) endMeasure(instance, `renderEffect`);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
notify() {
|
|||
|
|
if (!(this.flags & 256)) queueJob(this.job || this.createJob(), this.i ? this.i.uid : void 0, false, this.order);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
function renderEffect(fn, noLifecycle = false) {
|
|||
|
|
if (inOnce) return fn();
|
|||
|
|
new RenderEffect(fn, noLifecycle).run();
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/componentProps.ts
|
|||
|
|
function resolveSource(source) {
|
|||
|
|
return isFunction(source) ? resolveFunctionSource(source) : source;
|
|||
|
|
}
|
|||
|
|
function resolveFunctionSource(source) {
|
|||
|
|
if (source._cache) return source._cache.value;
|
|||
|
|
const parent = currentInstance && currentInstance.parent;
|
|||
|
|
if (parent) {
|
|||
|
|
const prev = setCurrentInstance(parent, getCurrentScope());
|
|||
|
|
try {
|
|||
|
|
source._cache = computed((oldValue) => {
|
|||
|
|
const prevInner = setCurrentInstance(parent);
|
|||
|
|
try {
|
|||
|
|
return stabilizeDynamicSourceValue(oldValue, source());
|
|||
|
|
} finally {
|
|||
|
|
restoreCurrentInstance(prevInner);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
onScopeDispose$1(() => source._cache = void 0);
|
|||
|
|
} finally {
|
|||
|
|
restoreCurrentInstance(prev);
|
|||
|
|
}
|
|||
|
|
return source._cache.value;
|
|||
|
|
}
|
|||
|
|
return source();
|
|||
|
|
}
|
|||
|
|
function snapshotRawProps(rawProps) {
|
|||
|
|
const snapshot = Object.create(null);
|
|||
|
|
for (const key in rawProps) if (key !== "$") snapshot[key] = freezeValue(key, readSource(rawProps[key]));
|
|||
|
|
const dynamicSources = rawProps.$;
|
|||
|
|
if (dynamicSources) {
|
|||
|
|
const snapshotSources = [];
|
|||
|
|
for (let i = 0; i < dynamicSources.length; i++) {
|
|||
|
|
const source = dynamicSources[i];
|
|||
|
|
const isDynamic = isFunction(source);
|
|||
|
|
const resolved = readSource(source) || EMPTY_OBJ;
|
|||
|
|
const value = Object.create(null);
|
|||
|
|
for (const key in resolved) value[key] = freezeValue(key, isDynamic ? resolved[key] : readSource(resolved[key]));
|
|||
|
|
snapshotSources[i] = value;
|
|||
|
|
}
|
|||
|
|
const symbols = Object.getOwnPropertySymbols(dynamicSources);
|
|||
|
|
for (let i = 0; i < symbols.length; i++) snapshotSources[symbols[i]] = dynamicSources[symbols[i]];
|
|||
|
|
snapshot.$ = snapshotSources;
|
|||
|
|
}
|
|||
|
|
return snapshot;
|
|||
|
|
}
|
|||
|
|
function readSource(source) {
|
|||
|
|
return isFunction(source) ? source() : source;
|
|||
|
|
}
|
|||
|
|
function freezeValue(key, value) {
|
|||
|
|
value = normalizePropValue(key, value);
|
|||
|
|
return isFunction(value) ? () => value : value;
|
|||
|
|
}
|
|||
|
|
function normalizePropValue(key, value, prevValue) {
|
|||
|
|
if (key === "class") return value && !isString(value) ? normalizeClass(value) : value;
|
|||
|
|
return key === "style" && isObject(value) ? stabilizeDynamicSourceValue(prevValue, normalizeStyle([value])) : value;
|
|||
|
|
}
|
|||
|
|
function stabilizeDynamicSourceValue(oldValue, value) {
|
|||
|
|
if (!isPlainObject(oldValue) || !isPlainObject(value)) return value;
|
|||
|
|
const oldKeys = Object.keys(oldValue);
|
|||
|
|
const newKeys = Object.keys(value);
|
|||
|
|
if (oldKeys.length !== newKeys.length) return value;
|
|||
|
|
for (let i = 0; i < newKeys.length; i++) {
|
|||
|
|
const key = newKeys[i];
|
|||
|
|
if (!hasOwn(oldValue, key) || !Object.is(oldValue[key], value[key])) return value;
|
|||
|
|
}
|
|||
|
|
return oldValue;
|
|||
|
|
}
|
|||
|
|
function getPropsProxyHandlers(comp) {
|
|||
|
|
if (comp.__propsHandlers) return comp.__propsHandlers;
|
|||
|
|
const propsOptions = normalizePropsOptions(comp)[0];
|
|||
|
|
const emitsOptions = normalizeEmitsOptions(comp);
|
|||
|
|
const isProp = propsOptions ? (key) => isString(key) && hasOwn(propsOptions, camelize(key)) : NO;
|
|||
|
|
const isAttr = propsOptions || emitsOptions ? (key) => isString(key) && key !== "$" && !isReservedProp(key) && !isProp(key) && !isEmitListener(emitsOptions, key) : (key) => isString(key) && !isReservedProp(key);
|
|||
|
|
const getProp = (instance, key) => {
|
|||
|
|
if (key === "__v_isReactive" || key === "__v_isShallow") return true;
|
|||
|
|
if (isProp(key)) {
|
|||
|
|
trackPropsValue(instance, key);
|
|||
|
|
return instance.propsValues[key];
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
const propsHandlers = propsOptions ? {
|
|||
|
|
get: getProp,
|
|||
|
|
has: (_, key) => isProp(key),
|
|||
|
|
ownKeys: () => Object.keys(propsOptions),
|
|||
|
|
getOwnPropertyDescriptor(target, key) {
|
|||
|
|
if (isProp(key)) return {
|
|||
|
|
configurable: true,
|
|||
|
|
enumerable: true,
|
|||
|
|
get: () => getProp(target, key)
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
} : null;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && propsOptions) Object.assign(propsHandlers, {
|
|||
|
|
set: propsSetDevTrap,
|
|||
|
|
deleteProperty: propsDeleteDevTrap
|
|||
|
|
});
|
|||
|
|
const getAttr = (instance, key) => {
|
|||
|
|
if (isAttr(key)) {
|
|||
|
|
trackPropsValue(instance, key);
|
|||
|
|
return instance.propsValues[key];
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
const hasAttr = (instance, key) => {
|
|||
|
|
if (!isAttr(key)) return false;
|
|||
|
|
trackPropsValue(instance, key);
|
|||
|
|
return hasOwn(instance.propsValues, key);
|
|||
|
|
};
|
|||
|
|
const attrsHandlers = {
|
|||
|
|
get: getAttr,
|
|||
|
|
has: hasAttr,
|
|||
|
|
ownKeys(target) {
|
|||
|
|
trackPropsValue(target, ATTR_KEYS);
|
|||
|
|
return Object.keys(target.propsValues).filter(isAttr);
|
|||
|
|
},
|
|||
|
|
getOwnPropertyDescriptor(target, key) {
|
|||
|
|
if (hasAttr(target, key)) return {
|
|||
|
|
configurable: true,
|
|||
|
|
enumerable: true,
|
|||
|
|
get: () => getAttr(target, key)
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) Object.assign(attrsHandlers, {
|
|||
|
|
set: propsSetDevTrap,
|
|||
|
|
deleteProperty: propsDeleteDevTrap
|
|||
|
|
});
|
|||
|
|
return comp.__propsHandlers = [propsHandlers, attrsHandlers];
|
|||
|
|
}
|
|||
|
|
function getAttrFromRawProps(rawProps, key) {
|
|||
|
|
if (key === "$") return;
|
|||
|
|
const dynamicSources = rawProps.$;
|
|||
|
|
const isEvent = dynamicSources && isString(key) && isOn(key);
|
|||
|
|
const merged = key === "class" || key === "style" || isEvent ? [] : void 0;
|
|||
|
|
if (dynamicSources) {
|
|||
|
|
let i = dynamicSources.length;
|
|||
|
|
let source, isDynamic;
|
|||
|
|
while (i--) {
|
|||
|
|
source = dynamicSources[i];
|
|||
|
|
isDynamic = isFunction(source);
|
|||
|
|
source = isDynamic ? resolveFunctionSource(source) : source;
|
|||
|
|
if (source && hasOwn(source, key)) {
|
|||
|
|
const value = isDynamic ? source[key] : resolveSource(source[key]);
|
|||
|
|
if (merged) merged.push(value);
|
|||
|
|
else return value;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (hasOwn(rawProps, key)) {
|
|||
|
|
const value = resolveSource(rawProps[key]);
|
|||
|
|
if (merged) merged.push(value);
|
|||
|
|
else return value;
|
|||
|
|
}
|
|||
|
|
if (merged && merged.length) {
|
|||
|
|
merged.reverse();
|
|||
|
|
return isEvent ? merged.reduce(mergeEventHandlers) : merged;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function mergeEventHandlers(existing, incoming) {
|
|||
|
|
if (!existing) return incoming;
|
|||
|
|
return incoming && existing !== incoming && !(isArray(existing) && existing.includes(incoming)) ? [].concat(existing, incoming) : existing;
|
|||
|
|
}
|
|||
|
|
function hasAttrFromRawProps(rawProps, key) {
|
|||
|
|
if (key === "$") return false;
|
|||
|
|
const dynamicSources = rawProps.$;
|
|||
|
|
if (dynamicSources) {
|
|||
|
|
let i = dynamicSources.length;
|
|||
|
|
while (i--) {
|
|||
|
|
const source = resolveSource(dynamicSources[i]);
|
|||
|
|
if (source && hasOwn(source, key)) return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return hasOwn(rawProps, key);
|
|||
|
|
}
|
|||
|
|
function getKeysFromRawProps(rawProps) {
|
|||
|
|
const keys = [];
|
|||
|
|
for (const key in rawProps) if (key !== "$") keys.push(key);
|
|||
|
|
const dynamicSources = rawProps.$;
|
|||
|
|
if (dynamicSources) {
|
|||
|
|
let i = dynamicSources.length;
|
|||
|
|
let source;
|
|||
|
|
while (i--) {
|
|||
|
|
source = isFunction(dynamicSources[i]) ? resolveFunctionSource(dynamicSources[i]) : dynamicSources[i];
|
|||
|
|
for (const key in source) keys.push(key);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return Array.from(new Set(keys));
|
|||
|
|
}
|
|||
|
|
function normalizePropsOptions(comp) {
|
|||
|
|
const cached = comp.__propsOptions;
|
|||
|
|
if (cached) return cached;
|
|||
|
|
const raw = comp.props;
|
|||
|
|
if (!raw) return EMPTY_ARR;
|
|||
|
|
const normalized = {};
|
|||
|
|
const needCastKeys = [];
|
|||
|
|
baseNormalizePropsOptions(raw, normalized, needCastKeys);
|
|||
|
|
return comp.__propsOptions = [normalized, needCastKeys];
|
|||
|
|
}
|
|||
|
|
function resolveDefault(factory, instance) {
|
|||
|
|
const prev = setCurrentInstance(instance);
|
|||
|
|
try {
|
|||
|
|
return factory.call(null, instance.props);
|
|||
|
|
} finally {
|
|||
|
|
restoreCurrentInstance(prev);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function hasFallthroughAttrs(comp, rawProps) {
|
|||
|
|
if (rawProps) {
|
|||
|
|
if (rawProps.$ || isInteropEnabled && rawProps[interopKey]) return true;
|
|||
|
|
const propsOptions = comp.props ? normalizePropsOptions(comp)[0] : null;
|
|||
|
|
for (const key in rawProps) if (!propsOptions || !hasOwn(propsOptions, camelize(key))) return true;
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
function resolveDynamicProps(props) {
|
|||
|
|
const mergedRawProps = {};
|
|||
|
|
for (const key in props) if (key !== "$") mergedRawProps[key] = resolveSource(props[key]);
|
|||
|
|
if (props.$) for (const source of props.$) {
|
|||
|
|
const isDynamic = isFunction(source);
|
|||
|
|
const resolved = isDynamic ? resolveFunctionSource(source) : source;
|
|||
|
|
for (const key in resolved) {
|
|||
|
|
const value = isDynamic ? resolved[key] : resolveSource(source[key]);
|
|||
|
|
if (key === "class" || key === "style") {
|
|||
|
|
const existing = mergedRawProps[key];
|
|||
|
|
mergedRawProps[key] = isArray(existing) ? [...existing, value] : [existing, value];
|
|||
|
|
} else if (isOn(key)) mergedRawProps[key] = mergeEventHandlers(mergedRawProps[key], value);
|
|||
|
|
else mergedRawProps[key] = value;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return mergedRawProps;
|
|||
|
|
}
|
|||
|
|
function getStaticBindingKeys(props) {
|
|||
|
|
const keys = [];
|
|||
|
|
for (const key in props) if (key !== "$" && isFunction(props[key])) keys.push(key);
|
|||
|
|
if (props.$) {
|
|||
|
|
for (const source of props.$) if (!isFunction(source)) {
|
|||
|
|
for (const key in source) if (isFunction(source[key])) keys.push(key);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return keys;
|
|||
|
|
}
|
|||
|
|
function propsSetDevTrap(_, key) {
|
|||
|
|
warn(`Attempt to mutate prop ${JSON.stringify(key)} failed. Props are readonly.`);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
function propsDeleteDevTrap(_, key) {
|
|||
|
|
warn(`Attempt to delete prop ${JSON.stringify(key)} failed. Props are readonly.`);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
const rawPropsProxyHandlers = {
|
|||
|
|
get: getAttrFromRawProps,
|
|||
|
|
has: hasAttrFromRawProps,
|
|||
|
|
ownKeys: getKeysFromRawProps,
|
|||
|
|
getOwnPropertyDescriptor(target, key) {
|
|||
|
|
if (hasAttrFromRawProps(target, key)) return {
|
|||
|
|
configurable: true,
|
|||
|
|
enumerable: true,
|
|||
|
|
get: () => getAttrFromRawProps(target, key)
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
const RAW_VALUES_KEY = Symbol(!!(process.env.NODE_ENV !== "production") ? "Raw values" : "");
|
|||
|
|
const ATTR_KEYS = Symbol(!!(process.env.NODE_ENV !== "production") ? "Attr keys" : "");
|
|||
|
|
const INITIAL_RAW_VALUES = {};
|
|||
|
|
function trackPropsValue(instance, key) {
|
|||
|
|
if (!instance.hasDynamicProps || activeSub === void 0) return;
|
|||
|
|
const deps = instance.propsDeps || (instance.propsDeps = /* @__PURE__ */ new Map());
|
|||
|
|
let dep = deps.get(key);
|
|||
|
|
if (!dep) deps.set(key, dep = new Dep(deps, key));
|
|||
|
|
trackDep(dep, instance.propsValues, key);
|
|||
|
|
}
|
|||
|
|
function triggerPropsValue(instance, key, newValue, oldValue) {
|
|||
|
|
const deps = instance.propsDeps;
|
|||
|
|
if (deps) {
|
|||
|
|
const dep = deps.get(key);
|
|||
|
|
if (dep) triggerDep(dep, instance.propsValues, key, newValue, oldValue);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function trackRawValues(instance) {
|
|||
|
|
trackPropsValue(instance, RAW_VALUES_KEY);
|
|||
|
|
return instance.rawValues;
|
|||
|
|
}
|
|||
|
|
function initInputs(instance, once = false) {
|
|||
|
|
const scope = instance.inputScope || instance.scope;
|
|||
|
|
const prevEffect = instance.inputEffect;
|
|||
|
|
if (prevEffect) prevEffect.stop();
|
|||
|
|
const parent = instance.parent || instance;
|
|||
|
|
const rawProps = instance.rawProps;
|
|||
|
|
const cells = instance.slotSources;
|
|||
|
|
const prev = setCurrentInstance(parent, scope);
|
|||
|
|
try {
|
|||
|
|
const dynamicSources = rawProps.$;
|
|||
|
|
const isInterop = isInteropEnabled && !!rawProps[interopKey];
|
|||
|
|
const canRebind = !!instance.inputScope;
|
|||
|
|
const hasGetters = hasDynamicPropsSource(rawProps);
|
|||
|
|
if (once || !cells && (isInterop || !canRebind && !hasGetters)) {
|
|||
|
|
instance.hasDynamicProps = !once && isInterop;
|
|||
|
|
deliverInputs(instance, isInterop ? rawProps : collectInputs(rawProps, cells), cells);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
instance.hasDynamicProps = canRebind || hasGetters;
|
|||
|
|
const hasStaticKeys = !dynamicSources;
|
|||
|
|
let hasDelivered = false;
|
|||
|
|
const effect = new RenderEffect(() => {
|
|||
|
|
const prevRawValues = instance.rawValues;
|
|||
|
|
const prevInner = setCurrentInstance(parent, scope);
|
|||
|
|
let rawValues;
|
|||
|
|
let propsToUpdate;
|
|||
|
|
try {
|
|||
|
|
if (!hasDelivered || instance.hasDynamicProps) {
|
|||
|
|
if (hasDelivered && hasStaticKeys) propsToUpdate = collectPropsToUpdate(rawProps, prevRawValues);
|
|||
|
|
else {
|
|||
|
|
rawValues = collectProps(rawProps, prevRawValues.style);
|
|||
|
|
if (hasDelivered && stabilizeDynamicSourceValue(prevRawValues, rawValues) === prevRawValues) rawValues = void 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (cells) collectSlotSources(cells);
|
|||
|
|
} finally {
|
|||
|
|
restoreCurrentInstance(prevInner);
|
|||
|
|
}
|
|||
|
|
if (effect.active) {
|
|||
|
|
hasDelivered = false;
|
|||
|
|
deliverInputs(instance, rawValues, cells, propsToUpdate);
|
|||
|
|
hasDelivered = true;
|
|||
|
|
}
|
|||
|
|
}, true);
|
|||
|
|
if (canRebind) instance.inputEffect = effect;
|
|||
|
|
if (!prevEffect) {
|
|||
|
|
effect.run();
|
|||
|
|
if (!effect.deps && !canRebind) {
|
|||
|
|
effect.stop();
|
|||
|
|
instance.hasDynamicProps = false;
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
if (scope.flags & 256) effect.pause();
|
|||
|
|
effect.notify();
|
|||
|
|
}
|
|||
|
|
} finally {
|
|||
|
|
restoreCurrentInstance(prev);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function collectInputs(rawProps, cells) {
|
|||
|
|
const prevSub = setActiveSub();
|
|||
|
|
try {
|
|||
|
|
const rawValues = collectProps(rawProps);
|
|||
|
|
if (cells) collectSlotSources(cells);
|
|||
|
|
return rawValues;
|
|||
|
|
} finally {
|
|||
|
|
setActiveSub(prevSub);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function deliverInputs(instance, rawValues, cells, propsToUpdate) {
|
|||
|
|
const prevSub = setActiveSub();
|
|||
|
|
startBatch();
|
|||
|
|
try {
|
|||
|
|
if (instance && (rawValues || propsToUpdate)) updateProps(instance, rawValues || instance.rawValues, propsToUpdate);
|
|||
|
|
if (cells) commitSlotSources(cells);
|
|||
|
|
} finally {
|
|||
|
|
try {
|
|||
|
|
endBatch();
|
|||
|
|
} finally {
|
|||
|
|
setActiveSub(prevSub);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function collectSlotSources(cells) {
|
|||
|
|
for (let i = 0; i < cells.length; i++) {
|
|||
|
|
const cell = cells[i];
|
|||
|
|
cell.next = cell.source();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function commitSlotSources(cells) {
|
|||
|
|
for (let i = 0; i < cells.length; i++) {
|
|||
|
|
const cell = cells[i];
|
|||
|
|
const next = stabilizeDynamicSourceValue(cell.committed, cell.next);
|
|||
|
|
cell.next = void 0;
|
|||
|
|
if (hasChanged(next, cell.committed)) {
|
|||
|
|
cell.committed = next;
|
|||
|
|
triggerDep(cell);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function hasDynamicPropsSource(rawProps) {
|
|||
|
|
if (rawProps.$) return true;
|
|||
|
|
for (const key in rawProps) if (isFunction(rawProps[key])) return true;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
function collectProps(rawProps, prevStyle) {
|
|||
|
|
const rawValues = Object.create(null);
|
|||
|
|
const dynamicSources = rawProps.$ || EMPTY_ARR;
|
|||
|
|
for (let i = -1; i < dynamicSources.length; i++) {
|
|||
|
|
const source = i < 0 ? rawProps : dynamicSources[i];
|
|||
|
|
const isDynamic = isFunction(source);
|
|||
|
|
const resolved = isDynamic ? source() : source;
|
|||
|
|
for (const key in resolved) {
|
|||
|
|
if (i < 0 && key === "$") continue;
|
|||
|
|
const value = isDynamic ? resolved[key] : readSource(resolved[key]);
|
|||
|
|
if (!dynamicSources.length) rawValues[key] = value;
|
|||
|
|
else if (key === "class") {
|
|||
|
|
if (rawValues.class !== value) rawValues.class = normalizeClass([rawValues.class, value]);
|
|||
|
|
} else if (key === "style") rawValues.style = normalizeStyle([rawValues.style, value]);
|
|||
|
|
else if (isOn(key)) {
|
|||
|
|
const existing = rawValues[key];
|
|||
|
|
if (value && existing !== value && !(isArray(existing) && existing.includes(value))) rawValues[key] = existing ? [].concat(existing, value) : value;
|
|||
|
|
else if (value == null && existing == null && !isModelListener(key)) rawValues[key] = value;
|
|||
|
|
} else if (key !== "") rawValues[key] = value;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (dynamicSources.length) {
|
|||
|
|
if (rawValues.style) rawValues.style = stabilizeDynamicSourceValue(prevStyle, rawValues.style);
|
|||
|
|
} else {
|
|||
|
|
if (rawValues.class) rawValues.class = normalizePropValue("class", rawValues.class);
|
|||
|
|
if (rawValues.style) rawValues.style = normalizePropValue("style", rawValues.style, prevStyle);
|
|||
|
|
}
|
|||
|
|
return rawValues;
|
|||
|
|
}
|
|||
|
|
function collectPropsToUpdate(rawProps, prevRawValues) {
|
|||
|
|
let propsToUpdate;
|
|||
|
|
for (const key in rawProps) {
|
|||
|
|
const source = rawProps[key];
|
|||
|
|
if (isFunction(source)) {
|
|||
|
|
const prevValue = prevRawValues[key];
|
|||
|
|
const value = normalizePropValue(key, source(), prevValue);
|
|||
|
|
if (hasChanged(value, prevValue)) (propsToUpdate || (propsToUpdate = [])).push(key, value);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return propsToUpdate;
|
|||
|
|
}
|
|||
|
|
function updateProps(instance, rawValues, propsToUpdate) {
|
|||
|
|
const propsValues = instance.propsValues;
|
|||
|
|
const [options, needCastKeys] = normalizePropsOptions(instance.type);
|
|||
|
|
const emitsOptions = normalizeEmitsOptions(instance.type);
|
|||
|
|
const prevRawValues = instance.rawValues;
|
|||
|
|
const isInitial = prevRawValues === INITIAL_RAW_VALUES;
|
|||
|
|
if (propsToUpdate) for (let i = 0; i < propsToUpdate.length; i += 2) rawValues[propsToUpdate[i]] = propsToUpdate[i + 1];
|
|||
|
|
else if (!isInitial) rawValues = stabilizeDynamicSourceValue(prevRawValues, rawValues);
|
|||
|
|
instance.rawValues = rawValues;
|
|||
|
|
if (propsToUpdate || !isInitial && rawValues !== prevRawValues) triggerPropsValue(instance, RAW_VALUES_KEY);
|
|||
|
|
const vnode = isInteropEnabled && instance.interopVNode;
|
|||
|
|
if (vnode && vnode.vi) vnode.props = rawValues;
|
|||
|
|
const present = propsToUpdate || isInitial ? void 0 : Object.create(null);
|
|||
|
|
let rawCastValues;
|
|||
|
|
const keys = propsToUpdate || Object.keys(rawValues);
|
|||
|
|
for (let i = 0; i < keys.length; i += propsToUpdate ? 2 : 1) {
|
|||
|
|
let key = keys[i];
|
|||
|
|
if (isReservedProp(key)) continue;
|
|||
|
|
const value = rawValues[key];
|
|||
|
|
const camelKey = camelize(key);
|
|||
|
|
if (options && hasOwn(options, camelKey)) {
|
|||
|
|
key = camelKey;
|
|||
|
|
if (needCastKeys && needCastKeys.includes(key)) {
|
|||
|
|
if (!rawCastValues) rawCastValues = Object.create(null);
|
|||
|
|
rawCastValues[key] = value;
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
} else if (isEmitListener(emitsOptions, key)) continue;
|
|||
|
|
if (present) present[key] = true;
|
|||
|
|
setPropValue(instance, key, value, isInitial);
|
|||
|
|
}
|
|||
|
|
if (needCastKeys && (rawCastValues || !propsToUpdate)) for (let i = 0; i < needCastKeys.length; i++) {
|
|||
|
|
const key = needCastKeys[i];
|
|||
|
|
const isAbsent = !rawCastValues || !hasOwn(rawCastValues, key);
|
|||
|
|
if (isAbsent && propsToUpdate) continue;
|
|||
|
|
setPropValue(instance, key, resolvePropValue(options, key, isAbsent ? void 0 : rawCastValues[key], instance, resolveDefault, isAbsent), isInitial);
|
|||
|
|
if (present) present[key] = true;
|
|||
|
|
}
|
|||
|
|
if (!propsToUpdate) {
|
|||
|
|
for (const key in options) if (present ? !present[key] : !hasOwn(propsValues, key)) {
|
|||
|
|
setPropValue(instance, key, resolvePropValue(options, key, void 0, instance, resolveDefault, true), isInitial);
|
|||
|
|
if (present) present[key] = true;
|
|||
|
|
}
|
|||
|
|
if (present) {
|
|||
|
|
for (const key in propsValues) if (!present[key]) {
|
|||
|
|
const oldValue = propsValues[key];
|
|||
|
|
delete propsValues[key];
|
|||
|
|
triggerPropsValue(instance, key, void 0, oldValue);
|
|||
|
|
triggerPropsValue(instance, ATTR_KEYS);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && options) {
|
|||
|
|
pushWarningContext(instance);
|
|||
|
|
try {
|
|||
|
|
validateProps(rawValues, instance.props, options);
|
|||
|
|
} finally {
|
|||
|
|
popWarningContext();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function setPropValue(instance, key, value, isInitial) {
|
|||
|
|
const propsValues = instance.propsValues;
|
|||
|
|
if (isInitial) {
|
|||
|
|
propsValues[key] = value;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
const hadKey = hasOwn(propsValues, key);
|
|||
|
|
const oldValue = propsValues[key];
|
|||
|
|
propsValues[key] = value;
|
|||
|
|
if (!hadKey) {
|
|||
|
|
triggerPropsValue(instance, key, value);
|
|||
|
|
triggerPropsValue(instance, ATTR_KEYS);
|
|||
|
|
} else if (hasChanged(value, oldValue)) triggerPropsValue(instance, key, value, oldValue);
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/dom/event.ts
|
|||
|
|
function addEventListener(el, event, handler, options) {
|
|||
|
|
el.addEventListener(event, handler, options);
|
|||
|
|
return () => el.removeEventListener(event, handler, options);
|
|||
|
|
}
|
|||
|
|
function on(el, event, handler, options) {
|
|||
|
|
if (isArray(handler)) handler.forEach((fn) => on(el, event, fn, options));
|
|||
|
|
else {
|
|||
|
|
if (!handler) return;
|
|||
|
|
el.addEventListener(event, createInvoker(handler), options);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function onBinding(el, event, handler, options) {
|
|||
|
|
if (isArray(handler)) {
|
|||
|
|
handler.forEach((fn) => onBinding(el, event, fn, options));
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (!handler) return;
|
|||
|
|
if (options && options.once) {
|
|||
|
|
const firedKey = `$evtonce_${options.capture ? 1 : 0}_${event}`;
|
|||
|
|
if (el[firedKey]) return;
|
|||
|
|
const invoker = handler;
|
|||
|
|
handler = (...args) => {
|
|||
|
|
el[firedKey] = true;
|
|||
|
|
return invoker(...args);
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
const cleanup = addEventListener(el, event, createInvoker(handler), options);
|
|||
|
|
onEffectCleanup(cleanup);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* A dynamic listener keeps one native listener per key across effect re-runs,
|
|||
|
|
* like a vdom invoker. A root's own `on*` binding and the fallthrough one are
|
|||
|
|
* two layers of it: the own handlers run first, then the fallthrough ones not
|
|||
|
|
* already among them, so re-binding either layer keeps that order. #15635
|
|||
|
|
*/
|
|||
|
|
function setListener(el, key, value) {
|
|||
|
|
const invokers = el.$vei || (el.$vei = {});
|
|||
|
|
const invoker = invokers[key] || (invokers[key] = {
|
|||
|
|
own: null,
|
|||
|
|
attrs: null,
|
|||
|
|
handlers: null,
|
|||
|
|
remove: void 0,
|
|||
|
|
fired: false
|
|||
|
|
});
|
|||
|
|
const layer = isApplyingFallthroughProps ? "attrs" : "own";
|
|||
|
|
invoker[layer] = value;
|
|||
|
|
if (composeHandlers(invoker).length) {
|
|||
|
|
if (!invoker.remove && !invoker.fired) attachInvoker(el, key, invoker);
|
|||
|
|
} else if (invoker.remove) {
|
|||
|
|
invoker.remove();
|
|||
|
|
invoker.remove = void 0;
|
|||
|
|
}
|
|||
|
|
onEffectCleanup(() => {
|
|||
|
|
invoker[layer] = null;
|
|||
|
|
invoker.handlers = null;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
function composeHandlers(invoker) {
|
|||
|
|
const { own, attrs } = invoker;
|
|||
|
|
const handlers = invoker.handlers = [];
|
|||
|
|
if (isArray(own)) {
|
|||
|
|
for (const fn of own) if (fn) handlers.push(fn);
|
|||
|
|
} else if (own) handlers.push(own);
|
|||
|
|
if (attrs) {
|
|||
|
|
const ownCount = handlers.length;
|
|||
|
|
for (const fn of isArray(attrs) ? attrs : [attrs]) if (fn) {
|
|||
|
|
const at = handlers.indexOf(fn);
|
|||
|
|
if (at < 0 || at >= ownCount) handlers.push(fn);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return handlers;
|
|||
|
|
}
|
|||
|
|
function attachInvoker(el, key, invoker) {
|
|||
|
|
const [event, options] = parseEventName(key);
|
|||
|
|
const once = !!options && options.once;
|
|||
|
|
const i = currentInstance;
|
|||
|
|
invoker.remove = addEventListener(el, event, (e) => {
|
|||
|
|
if (once) invoker.fired = true;
|
|||
|
|
const handlers = invoker.handlers || composeHandlers(invoker);
|
|||
|
|
if (handlers.length > 1) {
|
|||
|
|
const originalStop = e.stopImmediatePropagation;
|
|||
|
|
e.stopImmediatePropagation = () => {
|
|||
|
|
originalStop.call(e);
|
|||
|
|
e._stopped = true;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
const args = [e];
|
|||
|
|
for (const handler of handlers) {
|
|||
|
|
if (e._stopped) break;
|
|||
|
|
callWithAsyncErrorHandling(handler, i, 5, args);
|
|||
|
|
}
|
|||
|
|
}, options);
|
|||
|
|
}
|
|||
|
|
function delegate(el, event, handler) {
|
|||
|
|
const key = `$evt${event}`;
|
|||
|
|
const existing = el[key];
|
|||
|
|
const invoker = createInvoker(handler);
|
|||
|
|
if (existing) {
|
|||
|
|
if (isArray(existing)) existing.push(invoker);
|
|||
|
|
else el[key] = [existing, invoker];
|
|||
|
|
} else el[key] = invoker;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Event delegation borrowed from solid
|
|||
|
|
*/
|
|||
|
|
const delegatedEvents = /*@__PURE__*/ Object.create(null);
|
|||
|
|
const delegateEvents = (...names) => {
|
|||
|
|
for (const name of names) if (!delegatedEvents[name]) {
|
|||
|
|
delegatedEvents[name] = true;
|
|||
|
|
document.addEventListener(name, delegatedEventHandler);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
const delegatedEventHandler = (e) => {
|
|||
|
|
let node = e.composedPath && e.composedPath()[0] || e.target;
|
|||
|
|
if (e.target !== node) Object.defineProperty(e, "target", {
|
|||
|
|
configurable: true,
|
|||
|
|
value: node
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(e, "currentTarget", {
|
|||
|
|
configurable: true,
|
|||
|
|
get() {
|
|||
|
|
return node || document;
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
while (node !== null) {
|
|||
|
|
const handlers = node[`$evt${e.type}`];
|
|||
|
|
if (handlers) {
|
|||
|
|
if (isArray(handlers)) {
|
|||
|
|
for (const handler of handlers) if (!node.disabled) {
|
|||
|
|
handler(e);
|
|||
|
|
if (e.cancelBubble) return;
|
|||
|
|
}
|
|||
|
|
} else if (!node.disabled) {
|
|||
|
|
handlers(e);
|
|||
|
|
if (e.cancelBubble) return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
node = node.host && node.host !== node && node.host instanceof Node ? node.host : node.parentNode;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
function withVaporModifiers(fn, modifiers) {
|
|||
|
|
return createInvoker(typeof fn === "function" ? withModifiers(fn, modifiers) : fn);
|
|||
|
|
}
|
|||
|
|
function withVaporKeys(fn, modifiers) {
|
|||
|
|
return createInvoker(typeof fn === "function" ? withKeys(fn, modifiers) : fn);
|
|||
|
|
}
|
|||
|
|
function createInvoker(handler) {
|
|||
|
|
const i = currentInstance;
|
|||
|
|
return (...args) => callWithAsyncErrorHandling(handler, i, 5, args);
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/transition.ts
|
|||
|
|
let applyTransitionHooks;
|
|||
|
|
let applyTransitionLeaveHooks;
|
|||
|
|
let deferBranchUpdateDuringLeave;
|
|||
|
|
let removeBranchWithLeave;
|
|||
|
|
let isTransitionEnabled = false;
|
|||
|
|
function registerTransitionHooks(applyHooks, applyLeaveHooks, deferBranchUpdate, removeBranch) {
|
|||
|
|
isTransitionEnabled = true;
|
|||
|
|
applyTransitionHooks = applyHooks;
|
|||
|
|
applyTransitionLeaveHooks = applyLeaveHooks;
|
|||
|
|
deferBranchUpdateDuringLeave = deferBranchUpdate;
|
|||
|
|
removeBranchWithLeave = removeBranch;
|
|||
|
|
}
|
|||
|
|
const displayName = "VaporTransition";
|
|||
|
|
function isVaporTransition(component) {
|
|||
|
|
return component.displayName === displayName;
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/dom/prop.ts
|
|||
|
|
const shouldSkipFallthroughKey = (el, key) => {
|
|||
|
|
const instance = currentInstance;
|
|||
|
|
return !isApplyingFallthroughProps && el.$root && instance.hasFallthrough && instance.type.inheritAttrs !== false && key in instance.attrs && (!shouldUseFunctionalFallthrough(instance.type) || isFunctionalFallthroughKey(key));
|
|||
|
|
};
|
|||
|
|
function setProp(el, key, value) {
|
|||
|
|
if (key in el) setDOMProp(el, key, value);
|
|||
|
|
else setAttr(el, key, value);
|
|||
|
|
}
|
|||
|
|
function setAttr(el, key, value, isSVG = false, forceHydrate = true) {
|
|||
|
|
if (shouldSkipFallthroughKey(el, key)) return;
|
|||
|
|
if (key === "true-value") el._trueValue = value;
|
|||
|
|
else if (key === "false-value") el._falseValue = value;
|
|||
|
|
if (isHydrating$1 && !isRecreatedNode(el)) {
|
|||
|
|
(process.env.NODE_ENV !== "production" || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && attributeHasMismatch(el, key, value);
|
|||
|
|
if (skipHydratedWrite(el, key, value, forceHydrate)) {
|
|||
|
|
el[`$${key}`] = value;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (value !== el[`$${key}`]) {
|
|||
|
|
el[`$${key}`] = value;
|
|||
|
|
if (isSVG && key.startsWith("xlink:")) {
|
|||
|
|
if (value != null) el.setAttributeNS(xlinkNS, key, value);
|
|||
|
|
else el.removeAttributeNS(xlinkNS, key.slice(6, key.length));
|
|||
|
|
} else {
|
|||
|
|
const isBoolean = isSpecialBooleanAttr(key);
|
|||
|
|
if (value == null || isBoolean && !includeBooleanAttr(value)) el.removeAttribute(key);
|
|||
|
|
else el.setAttribute(key, isBoolean ? "" : isSymbol(value) ? String(value) : value);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function setDOMProp(el, key, value, forceHydrate = true, attrName) {
|
|||
|
|
if (shouldSkipFallthroughKey(el, key)) return;
|
|||
|
|
const cacheKey = `$p$${key}`;
|
|||
|
|
if (isHydrating$1 && !isRecreatedNode(el)) {
|
|||
|
|
(process.env.NODE_ENV !== "production" || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && attributeHasMismatch(el, key, value);
|
|||
|
|
if (skipHydratedWrite(el, key, value, forceHydrate)) {
|
|||
|
|
el[cacheKey] = value;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (value === el[cacheKey] && cacheKey in el) return;
|
|||
|
|
el[cacheKey] = value;
|
|||
|
|
let needRemove = false;
|
|||
|
|
if (value === "" || value == null) {
|
|||
|
|
const type = typeof el[key];
|
|||
|
|
if (type === "boolean") value = includeBooleanAttr(value);
|
|||
|
|
else if (value == null && type === "string") {
|
|||
|
|
value = "";
|
|||
|
|
needRemove = true;
|
|||
|
|
} else if (type === "number") {
|
|||
|
|
value = 0;
|
|||
|
|
needRemove = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
try {
|
|||
|
|
el[key] = value;
|
|||
|
|
} catch (e) {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && !needRemove) warn(`Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: value ${value} is invalid.`, e);
|
|||
|
|
}
|
|||
|
|
needRemove && el.removeAttribute(attrName || key);
|
|||
|
|
if ((key === "checked" || key === "selected") && !el.tagName.includes("-")) includeBooleanAttr(value) ? el.setAttribute(key, "") : el.removeAttribute(key);
|
|||
|
|
}
|
|||
|
|
function setClass(el, value, isSVG = false, isNormalized = false) {
|
|||
|
|
if (el.$clsFlags !== void 0) el.$clsFlags = void 0;
|
|||
|
|
if (el.$root) setClassIncremental(el, value, isNormalized);
|
|||
|
|
else {
|
|||
|
|
if (!isNormalized) value = normalizeClass(value);
|
|||
|
|
if (isHydrating$1 && !isRecreatedNode(el)) {
|
|||
|
|
(process.env.NODE_ENV !== "production" || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && classHasMismatch(el, value, false);
|
|||
|
|
el.$cls = value;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (value !== el.$cls) {
|
|||
|
|
el.$cls = value;
|
|||
|
|
if (isTransitionEnabled) patchClass(el, value, isSVG);
|
|||
|
|
else if (isSVG) el.setAttribute("class", value);
|
|||
|
|
else el.className = value;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function setClassName(el, flags, cls, prefix = "", suffix = "") {
|
|||
|
|
if (flags === el.$clsFlags) return;
|
|||
|
|
let value = prefix;
|
|||
|
|
if (isString(cls)) {
|
|||
|
|
if (flags & 1) value += cls;
|
|||
|
|
} else for (let i = 0, bit = 1; i < cls.length; i++, bit <<= 1) if (flags & bit) value += cls[i];
|
|||
|
|
if (!prefix && value.charCodeAt(0) === 32) value = value.slice(1);
|
|||
|
|
if (suffix) value = value ? `${value} ${suffix}` : suffix;
|
|||
|
|
if (el.$root || isHydrating$1) setClass(el, value, false, true);
|
|||
|
|
else {
|
|||
|
|
el.$cls = value;
|
|||
|
|
if (isTransitionEnabled) patchClass(el, value, false);
|
|||
|
|
else el.className = value;
|
|||
|
|
}
|
|||
|
|
el.$clsFlags = flags;
|
|||
|
|
}
|
|||
|
|
function setClassIncremental(el, value, isNormalized = false) {
|
|||
|
|
const cacheKey = isApplyingFallthroughProps ? "$clsi$" : "$clsi";
|
|||
|
|
const normalizedValue = isNormalized ? value : normalizeClass(value);
|
|||
|
|
if (isHydrating$1 && !isRecreatedNode(el)) {
|
|||
|
|
(process.env.NODE_ENV !== "production" || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && classHasMismatch(el, normalizedValue, true);
|
|||
|
|
el[cacheKey] = normalizedValue;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
const prev = el[cacheKey];
|
|||
|
|
if ((value = el[cacheKey] = normalizedValue) !== prev) {
|
|||
|
|
const nextList = value.split(/\s+/);
|
|||
|
|
if (value) el.classList.add(...nextList);
|
|||
|
|
if (prev) {
|
|||
|
|
let kept;
|
|||
|
|
for (const cls of prev.split(/\s+/)) if (!nextList.includes(cls) && !(kept || (kept = keptClasses(el))).includes(cls)) el.classList.remove(cls);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function keptClasses(el) {
|
|||
|
|
const other = isApplyingFallthroughProps ? el.$clsi : el.$clsi$;
|
|||
|
|
return other !== void 0 ? other.split(/\s+/) : el.$root.cls || EMPTY_ARR;
|
|||
|
|
}
|
|||
|
|
function shouldDeferCheckStyleMismatch(el) {
|
|||
|
|
return hasCssVarsInOwnerChain(currentInstance) || hasCssVars(el.style);
|
|||
|
|
}
|
|||
|
|
function hasCssVarsInOwnerChain(instance) {
|
|||
|
|
while (instance) {
|
|||
|
|
if (instance.getCssVars) return true;
|
|||
|
|
instance = instance.parent;
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
function hasCssVars(style) {
|
|||
|
|
for (let i = 0; i < style.length; i++) if (style.item(i).startsWith("--")) return true;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
function checkHydrationStyleMismatch(el, value, normalizedValue, isIncremental) {
|
|||
|
|
if (shouldDeferCheckStyleMismatch(el)) {
|
|||
|
|
const instance = currentInstance;
|
|||
|
|
queuePostFlushCb(() => {
|
|||
|
|
styleHasMismatch(el, value, normalizedValue, isIncremental, instance);
|
|||
|
|
});
|
|||
|
|
} else styleHasMismatch(el, value, normalizedValue, isIncremental);
|
|||
|
|
}
|
|||
|
|
function setStyle(el, value) {
|
|||
|
|
if (isHydrating$1 && isReactive(value)) for (const key in value) value[key];
|
|||
|
|
if (el.$root) setStyleIncremental(el, value);
|
|||
|
|
else {
|
|||
|
|
const normalizedValue = normalizeStyle(value);
|
|||
|
|
if (isHydrating$1 && !isRecreatedNode(el)) {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) checkHydrationStyleMismatch(el, value, normalizedValue, false);
|
|||
|
|
el.$sty = normalizedValue;
|
|||
|
|
hydrateVShowDisplay(el, normalizedValue);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
patchStyle(el, el.$sty, el.$sty = normalizedValue);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function setStyleIncremental(el, value) {
|
|||
|
|
const normalizedValue = isString(value) ? parseStringStyle(value) : normalizeStyle(value);
|
|||
|
|
el[isApplyingFallthroughProps ? "$styi$" : "$styi"] = normalizedValue;
|
|||
|
|
let next = normalizedValue;
|
|||
|
|
if ("$styi$" in el) {
|
|||
|
|
const base = el.$styi !== void 0 ? el.$styi : el.$root.sty;
|
|||
|
|
next = base ? extend$1({}, base, el.$styi$) : el.$styi$ || {};
|
|||
|
|
}
|
|||
|
|
if (isHydrating$1 && !isRecreatedNode(el)) {
|
|||
|
|
if ((!!(process.env.NODE_ENV !== "production") || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && !shouldSkipFallthroughKey(el, "style")) checkHydrationStyleMismatch(el, next, next, true);
|
|||
|
|
el.$sty = next;
|
|||
|
|
hydrateVShowDisplay(el, next);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
patchStyle(el, el.$sty, el.$sty = next);
|
|||
|
|
}
|
|||
|
|
function hydrateVShowDisplay(el, style) {
|
|||
|
|
if (vShowOriginalDisplay in el) {
|
|||
|
|
let display = isString(style) ? parseStringStyle(style).display : style && style.display;
|
|||
|
|
if (isArray(display)) display = display[display.length - 1];
|
|||
|
|
el[vShowOriginalDisplay] = display == null ? "" : String(display).replace(/\s*!important$/, "");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function setValue(el, value, forceHydrate = true) {
|
|||
|
|
if (shouldSkipFallthroughKey(el, "value")) return;
|
|||
|
|
el._value = value;
|
|||
|
|
if (isHydrating$1 && !isRecreatedNode(el)) {
|
|||
|
|
(process.env.NODE_ENV !== "production" || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && attributeHasMismatch(el, "value", isString(value) ? getClientText(el, value) : value);
|
|||
|
|
if (skipHydratedWrite(el, "value", value, forceHydrate)) return;
|
|||
|
|
}
|
|||
|
|
const oldValue = el.tagName === "OPTION" ? el.getAttribute("value") : el.value;
|
|||
|
|
const newValue = value == null ? "" : value;
|
|||
|
|
if (oldValue !== newValue) el.value = newValue;
|
|||
|
|
if (value == null) el.removeAttribute("value");
|
|||
|
|
else el.setAttribute("value", isSymbol(newValue) ? String(newValue) : newValue);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Only called on text nodes!
|
|||
|
|
* Compiler should also ensure value passed here is already converted by
|
|||
|
|
* `toDisplayString`
|
|||
|
|
*/
|
|||
|
|
function setText(el, value) {
|
|||
|
|
if (isHydrating$1 && !isRecreatedNode(el) && !isRecreatedNode(el.parentNode)) {
|
|||
|
|
const clientText = getClientText(el.parentNode, value);
|
|||
|
|
if (el.nodeValue == clientText) {
|
|||
|
|
el.$txt = clientText;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
const parent = el.parentElement;
|
|||
|
|
if (parent && !isMismatchAllowed(parent, 0)) {
|
|||
|
|
(process.env.NODE_ENV !== "production" || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && warnHydrationTextMismatch(el, value);
|
|||
|
|
logMismatchError();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (el.$txt !== value) el.nodeValue = el.$txt = value;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Used by setDynamicProps and `textContent` bindings, so need to guard with
|
|||
|
|
* `toDisplayString`
|
|||
|
|
*/
|
|||
|
|
function setElementText(el, value, forceHydrate = true) {
|
|||
|
|
value = toDisplayString(value);
|
|||
|
|
if (isHydrating$1 && !isRecreatedNode(el)) {
|
|||
|
|
let clientText = getClientText(el, value);
|
|||
|
|
if (el.textContent === clientText) {
|
|||
|
|
el.$txt = clientText;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (!isMismatchAllowed(el, 0)) {
|
|||
|
|
(process.env.NODE_ENV !== "production" || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && warn(`Hydration text content mismatch on`, el, `\n - rendered on server: ${el.textContent}\n - expected on client: ${clientText}`);
|
|||
|
|
logMismatchError();
|
|||
|
|
}
|
|||
|
|
if (skipHydratedWrite(el, "textContent", value, forceHydrate)) {
|
|||
|
|
el.$txt = value;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (el.$txt !== value) el.textContent = el.$txt = value;
|
|||
|
|
}
|
|||
|
|
function setHtml(el, value, forceHydrate = true) {
|
|||
|
|
value = value == null ? "" : unsafeToTrustedHTML(value);
|
|||
|
|
if (isHydrating$1 && !isRecreatedNode(el) && skipHydratedWrite(el, "innerHTML", value, forceHydrate)) {
|
|||
|
|
el.$html = value;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (el.$html !== value) el.innerHTML = el.$html = value;
|
|||
|
|
}
|
|||
|
|
function setDynamicProps(el, args, staticKeys, isSVG) {
|
|||
|
|
patchDynamicProps(el, args.length > 1 ? mergeProps(...args) : args[0] || EMPTY_OBJ, isSVG, staticKeys);
|
|||
|
|
}
|
|||
|
|
function setDynamicEvents(el, events) {
|
|||
|
|
patchDynamicProps(el, toHandlers(events, true));
|
|||
|
|
}
|
|||
|
|
function patchDynamicProps(el, props, isSVG, staticKeys) {
|
|||
|
|
const cacheKey = `$dprops${isApplyingFallthroughProps ? "$" : ""}`;
|
|||
|
|
const prevProps = el[cacheKey];
|
|||
|
|
const nextProps = Object.create(null);
|
|||
|
|
if (prevProps) {
|
|||
|
|
for (const key in prevProps) if (!(key in props)) setDynamicProp(el, key, null, isSVG);
|
|||
|
|
}
|
|||
|
|
const hydratedKeys = isHydrating$1 ? staticKeys : void 0;
|
|||
|
|
for (const key of Object.keys(props)) {
|
|||
|
|
if (isReservedProp(key)) continue;
|
|||
|
|
const value = props[key];
|
|||
|
|
nextProps[key] = value;
|
|||
|
|
if (prevProps && key in prevProps && !isOn(key) && (value == null || typeof value !== "object") && Object.is(prevProps[key], value)) continue;
|
|||
|
|
setDynamicProp(el, key, value, isSVG, hydratedKeys && hydratedKeys.includes(key));
|
|||
|
|
}
|
|||
|
|
el[cacheKey] = nextProps;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* @internal
|
|||
|
|
*/
|
|||
|
|
function setDynamicProp(el, key, value, isSVG = false, forceHydrate = false) {
|
|||
|
|
if (key === "class") setClass(el, value, isSVG);
|
|||
|
|
else if (key === "style") setStyle(el, value);
|
|||
|
|
else if (isOn(key)) setListener(el, key, value);
|
|||
|
|
else if (key[0] === "." ? (key = key.slice(1), forceHydrate = true) : key[0] === "^" ? (key = key.slice(1), false) : shouldSetAsProp(el, key, value, isSVG)) {
|
|||
|
|
if (key === "innerHTML") setHtml(el, value, forceHydrate);
|
|||
|
|
else if (key === "textContent") setElementText(el, value, forceHydrate);
|
|||
|
|
else if (key === "value" && canSetValueDirectly(el.tagName)) setValue(el, value, forceHydrate);
|
|||
|
|
else setDOMProp(el, key, value, forceHydrate);
|
|||
|
|
} else if (el._isVueCE && (shouldSetAsPropForVueCE(el, key) || el._def.__asyncLoader && (/[A-Z]/.test(key) || !isString(value)))) setDOMProp(el, camelize(key), value, forceHydrate, key);
|
|||
|
|
else setAttr(el, key, value, isSVG, forceHydrate);
|
|||
|
|
return value;
|
|||
|
|
}
|
|||
|
|
let isOptimized = false;
|
|||
|
|
/**
|
|||
|
|
* Optimize property lookup for cache properties on Element and Text nodes
|
|||
|
|
*/
|
|||
|
|
function optimizePropertyLookup() {
|
|||
|
|
if (isOptimized) return;
|
|||
|
|
isOptimized = true;
|
|||
|
|
const proto = Element.prototype;
|
|||
|
|
proto.$transition = void 0;
|
|||
|
|
proto.$key = void 0;
|
|||
|
|
proto.$evtclick = void 0;
|
|||
|
|
proto.$vei = void 0;
|
|||
|
|
proto.$root = false;
|
|||
|
|
proto.$clsFlags = void 0;
|
|||
|
|
proto.$cls = proto.$sty = "";
|
|||
|
|
proto.$html = void 0;
|
|||
|
|
Text.prototype.$txt = void 0;
|
|||
|
|
}
|
|||
|
|
function classHasMismatch(el, expected, isIncremental) {
|
|||
|
|
const actual = el.getAttribute("class");
|
|||
|
|
const actualClassSet = toClassSet(actual || "");
|
|||
|
|
const expectedClassSet = toClassSet(expected);
|
|||
|
|
let hasMismatch = false;
|
|||
|
|
if (isIncremental) {
|
|||
|
|
if (expected) hasMismatch = Array.from(expectedClassSet).some((cls) => !actualClassSet.has(cls));
|
|||
|
|
} else hasMismatch = !isSetEqual(actualClassSet, expectedClassSet);
|
|||
|
|
if (hasMismatch) {
|
|||
|
|
if (warnPropMismatch(el, "class", 2, actual, expected)) {
|
|||
|
|
logMismatchError();
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
function styleHasMismatch(el, value, normalizedValue, isIncremental, instance = currentInstance) {
|
|||
|
|
const actual = el.getAttribute("style");
|
|||
|
|
const actualStyleMap = toStyleMap(actual || "");
|
|||
|
|
const expected = isString(value) ? value : stringifyStyle(normalizedValue);
|
|||
|
|
const expectedStyleMap = toStyleMap(expected);
|
|||
|
|
if (el[vShowHidden]) expectedStyleMap.set("display", "none");
|
|||
|
|
if (instance) resolveCssVars$1(instance, el, expectedStyleMap);
|
|||
|
|
let hasMismatch = false;
|
|||
|
|
if (isIncremental) {
|
|||
|
|
if (expected) hasMismatch = Array.from(expectedStyleMap.entries()).some(([key, val]) => actualStyleMap.get(key) !== val);
|
|||
|
|
} else hasMismatch = !isMapEqual(actualStyleMap, expectedStyleMap);
|
|||
|
|
if (hasMismatch) {
|
|||
|
|
if (warnPropMismatch(el, "style", 3, actual, expected)) {
|
|||
|
|
logMismatchError();
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* dev only
|
|||
|
|
*/
|
|||
|
|
function resolveCssVars$1(instance, block, expectedMap) {
|
|||
|
|
if (!instance.isMounted) return;
|
|||
|
|
const rootBlocks = normalizeBlock(instance);
|
|||
|
|
if (instance.getCssVars && normalizeBlock(block).every((b) => rootBlocks.includes(b))) {
|
|||
|
|
const cssVars = instance.getCssVars();
|
|||
|
|
for (const key in cssVars) {
|
|||
|
|
const value = normalizeCssVarValue(cssVars[key]);
|
|||
|
|
expectedMap.set(`--${getEscapedCssVarName(key, false)}`, value);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (normalizeBlock(block).every((b) => rootBlocks.includes(b)) && instance.parent) {
|
|||
|
|
if (isVaporComponent(instance.parent)) resolveCssVars$1(instance.parent, instance.block, expectedMap);
|
|||
|
|
else if (isInteropEnabled && instance.interopVNode) resolveCssVars(instance.parent, instance.interopVNode, expectedMap);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function attributeHasMismatch(el, key, value) {
|
|||
|
|
if (isValidHtmlOrSvgAttribute(el, key)) {
|
|||
|
|
const { actual, expected } = getAttributeMismatch(el, key, value);
|
|||
|
|
if (actual !== expected) {
|
|||
|
|
if (warnPropMismatch(el, key, 4, actual, expected)) {
|
|||
|
|
logMismatchError();
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
function getClientText(el, value) {
|
|||
|
|
if (value[0] === "\n" && (el.tagName === "PRE" || el.tagName === "TEXTAREA")) value = value.slice(1);
|
|||
|
|
return value;
|
|||
|
|
}
|
|||
|
|
function skipHydratedWrite(el, key, value, forceHydrate) {
|
|||
|
|
return !forceHydrate && !shouldForceHydrate(el, key) || isUnchangedResourceProp(el, key, value);
|
|||
|
|
}
|
|||
|
|
function shouldForceHydrate(el, key) {
|
|||
|
|
const { tagName } = el;
|
|||
|
|
return (tagName === "INPUT" || tagName === "OPTION") && (key.endsWith("value") || key === "indeterminate") || tagName.includes("-");
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/asyncComponentState.ts
|
|||
|
|
let isAsyncComponentEnabled = false;
|
|||
|
|
function enableAsyncComponent() {
|
|||
|
|
isAsyncComponentEnabled = true;
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/slotBoundary.ts
|
|||
|
|
function withSlotBoundary(boundary, fn) {
|
|||
|
|
return withRenderContext(deriveSlotBoundary(currentRenderContext, boundary), fn);
|
|||
|
|
}
|
|||
|
|
function trackSlotBoundaryDirtying(fragment, onInvalid) {
|
|||
|
|
const boundary = currentRenderContext.slotBoundary;
|
|||
|
|
if (!boundary) return;
|
|||
|
|
if (onInvalid) registerContentInvalid(boundary, onInvalid, fragment);
|
|||
|
|
let prevValid;
|
|||
|
|
(fragment.bu || (fragment.bu = [])).push(() => {
|
|||
|
|
prevValid = isValidSlot(fragment);
|
|||
|
|
});
|
|||
|
|
(fragment.u || (fragment.u = [])).push(() => {
|
|||
|
|
if (isValidSlot(fragment) !== prevValid) boundary.markDirty();
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
function registerContentInvalid(boundary, onInvalid, fragment) {
|
|||
|
|
const callbacks = boundary.onContentInvalid || (boundary.onContentInvalid = []);
|
|||
|
|
callbacks.push(onInvalid);
|
|||
|
|
const unregister = () => {
|
|||
|
|
const index = callbacks.indexOf(onInvalid);
|
|||
|
|
if (index > -1) callbacks.splice(index, 1);
|
|||
|
|
};
|
|||
|
|
(fragment.bum || (fragment.bum = [])).push(unregister);
|
|||
|
|
}
|
|||
|
|
function hasSlotFallback(boundary) {
|
|||
|
|
while (boundary) {
|
|||
|
|
if (boundary.getFallback()) return true;
|
|||
|
|
boundary = boundary.getParent();
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/helpers/setKey.ts
|
|||
|
|
function setBlockKey(block, key) {
|
|||
|
|
const frag = block;
|
|||
|
|
frag.$key = key;
|
|||
|
|
if (isInteropEnabled && frag.setKey) frag.setKey(key);
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region \0@oxc-project+runtime@0.146.0/helpers/esm/typeof.js
|
|||
|
|
function _typeof(o) {
|
|||
|
|
"@babel/helpers - typeof";
|
|||
|
|
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|||
|
|
return typeof o;
|
|||
|
|
} : function(o) {
|
|||
|
|
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|||
|
|
}, _typeof(o);
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region \0@oxc-project+runtime@0.146.0/helpers/esm/toPrimitive.js
|
|||
|
|
function toPrimitive(t, r) {
|
|||
|
|
if ("object" != _typeof(t) || !t) return t;
|
|||
|
|
var e = t[Symbol.toPrimitive];
|
|||
|
|
if (void 0 !== e) {
|
|||
|
|
var i = e.call(t, r || "default");
|
|||
|
|
if ("object" != _typeof(i)) return i;
|
|||
|
|
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|||
|
|
}
|
|||
|
|
return ("string" === r ? String : Number)(t);
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region \0@oxc-project+runtime@0.146.0/helpers/esm/toPropertyKey.js
|
|||
|
|
function toPropertyKey(t) {
|
|||
|
|
var i = toPrimitive(t, "string");
|
|||
|
|
return "symbol" == _typeof(i) ? i : i + "";
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region \0@oxc-project+runtime@0.146.0/helpers/esm/defineProperty.js
|
|||
|
|
function _defineProperty(e, r, t) {
|
|||
|
|
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|||
|
|
value: t,
|
|||
|
|
enumerable: !0,
|
|||
|
|
configurable: !0,
|
|||
|
|
writable: !0
|
|||
|
|
}) : e[r] = t, e;
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region \0@oxc-project+runtime@0.146.0/helpers/esm/objectSpread2.js
|
|||
|
|
function ownKeys(e, r) {
|
|||
|
|
var t = Object.keys(e);
|
|||
|
|
if (Object.getOwnPropertySymbols) {
|
|||
|
|
var o = Object.getOwnPropertySymbols(e);
|
|||
|
|
r && (o = o.filter(function(r) {
|
|||
|
|
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
|||
|
|
})), t.push.apply(t, o);
|
|||
|
|
}
|
|||
|
|
return t;
|
|||
|
|
}
|
|||
|
|
function _objectSpread2(e) {
|
|||
|
|
for (var r = 1; r < arguments.length; r++) {
|
|||
|
|
var t = null != arguments[r] ? arguments[r] : {};
|
|||
|
|
r % 2 ? ownKeys(Object(t), !0).forEach(function(r) {
|
|||
|
|
_defineProperty(e, r, t[r]);
|
|||
|
|
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r) {
|
|||
|
|
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
return e;
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/slotFragment.ts
|
|||
|
|
function renderSlotFallback(boundary, scope) {
|
|||
|
|
let result;
|
|||
|
|
while (boundary) {
|
|||
|
|
const current = boundary;
|
|||
|
|
const localFallback = current.getFallback();
|
|||
|
|
if (localFallback) {
|
|||
|
|
let selected = false;
|
|||
|
|
const onContentInvalid = [];
|
|||
|
|
const getScopeIds = current.getScopeIds;
|
|||
|
|
const render = getScopeIds ? () => renderWithSlotScopeIds(getScopeIds(), localFallback) : localFallback;
|
|||
|
|
const adopt = isHydratingSlotFallback && current.adoptFallback;
|
|||
|
|
if (adopt) current.adoptFallback = void 0;
|
|||
|
|
const renderFallback = adopt ? () => adopt(render) : render;
|
|||
|
|
const content = current.run(() => withSlotBoundary(_objectSpread2(_objectSpread2({}, current), {}, {
|
|||
|
|
getFallback: () => void 0,
|
|||
|
|
onContentInvalid,
|
|||
|
|
markDirty: (force) => current.markDirty(!!force || !selected && hasSlotFallback(current.getParent()))
|
|||
|
|
}), renderFallback), scope);
|
|||
|
|
if (isValidSlot(content)) {
|
|||
|
|
selected = true;
|
|||
|
|
return {
|
|||
|
|
block: content,
|
|||
|
|
onContentInvalid,
|
|||
|
|
adopted: !!adopt
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
result = {
|
|||
|
|
block: content,
|
|||
|
|
onContentInvalid,
|
|||
|
|
adopted: !!adopt
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
boundary = current.getParent();
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
function beforeExpose(state, block) {
|
|||
|
|
const bm = state.bm;
|
|||
|
|
if (bm) for (let i = 0; i < bm.length; i++) bm[i](block);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* The winning exposed branch for a slot host: the committed fallback while one
|
|||
|
|
* is active, the resolved content otherwise. Every host's `syncNodes` points
|
|||
|
|
* its exposed nodes here.
|
|||
|
|
*/
|
|||
|
|
function resolveExposedSlotNodes(state) {
|
|||
|
|
return state.activeFallback || state.getContent();
|
|||
|
|
}
|
|||
|
|
function markSlotResolutionDirty(state, force = false) {
|
|||
|
|
if (state.isDisposed()) return;
|
|||
|
|
if (state.isReconciling || state.isBusy()) {
|
|||
|
|
state.pendingRecheck = true;
|
|||
|
|
state.pendingRecheckForce = state.pendingRecheckForce || force;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
recheckSlotResolution(state, force);
|
|||
|
|
}
|
|||
|
|
function invalidateExposedSlotContent(state) {
|
|||
|
|
const callbacks = state.activeFallback ? state.activeFallbackInvalidCallbacks : state.boundary.onContentInvalid;
|
|||
|
|
if (callbacks) for (let i = 0; i < callbacks.length; i++) callbacks[i]();
|
|||
|
|
}
|
|||
|
|
function clearSlotFallback(state, parentNode = state.getParentNode()) {
|
|||
|
|
if (state.fallbackScope) {
|
|||
|
|
state.fallbackScope.stop();
|
|||
|
|
state.fallbackScope = void 0;
|
|||
|
|
}
|
|||
|
|
const fallback = state.activeFallback;
|
|||
|
|
if (fallback) {
|
|||
|
|
remove(fallback, state.fallbackInserted ? parentNode || void 0 : void 0);
|
|||
|
|
state.activeFallback = null;
|
|||
|
|
state.fallbackInserted = false;
|
|||
|
|
}
|
|||
|
|
state.activeFallbackInvalidCallbacks = void 0;
|
|||
|
|
}
|
|||
|
|
function leaveSlotFallback(state, hooks, afterLeave) {
|
|||
|
|
const fallback = state.activeFallback;
|
|||
|
|
if (!fallback || !applyTransitionLeaveHooks(fallback, hooks, afterLeave)) return false;
|
|||
|
|
clearSlotFallback(state);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
function renderFallbackInScope(state) {
|
|||
|
|
const scope = new EffectScope$1(true);
|
|||
|
|
let renderedFallback;
|
|||
|
|
try {
|
|||
|
|
renderedFallback = renderSlotFallback(state.boundary, scope);
|
|||
|
|
} catch (err) {
|
|||
|
|
scope.stop();
|
|||
|
|
throw err;
|
|||
|
|
}
|
|||
|
|
if (!renderedFallback) {
|
|||
|
|
scope.stop();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
return {
|
|||
|
|
block: renderedFallback.block,
|
|||
|
|
onContentInvalid: renderedFallback.onContentInvalid,
|
|||
|
|
adopted: renderedFallback.adopted,
|
|||
|
|
scope
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
function placeAdoptedFallback(state, parentNode, anchor) {
|
|||
|
|
if (!state.fallbackInserted) return false;
|
|||
|
|
const fallback = state.activeFallback;
|
|||
|
|
if (isInteropEnabled && isInteropFragment(fallback)) fallback.insert(parentNode, anchor);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
function insertActiveSlotFallback(state, moveType) {
|
|||
|
|
const fallback = state.activeFallback;
|
|||
|
|
if (isHydrating$1 || !fallback || !isValidSlot(fallback)) return;
|
|||
|
|
const parentNode = state.getParentNode();
|
|||
|
|
if (!parentNode || isHydratingSlotFallback && placeAdoptedFallback(state, parentNode, state.getAnchor())) return;
|
|||
|
|
if (moveType === void 0) insert(fallback, parentNode, state.getAnchor());
|
|||
|
|
else move(fallback, parentNode, state.getAnchor(), moveType);
|
|||
|
|
state.fallbackInserted = true;
|
|||
|
|
}
|
|||
|
|
function commitSlotFallback(state, block, scope, onContentInvalid, detachContent, adopted) {
|
|||
|
|
state.activeFallback = block;
|
|||
|
|
state.activeFallbackInvalidCallbacks = onContentInvalid;
|
|||
|
|
state.fallbackScope = scope;
|
|||
|
|
state.fallbackInserted = isHydrating$1 || adopted;
|
|||
|
|
if (isTransitionEnabled) {
|
|||
|
|
if (state.$transition) {
|
|||
|
|
if (!isArray(block)) setBlockKey(block, "_fb");
|
|||
|
|
state.$transition = applyTransitionHooks(block, state.$transition, ownerFragment(state));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (detachContent && !isHydrating$1) {
|
|||
|
|
const parentNode = state.getParentNode();
|
|||
|
|
const contentInvalidCallbacks = state.boundary.onContentInvalid;
|
|||
|
|
if (contentInvalidCallbacks) for (let i = 0; i < contentInvalidCallbacks.length; i++) contentInvalidCallbacks[i]();
|
|||
|
|
if (parentNode) removeAttachedNodes$1(state.getContent(), parentNode, false);
|
|||
|
|
}
|
|||
|
|
beforeExpose(state, block);
|
|||
|
|
insertActiveSlotFallback(state);
|
|||
|
|
}
|
|||
|
|
function ownerFragment(state) {
|
|||
|
|
const frag = state;
|
|||
|
|
return frag.__vf ? frag : void 0;
|
|||
|
|
}
|
|||
|
|
function renderAndCommitSlotFallback(state, hadFallback) {
|
|||
|
|
const result = renderFallbackInScope(state);
|
|||
|
|
clearSlotFallback(state);
|
|||
|
|
if (result) commitSlotFallback(state, result.block, result.scope, result.onContentInvalid, !hadFallback, result.adopted);
|
|||
|
|
}
|
|||
|
|
function disposeSlotResolution(state, parentNode) {
|
|||
|
|
clearSlotFallback(state, parentNode || null);
|
|||
|
|
state.pendingRecheck = false;
|
|||
|
|
state.pendingRecheckForce = false;
|
|||
|
|
state.lastNodesValid = void 0;
|
|||
|
|
}
|
|||
|
|
function recheckSlotResolution(state, force = false) {
|
|||
|
|
if (state.isReconciling) {
|
|||
|
|
state.pendingRecheck = true;
|
|||
|
|
state.pendingRecheckForce = state.pendingRecheckForce || force;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
let nextForce = force || state.pendingRecheckForce;
|
|||
|
|
do {
|
|||
|
|
state.pendingRecheck = false;
|
|||
|
|
state.pendingRecheckForce = false;
|
|||
|
|
state.isReconciling = true;
|
|||
|
|
try {
|
|||
|
|
recheckSlotResolutionNow(state, nextForce);
|
|||
|
|
} finally {
|
|||
|
|
state.isReconciling = false;
|
|||
|
|
}
|
|||
|
|
if (!state.pendingRecheck) return;
|
|||
|
|
nextForce = state.pendingRecheckForce;
|
|||
|
|
} while (true);
|
|||
|
|
}
|
|||
|
|
function recheckSlotResolutionNow(state, force) {
|
|||
|
|
var _state$lastNodesValid;
|
|||
|
|
const fallback = state.activeFallback;
|
|||
|
|
const fallbackValid = fallback ? isValidSlot(fallback) : false;
|
|||
|
|
const contentValid = state.isContentValid();
|
|||
|
|
const exposedValid = fallback ? fallbackValid : contentValid;
|
|||
|
|
const prevNodesValid = (_state$lastNodesValid = state.lastNodesValid) !== null && _state$lastNodesValid !== void 0 ? _state$lastNodesValid : exposedValid;
|
|||
|
|
if (!force && contentValid && !fallback && prevNodesValid) {
|
|||
|
|
state.syncNodes();
|
|||
|
|
state.lastNodesValid = true;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (contentValid || fallback && !hasSlotFallback(state.boundary)) {
|
|||
|
|
clearSlotFallback(state);
|
|||
|
|
if (fallback) {
|
|||
|
|
const content = state.getContent();
|
|||
|
|
beforeExpose(state, content);
|
|||
|
|
if (!isHydrating$1) {
|
|||
|
|
const parentNode = state.getParentNode();
|
|||
|
|
if (parentNode) insert(content, parentNode, state.getAnchor());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else if (fallback) {
|
|||
|
|
if (prevNodesValid) {
|
|||
|
|
if (!fallbackValid && hasSlotFallback(state.boundary.getParent())) renderAndCommitSlotFallback(state, true);
|
|||
|
|
else if (force && fallbackValid) renderAndCommitSlotFallback(state, true);
|
|||
|
|
} else if (fallbackValid) insertActiveSlotFallback(state);
|
|||
|
|
else if (force) renderAndCommitSlotFallback(state, true);
|
|||
|
|
} else renderAndCommitSlotFallback(state, false);
|
|||
|
|
const nextFallback = state.activeFallback;
|
|||
|
|
const nextNodesValid = contentValid && !nextFallback ? true : nextFallback ? nextFallback === fallback ? fallbackValid : isValidSlot(nextFallback) : state.isContentValid();
|
|||
|
|
state.syncNodes();
|
|||
|
|
state.lastNodesValid = nextNodesValid;
|
|||
|
|
if (prevNodesValid !== nextNodesValid) state.notifyExposedValidityChange();
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/dom/hydrateFragment.ts
|
|||
|
|
let currentSlotEndAnchor = null;
|
|||
|
|
/** Locates the boundary's SSR range and consumes its opening marker. */
|
|||
|
|
function withHydratingSlotBoundary(fn) {
|
|||
|
|
const claim = createFragmentClaim();
|
|||
|
|
locateHydrationNode(claim);
|
|||
|
|
const prev = currentSlotEndAnchor;
|
|||
|
|
const close = currentSlotEndAnchor = locateFragmentEnd(claim.start);
|
|||
|
|
try {
|
|||
|
|
return fn();
|
|||
|
|
} finally {
|
|||
|
|
currentSlotEndAnchor = prev;
|
|||
|
|
if (close) trimHydrationBoundary(close);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Insert an anchor at a position resolved during the hydration pass. Untracked
|
|||
|
|
* anchors hold no SSR logical position, so traversal steps over them and the
|
|||
|
|
* insert can happen right away. `nextNode` may already have been trimmed by
|
|||
|
|
* boundary cleanup, in which case the anchor is appended instead.
|
|||
|
|
*/
|
|||
|
|
function insertUntrackedAnchor(parentNode$1, nextNode, anchor) {
|
|||
|
|
parentNode$1.insertBefore(anchor, nextNode && /* @__PURE__ */ parentNode(nextNode) === parentNode$1 ? nextNode : null);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Whether `node` can serve as `frag`'s anchor. Beyond the SSR candidates
|
|||
|
|
* (`<!---->` and a fragment close), dev builds also accept a runtime anchor
|
|||
|
|
* this fragment kind already created: those carry the fragment's debug label
|
|||
|
|
* as their comment data, where prod uses unlabeled text nodes.
|
|||
|
|
*/
|
|||
|
|
function isReusableAnchorCandidate(node, frag) {
|
|||
|
|
return !!node && (isComment(node, "") || isRangeEnd(node) || !!(process.env.NODE_ENV !== "production") && frag !== void 0 && (frag.__vf & 256 && isComment(node, "v-if") || frag.anchorLabel !== void 0 && isComment(node, frag.anchorLabel)));
|
|||
|
|
}
|
|||
|
|
function reuseOrCreateAfterAnchor(node, resetNodes) {
|
|||
|
|
const parent = /* @__PURE__ */ parentNode(node);
|
|||
|
|
return isClaimedAnchor(node) && parent ? {
|
|||
|
|
kind: "create",
|
|||
|
|
parent,
|
|||
|
|
next: node.nextSibling,
|
|||
|
|
resetNodes
|
|||
|
|
} : {
|
|||
|
|
kind: "reuse",
|
|||
|
|
node,
|
|||
|
|
resetNodes
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
function prepareDeferredHydrationAnchor(frag, hasRender) {
|
|||
|
|
const isRevivingDeferredBranch = isInDeferredHydrationBoundary() && hasRender && !(frag.__vf & 4) && !isValidBlock(frag.nodes);
|
|||
|
|
const reusingDeferredAnchor = isRevivingDeferredBranch && !!frag.anchor && !!frag.anchor.parentNode;
|
|||
|
|
if (isRevivingDeferredBranch) {
|
|||
|
|
let slotEndAnchor = null;
|
|||
|
|
const anchor = frag.anchor || (currentHydrationNode === (slotEndAnchor = currentSlotEndAnchor) ? slotEndAnchor : null);
|
|||
|
|
if (anchor) setCurrentHydrationNode(claimAnchor(anchor));
|
|||
|
|
}
|
|||
|
|
return reusingDeferredAnchor;
|
|||
|
|
}
|
|||
|
|
/** Rule 1: adopt the anchor createPlainElement injected for native children. */
|
|||
|
|
function planReuseInjectedAnchor(frag) {
|
|||
|
|
if (frag.__vf & 512 && isClaimedAnchor(currentHydrationNode) && /* @__PURE__ */ parentNode(currentHydrationNode)) return {
|
|||
|
|
kind: "reuse",
|
|||
|
|
node: currentHydrationNode
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
/** Rule 2: the fragment owns an SSR range; its close marker is the anchor. */
|
|||
|
|
function planReuseOwnClose(frag) {
|
|||
|
|
const close = frag.__vf & 4 ? currentSlotEndAnchor : frag.hydrationClaim && frag.hydrationClaim.start ? locateClaimedEnd(frag.hydrationClaim.start) : null;
|
|||
|
|
if (close) return reuseOrCreateAfterAnchor(close);
|
|||
|
|
}
|
|||
|
|
/** Rule 3: the client rendered nothing and owns no range. */
|
|||
|
|
function planEmptyBranch(frag) {
|
|||
|
|
const flags = frag.__vf;
|
|||
|
|
if (isReusableAnchorCandidate(currentHydrationNode, frag)) return reuseOrCreateAfterAnchor(currentHydrationNode);
|
|||
|
|
if (!(flags & 512) && currentHydrationNode && isComment(currentHydrationNode, "teleport anchor")) {
|
|||
|
|
const parentNode$2 = /* @__PURE__ */ parentNode(currentHydrationNode);
|
|||
|
|
if (parentNode$2) return {
|
|||
|
|
kind: "create",
|
|||
|
|
parent: parentNode$2,
|
|||
|
|
next: currentHydrationNode,
|
|||
|
|
mark: currentHydrationNode
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
if (!(flags & 4) && currentHydrationNode && !isRangeEnd(currentHydrationNode)) {
|
|||
|
|
const parentNode$3 = /* @__PURE__ */ parentNode(currentHydrationNode);
|
|||
|
|
if (flags & 512 && parentNode$3) return {
|
|||
|
|
kind: "create-cleanup",
|
|||
|
|
parent: parentNode$3,
|
|||
|
|
next: null,
|
|||
|
|
cleanupStart: currentHydrationNode,
|
|||
|
|
cleanupUntil: null,
|
|||
|
|
cleanupContainer: parentNode$3
|
|||
|
|
};
|
|||
|
|
if (parentNode$3) {
|
|||
|
|
const anchor = nextLogicalSibling(currentHydrationNode);
|
|||
|
|
if (isReusableAnchorCandidate(anchor, frag) && /* @__PURE__ */ parentNode(anchor)) return reuseOrCreateAfterAnchor(anchor, true);
|
|||
|
|
return planTrimFromCursor(parentNode$3, anchor);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/** Trim the unclaimed SSR range at the cursor, then create a fresh anchor. */
|
|||
|
|
function planTrimFromCursor(parent, next) {
|
|||
|
|
return {
|
|||
|
|
kind: "create-cleanup",
|
|||
|
|
parent,
|
|||
|
|
next,
|
|||
|
|
cleanupStart: currentHydrationNode,
|
|||
|
|
cleanupUntil: next
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
/** Rule 4: the block is a bare runtime comment from earlier in this pass. */
|
|||
|
|
function planRestartFromRuntimeComment(frag) {
|
|||
|
|
if (isValidBlock(frag.nodes) || !(frag.nodes instanceof Comment)) return;
|
|||
|
|
if (isReusableAnchorCandidate(frag.nodes, frag) && /* @__PURE__ */ parentNode(frag.nodes)) return reuseOrCreateAfterAnchor(frag.nodes, true);
|
|||
|
|
if (!/* @__PURE__ */ parentNode(frag.nodes) && currentHydrationNode) {
|
|||
|
|
const parentNode$4 = /* @__PURE__ */ parentNode(currentHydrationNode);
|
|||
|
|
if (parentNode$4) return planTrimFromCursor(parentNode$4, nextLogicalSibling(currentHydrationNode));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/** Rule 5: derive the anchor position from the hydrated block itself. */
|
|||
|
|
function planFromBlockBoundary(frag) {
|
|||
|
|
const end = currentSlotEndAnchor;
|
|||
|
|
if (end && currentHydrationNode === end && !isValidBlock(frag.nodes)) return {
|
|||
|
|
kind: "create",
|
|||
|
|
parent: end.parentNode,
|
|||
|
|
next: end
|
|||
|
|
};
|
|||
|
|
const node = findBlockBoundary(frag.nodes);
|
|||
|
|
return {
|
|||
|
|
kind: "create",
|
|||
|
|
parent: node.parentNode,
|
|||
|
|
next: node.nextNode
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
function resolveDynamicAnchor(frag, isEmpty) {
|
|||
|
|
return planReuseInjectedAnchor(frag) || planReuseOwnClose(frag) || (isEmpty ? planEmptyBranch(frag) : void 0) || planRestartFromRuntimeComment(frag) || planFromBlockBoundary(frag);
|
|||
|
|
}
|
|||
|
|
function executeAnchorPlan(frag, plan) {
|
|||
|
|
let advanceAfterRestore = null;
|
|||
|
|
let exitHydrationBoundary;
|
|||
|
|
const createRuntimeAnchor = () => {
|
|||
|
|
var _frag$anchorLabel;
|
|||
|
|
return frag.anchor = claimUntrackedAnchor(!!(process.env.NODE_ENV !== "production") ? /* @__PURE__ */ createComment((_frag$anchorLabel = frag.anchorLabel) !== null && _frag$anchorLabel !== void 0 ? _frag$anchorLabel : "") : /* @__PURE__ */ createTextNode());
|
|||
|
|
};
|
|||
|
|
try {
|
|||
|
|
switch (plan.kind) {
|
|||
|
|
case "reuse":
|
|||
|
|
if (plan.resetNodes) frag.nodes = EMPTY_BLOCK;
|
|||
|
|
frag.anchor = claimAnchor(plan.node);
|
|||
|
|
if (currentHydrationNode === frag.anchor) advanceHydrationNode(frag.anchor);
|
|||
|
|
else {
|
|||
|
|
exitHydrationBoundary = enterHydrationBoundary(frag.anchor);
|
|||
|
|
advanceAfterRestore = frag.anchor;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case "create":
|
|||
|
|
if (plan.resetNodes) frag.nodes = EMPTY_BLOCK;
|
|||
|
|
if (plan.mark) claimAnchor(plan.mark);
|
|||
|
|
insertUntrackedAnchor(plan.parent, plan.next, createRuntimeAnchor());
|
|||
|
|
break;
|
|||
|
|
case "create-cleanup": {
|
|||
|
|
frag.nodes = EMPTY_BLOCK;
|
|||
|
|
const cleanupParent = /* @__PURE__ */ parentNode(plan.cleanupStart);
|
|||
|
|
if (cleanupParent) updateLastLocatedLogicalChild(cleanupParent, plan.cleanupStart, plan.cleanupUntil, 1);
|
|||
|
|
if (plan.cleanupUntil) exitHydrationBoundary = enterHydrationBoundary(plan.cleanupUntil);
|
|||
|
|
else {
|
|||
|
|
cleanupHydrationTail(plan.cleanupStart, plan.cleanupContainer);
|
|||
|
|
setCurrentHydrationNode(null);
|
|||
|
|
}
|
|||
|
|
insertUntrackedAnchor(plan.parent, plan.next, createRuntimeAnchor());
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} finally {
|
|||
|
|
exitHydrationBoundary && exitHydrationBoundary();
|
|||
|
|
if (advanceAfterRestore && currentHydrationNode === advanceAfterRestore) advanceHydrationNode(advanceAfterRestore);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function hydrateDynamicFragmentAnchor(frag, isEmpty = false) {
|
|||
|
|
executeAnchorPlan(frag, resolveDynamicAnchor(frag, isEmpty));
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* The hydrating half of `SlotFragment.updateSlot`. The range the server left
|
|||
|
|
* says what it rendered, so nothing is tried and taken back:
|
|||
|
|
* - `<!--(-->`: the fallback, with none of the content's output;
|
|||
|
|
* - `<!--[--><!--]-->`: nothing;
|
|||
|
|
* - anything else: the content.
|
|||
|
|
*/
|
|||
|
|
function hydrateSlotFragmentContent(frag, render, key, shouldForce) {
|
|||
|
|
locateHydrationNode();
|
|||
|
|
const open = currentHydrationNode;
|
|||
|
|
const resolve = () => recheckSlotResolution(frag, shouldForce || frag.pendingRecheckForce);
|
|||
|
|
if (open && isComment(open, "[") && open.nextSibling && isComment(open.nextSibling, "]")) {
|
|||
|
|
const close = frag.anchor = claimAnchor(open.nextSibling);
|
|||
|
|
runWithoutHydration(() => {
|
|||
|
|
frag.updateContent(render, key);
|
|||
|
|
resolve();
|
|||
|
|
});
|
|||
|
|
advanceHydrationNode(close);
|
|||
|
|
} else if (open && isComment(open, "(")) {
|
|||
|
|
const close = frag.anchor = claimAnchor(locateEndAnchor(open));
|
|||
|
|
hydrateSlotFallbackRange({
|
|||
|
|
first: open.nextSibling,
|
|||
|
|
close,
|
|||
|
|
boundary: frag.boundary
|
|||
|
|
}, () => {
|
|||
|
|
frag.updateContent(render, key);
|
|||
|
|
resolve();
|
|||
|
|
if (frag.activeFallback && !frag.fallbackInserted) frag.insert(close.parentNode, close);
|
|||
|
|
});
|
|||
|
|
advanceHydrationNode(close);
|
|||
|
|
} else withHydratingSlotBoundary(() => {
|
|||
|
|
frag.updateContent(render, key);
|
|||
|
|
if (isValidSlot(frag.getContent())) {
|
|||
|
|
resolve();
|
|||
|
|
hydrateDynamicFragmentAnchor(frag, !isValidBlock(frag.nodes));
|
|||
|
|
} else {
|
|||
|
|
if (open) warnHydrationNodeMismatch(open, `slot fallback`);
|
|||
|
|
frag.syncNodes();
|
|||
|
|
hydrateDynamicFragmentAnchor(frag, true);
|
|||
|
|
runWithoutHydration(resolve);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* The nodes in the range are the fallback's: `createContent` runs the slot
|
|||
|
|
* content without hydration and places it as on the client. The fallback is
|
|||
|
|
* adopted from within it, by whichever slot on the boundary chain resolves it
|
|||
|
|
* (see `renderSlotFallback`), and never moves.
|
|||
|
|
*/
|
|||
|
|
function hydrateSlotFallbackRange(range, createContent) {
|
|||
|
|
const first = range.first;
|
|||
|
|
const last = range.close.previousSibling;
|
|||
|
|
if (first !== range.close) {
|
|||
|
|
range.adopt = (render) => hydrateNode(first, render);
|
|||
|
|
if (range.boundary) range.boundary.adoptFallback = range.adopt;
|
|||
|
|
}
|
|||
|
|
withHydratingSlotFallback(createContent);
|
|||
|
|
const boundary = range.boundary;
|
|||
|
|
if (boundary && boundary.adoptFallback) {
|
|||
|
|
warnHydrationNodeMismatch(first, `slot content`);
|
|||
|
|
boundary.adoptFallback = void 0;
|
|||
|
|
removeFragmentNodes(first.previousSibling, last.nextSibling);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/componentSlots.ts
|
|||
|
|
const rawSlotsOwnerMap = /* @__PURE__ */ new WeakMap();
|
|||
|
|
const rawSlotWrappersCache = /* @__PURE__ */ new WeakMap();
|
|||
|
|
function normalizeRawSlots(rawSlots) {
|
|||
|
|
if (!rawSlots) return rawSlots;
|
|||
|
|
const normalized = isFunction(rawSlots) ? { default: rawSlots } : rawSlots;
|
|||
|
|
if (!rawSlotsOwnerMap.has(normalized)) rawSlotsOwnerMap.set(normalized, getScopeOwner());
|
|||
|
|
return normalized;
|
|||
|
|
}
|
|||
|
|
var SlotSourceCell = class extends Dep {
|
|||
|
|
constructor(source) {
|
|||
|
|
super();
|
|||
|
|
this.source = source;
|
|||
|
|
this.committed = void 0;
|
|||
|
|
this.next = void 0;
|
|||
|
|
}
|
|||
|
|
get value() {
|
|||
|
|
trackDep(this);
|
|||
|
|
return this.committed;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
/**
|
|||
|
|
* A dynamic slot descriptor is the parent's expression, like a prop getter:
|
|||
|
|
* replace each function source with a reader of the cell the input effect
|
|||
|
|
* commits it to. Slot functions keep their closure semantics. Returns the
|
|||
|
|
* isolated slots with their cells, or nothing when no source is a function.
|
|||
|
|
*/
|
|||
|
|
function isolateSlotSources(rawSlots) {
|
|||
|
|
const dynamicSources = rawSlots.$;
|
|||
|
|
if (!dynamicSources) return;
|
|||
|
|
let count = 0;
|
|||
|
|
for (let i = 0; i < dynamicSources.length; i++) if (isFunction(dynamicSources[i])) count++;
|
|||
|
|
if (!count) return;
|
|||
|
|
const cells = new Array(count);
|
|||
|
|
const isolatedSources = dynamicSources.slice();
|
|||
|
|
for (let i = 0, n = 0; i < dynamicSources.length; i++) {
|
|||
|
|
const source = dynamicSources[i];
|
|||
|
|
if (isFunction(source)) {
|
|||
|
|
const cell = cells[n++] = new SlotSourceCell(source);
|
|||
|
|
isolatedSources[i] = isolateSlotSource(cell);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
const isolated = extend$1({}, rawSlots, { $: isolatedSources });
|
|||
|
|
rawSlotsOwnerMap.set(isolated, rawSlotsOwnerMap.get(rawSlots) || null);
|
|||
|
|
return [isolated, cells];
|
|||
|
|
}
|
|||
|
|
function isolateSlotSource(cell) {
|
|||
|
|
const isolated = () => cell.value;
|
|||
|
|
isolated._cache = cell;
|
|||
|
|
return isolated;
|
|||
|
|
}
|
|||
|
|
function initSlots(instance) {
|
|||
|
|
const isolated = isolateSlotSources(instance.rawSlots);
|
|||
|
|
if (isolated) {
|
|||
|
|
instance.rawSlots = isolated[0];
|
|||
|
|
instance.slotSources = isolated[1];
|
|||
|
|
instance.slots = new Proxy(isolated[0], dynamicSlotsProxyHandlers);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function withSlotOwner(slots, fn) {
|
|||
|
|
const owner = rawSlotsOwnerMap.get(slots);
|
|||
|
|
if (owner === void 0) return fn();
|
|||
|
|
return withRenderContext(deriveSlotOwner(currentRenderContext, owner), fn);
|
|||
|
|
}
|
|||
|
|
function getOwnedSlot(slots, key, slot) {
|
|||
|
|
if (!rawSlotsOwnerMap.has(slots)) return slot;
|
|||
|
|
let wrappers = rawSlotWrappersCache.get(slots);
|
|||
|
|
if (!wrappers) rawSlotWrappersCache.set(slots, wrappers = /* @__PURE__ */ new Map());
|
|||
|
|
const cached = wrappers.get(key);
|
|||
|
|
if (cached && cached.slot === slot) return cached.wrapped;
|
|||
|
|
const wrapped = ((...args) => withSlotOwner(slots, () => slot(...args)));
|
|||
|
|
wrapped._ = slot._;
|
|||
|
|
wrappers.set(key, {
|
|||
|
|
slot,
|
|||
|
|
wrapped
|
|||
|
|
});
|
|||
|
|
return wrapped;
|
|||
|
|
}
|
|||
|
|
const dynamicSlotsProxyHandlers = {
|
|||
|
|
get: getSlot,
|
|||
|
|
has: (target, key) => !!getSlot(target, key),
|
|||
|
|
getOwnPropertyDescriptor(target, key) {
|
|||
|
|
const slot = getSlot(target, key);
|
|||
|
|
if (slot) return {
|
|||
|
|
configurable: true,
|
|||
|
|
enumerable: true,
|
|||
|
|
value: slot
|
|||
|
|
};
|
|||
|
|
},
|
|||
|
|
ownKeys(target) {
|
|||
|
|
const keys = new Set(Object.keys(target).filter((k) => k !== "$"));
|
|||
|
|
const dynamicSources = target.$;
|
|||
|
|
if (dynamicSources) for (const source of dynamicSources) if (isFunction(source)) {
|
|||
|
|
const slot = withSlotOwner(target, () => resolveFunctionSource(source));
|
|||
|
|
if (slot) {
|
|||
|
|
if (isArray(slot)) for (const s of slot) keys.add(String(s.name));
|
|||
|
|
else keys.add(String(slot.name));
|
|||
|
|
}
|
|||
|
|
} else for (const key of Object.keys(source)) keys.add(key);
|
|||
|
|
return [...keys];
|
|||
|
|
},
|
|||
|
|
set: NO,
|
|||
|
|
deleteProperty: NO
|
|||
|
|
};
|
|||
|
|
function getSlot(target, key) {
|
|||
|
|
const slot = resolveSlot(target, key);
|
|||
|
|
if (slot) return getOwnedSlot(target, key, isFunction(slot) ? slot : slot.fn);
|
|||
|
|
}
|
|||
|
|
function resolveSlot(target, key) {
|
|||
|
|
if (key === "$") return;
|
|||
|
|
const dynamicSources = target.$;
|
|||
|
|
if (dynamicSources) {
|
|||
|
|
let i = dynamicSources.length;
|
|||
|
|
let source;
|
|||
|
|
while (i--) {
|
|||
|
|
source = dynamicSources[i];
|
|||
|
|
if (isFunction(source)) {
|
|||
|
|
const slot = withSlotOwner(target, () => resolveFunctionSource(source));
|
|||
|
|
if (slot) {
|
|||
|
|
if (isArray(slot)) {
|
|||
|
|
for (let j = slot.length - 1; j >= 0; j--) if (String(slot[j].name) === key) return slot[j];
|
|||
|
|
} else if (String(slot.name) === key) return slot;
|
|||
|
|
}
|
|||
|
|
} else if (hasOwn(source, key)) return source[key];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (hasOwn(target, key)) return target[key];
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Get the effective slot instance for accessing rawSlots and scopeId.
|
|||
|
|
* Prefers the slot owner (if inside a slot), falls back to currentInstance.
|
|||
|
|
*/
|
|||
|
|
function getScopeOwner() {
|
|||
|
|
return currentRenderContext.slotOwner || currentInstance;
|
|||
|
|
}
|
|||
|
|
function createSlot(name = "default", rawProps, fallback, flags = 0) {
|
|||
|
|
const _insertionParent = insertionParent;
|
|||
|
|
const _insertionAnchor = insertionAnchor;
|
|||
|
|
if (!isHydrating$1) resetInsertionState();
|
|||
|
|
let hydrationCursor = null;
|
|||
|
|
const instance = getScopeOwner();
|
|||
|
|
const rawSlots = instance.rawSlots;
|
|||
|
|
const scopeId = !(flags & 1) && instance.type.__scopeId;
|
|||
|
|
const outerSlotScopeIds = currentRenderContext.slotScopeIds;
|
|||
|
|
const slotScopeIds = scopeId ? outerSlotScopeIds ? [...outerSlotScopeIds, `${scopeId}-s`] : [`${scopeId}-s`] : outerSlotScopeIds;
|
|||
|
|
const once = !!(flags & 2);
|
|||
|
|
const slotProps = rawProps ? new Proxy(once ? snapshotRawProps(rawProps) : rawProps, rawPropsProxyHandlers) : EMPTY_OBJ;
|
|||
|
|
let fragment;
|
|||
|
|
let isCustomElementSlot = false;
|
|||
|
|
const interopSlotsSource = isInteropEnabled && rawSlots[interopSlotsKey];
|
|||
|
|
if (interopSlotsSource) {
|
|||
|
|
if (isHydrating$1) hydrationCursor = enterHydrationCursor();
|
|||
|
|
fragment = withRenderContext(deriveSlotScopeIds(currentRenderContext, slotScopeIds), () => instance.appContext.vdom.slot(interopSlotsSource, name, slotProps, instance, {
|
|||
|
|
fallback,
|
|||
|
|
flags,
|
|||
|
|
adoptAnchor: _insertionAnchor
|
|||
|
|
}));
|
|||
|
|
} else {
|
|||
|
|
if (once && fallback) {
|
|||
|
|
const originalFallback = fallback;
|
|||
|
|
fallback = (...args) => withOnce(() => originalFallback(...args));
|
|||
|
|
}
|
|||
|
|
if (isHydrating$1) hydrationCursor = captureHydrationCursor();
|
|||
|
|
const ce = instance.ce || isAsyncComponentEnabled && instance.parent && isAsyncWrapper(instance.parent) && instance.parent.ce;
|
|||
|
|
isCustomElementSlot = !!(ce && ce._hasShadowRoot());
|
|||
|
|
const slotFragment = !isCustomElementSlot && shouldUseSlotFragment(rawSlots, name, fallback, flags) ? new SlotFragment(flags, _insertionAnchor) : void 0;
|
|||
|
|
let dynamicFragment;
|
|||
|
|
if (slotFragment) {
|
|||
|
|
slotFragment.ctx = deriveSlotScopeIds(slotFragment.ctx, slotScopeIds);
|
|||
|
|
fragment = slotFragment;
|
|||
|
|
} else {
|
|||
|
|
dynamicFragment = new DynamicFragment(132, !!(process.env.NODE_ENV !== "production") ? "slot" : void 0, false, false, void 0, _insertionAnchor);
|
|||
|
|
const ctx = dynamicFragment.ctx;
|
|||
|
|
dynamicFragment.ctx = deriveRenderContext(ctx, ctx.slotOwner, null, slotScopeIds, ctx.suspense);
|
|||
|
|
fragment = dynamicFragment;
|
|||
|
|
}
|
|||
|
|
const isDynamicName = isFunction(name);
|
|||
|
|
const renderSlot = () => {
|
|||
|
|
if (isCustomElementSlot) {
|
|||
|
|
const el = /* @__PURE__ */ createElement("slot");
|
|||
|
|
const ownScopeId = instance.type.__scopeId;
|
|||
|
|
if (ownScopeId) el.setAttribute(ownScopeId, "");
|
|||
|
|
if (outerSlotScopeIds) setElementScopeIds(el, outerSlotScopeIds);
|
|||
|
|
const setSlotProps = () => {
|
|||
|
|
const slotName = isFunction(name) ? name() : name;
|
|||
|
|
setDynamicProps(el, [slotProps, slotName !== "default" ? { name: slotName } : {}]);
|
|||
|
|
};
|
|||
|
|
if (once) setSlotProps();
|
|||
|
|
else renderEffect(setSlotProps);
|
|||
|
|
if (fallback) {
|
|||
|
|
const fallbackFn = fallback;
|
|||
|
|
withRenderContext(dynamicFragment.ctx, () => {
|
|||
|
|
const block = fallbackFn();
|
|||
|
|
insert(block, el);
|
|||
|
|
registerNestedVDOMCleanup(block);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
fragment.nodes = el;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
const slotName = isFunction(name) ? name() : name;
|
|||
|
|
const resolvedSlot = resolveSlot(rawSlots, slotName);
|
|||
|
|
const slot = resolvedSlot ? getOwnedSlot(rawSlots, slotName, isFunction(resolvedSlot) ? resolvedSlot : resolvedSlot.fn) : void 0;
|
|||
|
|
const render = slot ? getBoundSlot(slot) : void 0;
|
|||
|
|
const key = resolvedSlot && !isFunction(resolvedSlot) && hasOwn(resolvedSlot, "key") ? resolvedSlot.key : render || fallback;
|
|||
|
|
if (slotFragment) slotFragment.updateSlot(render, fallback, key);
|
|||
|
|
else if (isHydrating$1) withHydratingSlotBoundary(() => dynamicFragment.update(render || fallback, key));
|
|||
|
|
else dynamicFragment.update(render || fallback, key);
|
|||
|
|
};
|
|||
|
|
let cachedSlot;
|
|||
|
|
let cachedBoundSlot;
|
|||
|
|
const getBoundSlot = (slot) => {
|
|||
|
|
if (slot !== cachedSlot) {
|
|||
|
|
cachedSlot = slot;
|
|||
|
|
cachedBoundSlot = () => renderWithSlotScopeIds(slotScopeIds, () => once ? withOnce(() => slot(slotProps)) : slot(slotProps));
|
|||
|
|
}
|
|||
|
|
return cachedBoundSlot;
|
|||
|
|
};
|
|||
|
|
if (!once && !isCustomElementSlot && (isDynamicName || rawSlots.$)) renderEffect(renderSlot);
|
|||
|
|
else renderSlot();
|
|||
|
|
}
|
|||
|
|
if (isHydrating$1 && isInteropEnabled && isInteropFragment(fragment)) fragment.hydrate();
|
|||
|
|
finishBlockCreation(fragment, fragment.anchor, hydrationCursor, _insertionParent, _insertionAnchor, isCustomElementSlot);
|
|||
|
|
return fragment;
|
|||
|
|
}
|
|||
|
|
function shouldUseSlotFragment(rawSlots, name, fallback, flags) {
|
|||
|
|
if (currentRenderContext.slotBoundary && isForwardedSlot(flags)) return true;
|
|||
|
|
if (!fallback) return false;
|
|||
|
|
if (rawSlots === EMPTY_OBJ) return false;
|
|||
|
|
if (isFunction(name) || rawSlots.$) return true;
|
|||
|
|
const slot = resolveSlot(rawSlots, name);
|
|||
|
|
if (!slot) return false;
|
|||
|
|
return (isFunction(slot) ? slot : slot.fn)._ === 1;
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/scopeId.ts
|
|||
|
|
/**
|
|||
|
|
* Catch-up for slot content DOM created outside the ambient window (eager
|
|||
|
|
* template clones, hand-built elements). Shallow on purpose: element subtrees
|
|||
|
|
* can contain mounted component internals, so descendants are left to the
|
|||
|
|
* creation-time ambient. Interop fragments derive their ids through the vdom
|
|||
|
|
* patch context and are skipped.
|
|||
|
|
*/
|
|||
|
|
function stampSlotContent(block, scopeIds) {
|
|||
|
|
if (block instanceof Element) {
|
|||
|
|
for (let i = 0; i < scopeIds.length; i++) if (!block.hasAttribute(scopeIds[i])) block.setAttribute(scopeIds[i], "");
|
|||
|
|
} else if (isArray(block)) for (const b of block) stampSlotContent(b, scopeIds);
|
|||
|
|
else if (isFragment(block) && !(isInteropEnabled && isInteropFragment(block)) && !(isSlotResolver(block) && block.activeFallback)) stampSlotContent(block.nodes, scopeIds);
|
|||
|
|
}
|
|||
|
|
function renderWithSlotScopeIds(scopeIds, render) {
|
|||
|
|
const block = withRenderContext(deriveSlotScopeIds(currentRenderContext, scopeIds), render);
|
|||
|
|
if (scopeIds && !isHydrating$1) stampSlotContent(block, scopeIds);
|
|||
|
|
return block;
|
|||
|
|
}
|
|||
|
|
function getCurrentScopeId() {
|
|||
|
|
const scopeOwner = getScopeOwner();
|
|||
|
|
return scopeOwner ? scopeOwner.type.__scopeId : void 0;
|
|||
|
|
}
|
|||
|
|
function registerScopeIdOwner(instance, frag) {
|
|||
|
|
const owners = frag.scopeIdOwners || (frag.scopeIdOwners = []);
|
|||
|
|
if (!owners.includes(instance)) owners.push(instance);
|
|||
|
|
}
|
|||
|
|
function resolveScopeIdRoot(instance, onComponent) {
|
|||
|
|
return getRootElement(instance.block, {
|
|||
|
|
onDynamicFragment: (frag) => registerScopeIdOwner(instance, frag),
|
|||
|
|
onComponent,
|
|||
|
|
excludeSlotOutlets: true
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
function applyScopeIdOwners(owners) {
|
|||
|
|
for (let i = 0; i < owners.length; i++) applyRootScopeIds(owners[i]);
|
|||
|
|
}
|
|||
|
|
let publishInteropScopeIds = null;
|
|||
|
|
function setPublishInteropScopeIds(fn) {
|
|||
|
|
publishInteropScopeIds = fn;
|
|||
|
|
}
|
|||
|
|
function pushOwnRootScopeIds(instance, ids) {
|
|||
|
|
const { scopeId, slotScopeIds } = instance;
|
|||
|
|
if (scopeId) (ids || (ids = [])).push(scopeId);
|
|||
|
|
if (slotScopeIds) (ids || (ids = [])).push(...slotScopeIds);
|
|||
|
|
return ids;
|
|||
|
|
}
|
|||
|
|
function hasOwnRootScopeIds(instance) {
|
|||
|
|
return !!(instance.parent && (instance.scopeId || instance.slotScopeIds));
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* The instance's root-only ids, climbing the effective-root chain so the
|
|||
|
|
* innermost owner's collection carries every ancestor's contribution.
|
|||
|
|
* Assigned parent blocks ground the climb: a null parent block means an
|
|||
|
|
* in-setup mount, where the mounting component is never the root.
|
|||
|
|
*/
|
|||
|
|
function collectRootScopeIds(instance) {
|
|||
|
|
let ids = pushOwnRootScopeIds(instance, null);
|
|||
|
|
let current = instance;
|
|||
|
|
while (current.parent && isVaporComponent(current.parent) && isRootChainChild(current.parent, current)) {
|
|||
|
|
current = current.parent;
|
|||
|
|
ids = pushOwnRootScopeIds(current, ids);
|
|||
|
|
}
|
|||
|
|
return ids;
|
|||
|
|
}
|
|||
|
|
function isRootChainChild(parent, child) {
|
|||
|
|
return parent.block === child || !!parent.block && getRootChainComponent(parent.block) === child;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Resolves the effective root, registers owners along the chain, and applies
|
|||
|
|
* the instance's root-only ids: element roots are stamped, vnode-backed roots
|
|||
|
|
* are published for core to apply at its own mount. When the chain crosses a
|
|||
|
|
* nested component with its own root ids, the outer owner delegates — the
|
|||
|
|
* innermost owner's collect climbs every ancestor, so one pre-insert
|
|||
|
|
* application preserves both custom element connectedCallback timing and
|
|||
|
|
* VDOM's innermost-first attribute order.
|
|||
|
|
*/
|
|||
|
|
function applyRootScopeIds(instance) {
|
|||
|
|
let delegated = false;
|
|||
|
|
const root = resolveScopeIdRoot(instance, (nested) => {
|
|||
|
|
if (hasOwnRootScopeIds(nested)) delegated = true;
|
|||
|
|
});
|
|||
|
|
if (delegated) return;
|
|||
|
|
const scopeIds = collectRootScopeIds(instance);
|
|||
|
|
if (!scopeIds) return;
|
|||
|
|
if (root) setElementScopeIds(root, scopeIds);
|
|||
|
|
if (isInteropEnabled && publishInteropScopeIds) publishInteropScopeIds(instance.block, scopeIds);
|
|||
|
|
}
|
|||
|
|
function applyComponentScopeIds(instance) {
|
|||
|
|
if (!hasOwnRootScopeIds(instance)) return;
|
|||
|
|
applyRootScopeIds(instance);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Hydration counterpart of applyComponentScopeIds: hydrated roots already
|
|||
|
|
* carry SSR scope attrs, so the walk only registers dynamic root tracking,
|
|||
|
|
* publishes interop carriers, and stamps mismatch-recreated roots
|
|||
|
|
* (client-built DOM without SSR attrs).
|
|||
|
|
*/
|
|||
|
|
function hydrateComponentScopeIds(instance) {
|
|||
|
|
if (!hasOwnRootScopeIds(instance)) return;
|
|||
|
|
const root = resolveScopeIdRoot(instance);
|
|||
|
|
const stampRoot = root && isRecreatedNode(root) ? root : void 0;
|
|||
|
|
const publish = isInteropEnabled && publishInteropScopeIds;
|
|||
|
|
if (!stampRoot && !publish) return;
|
|||
|
|
const scopeIds = collectRootScopeIds(instance);
|
|||
|
|
if (!scopeIds) return;
|
|||
|
|
if (stampRoot) setElementScopeIds(stampRoot, scopeIds);
|
|||
|
|
if (publish) publish(instance.block, scopeIds);
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/keepAlive.ts
|
|||
|
|
let isKeepAliveEnabled = false;
|
|||
|
|
let currentCacheKey;
|
|||
|
|
function enableKeepAlive() {
|
|||
|
|
isKeepAliveEnabled = true;
|
|||
|
|
}
|
|||
|
|
function withKeepAliveEnabled(value) {
|
|||
|
|
enableKeepAlive();
|
|||
|
|
return value;
|
|||
|
|
}
|
|||
|
|
function getKeepAliveContext(instance) {
|
|||
|
|
let owner = instance;
|
|||
|
|
while (isAsyncComponentEnabled && owner && owner.vapor && isAsyncWrapper(owner)) owner = owner.parent;
|
|||
|
|
return owner && owner.vapor && isKeepAlive(owner) ? owner.ctx : null;
|
|||
|
|
}
|
|||
|
|
function withCurrentCacheKey(key, fn) {
|
|||
|
|
if (key === void 0) return fn();
|
|||
|
|
const prev = currentCacheKey;
|
|||
|
|
currentCacheKey = key;
|
|||
|
|
try {
|
|||
|
|
return fn();
|
|||
|
|
} finally {
|
|||
|
|
currentCacheKey = prev;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/fragment.ts
|
|||
|
|
var VaporFragment = class {
|
|||
|
|
constructor(nodes, flags = 1) {
|
|||
|
|
this.nodes = nodes;
|
|||
|
|
this.__vf = flags;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
var RenderContextFragment = class extends VaporFragment {
|
|||
|
|
constructor(nodes, flags = 1) {
|
|||
|
|
super(nodes, flags);
|
|||
|
|
this.renderInstance = currentInstance;
|
|||
|
|
this.ctx = currentRenderContext;
|
|||
|
|
if (isKeepAliveEnabled) this.keepAliveCtx = getKeepAliveContext(currentInstance);
|
|||
|
|
}
|
|||
|
|
get slotBoundary() {
|
|||
|
|
return this.ctx.slotBoundary;
|
|||
|
|
}
|
|||
|
|
get slotScopeIds() {
|
|||
|
|
return this.ctx.slotScopeIds;
|
|||
|
|
}
|
|||
|
|
runWithRenderCtx(fn, scope) {
|
|||
|
|
return runWithRenderCtx(this, fn, scope);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
function runWithRenderCtx(fragment, fn, scope) {
|
|||
|
|
if (scope === void 0 && currentInstance === fragment.renderInstance) return withRenderContext(fragment.ctx, fn);
|
|||
|
|
const prevInstance = setCurrentInstance(fragment.renderInstance, scope);
|
|||
|
|
try {
|
|||
|
|
return withRenderContext(fragment.ctx, fn);
|
|||
|
|
} finally {
|
|||
|
|
restoreCurrentInstance(prevInstance);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* The one construction point for a slot host's boundary context, shared by
|
|||
|
|
* SlotFragment and both vdom-interop slot hosts. `run` always comes from the
|
|||
|
|
* host fragment's render seam, and so does the id cell unless the boundary
|
|||
|
|
* stands for an enclosing outlet; `getParent`, `getFallback` and `markDirty`
|
|||
|
|
* stay host-specific (ownership caps, fallback sources and dirty batching
|
|||
|
|
* differ per host).
|
|||
|
|
*/
|
|||
|
|
function createSlotBoundary(fragment, getParent, getFallback, markDirty, onContentInvalid, getScopeIds = () => fragment.slotScopeIds) {
|
|||
|
|
return {
|
|||
|
|
getParent,
|
|||
|
|
getFallback,
|
|||
|
|
run: (fn, scope) => runWithRenderCtx(fragment, fn, scope),
|
|||
|
|
getScopeIds,
|
|||
|
|
markDirty,
|
|||
|
|
onContentInvalid
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
var ForFragment = class extends VaporFragment {
|
|||
|
|
constructor(nodes, trackSlotBoundary, onInvalid) {
|
|||
|
|
super(nodes, 8);
|
|||
|
|
if (trackSlotBoundary) trackSlotBoundaryDirtying(this, onInvalid);
|
|||
|
|
}
|
|||
|
|
onReset(fn) {
|
|||
|
|
(this.resetListeners || (this.resetListeners = [])).push(fn);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
var ForBlock = class extends VaporFragment {
|
|||
|
|
constructor(nodes, scope, item, key, index, renderKey) {
|
|||
|
|
super(nodes, 16);
|
|||
|
|
this.scope = scope;
|
|||
|
|
this.itemRef = item;
|
|||
|
|
this.keyRef = key;
|
|||
|
|
this.indexRef = index;
|
|||
|
|
this.key = renderKey;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
var DynamicFragment = class extends RenderContextFragment {
|
|||
|
|
constructor(flags = 0, anchorLabel, keyed = false, trackSlotBoundary = false, onInvalid, adoptAnchor) {
|
|||
|
|
super(EMPTY_BLOCK, 2 | flags);
|
|||
|
|
this.everUpdated = false;
|
|||
|
|
if (keyed) this.keyed = true;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) this.anchorLabel = anchorLabel;
|
|||
|
|
if (!isHydrating$1) this.anchor = resolveFragmentAnchor(adoptAnchor, anchorLabel);
|
|||
|
|
if (trackSlotBoundary) trackSlotBoundaryDirtying(this, onInvalid);
|
|||
|
|
}
|
|||
|
|
get autoHydrate() {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
update(render, key = render, noScope = false, branchKey) {
|
|||
|
|
const everUpdated = this.everUpdated;
|
|||
|
|
this.everUpdated = true;
|
|||
|
|
if (key === this.current) {
|
|||
|
|
if (isHydrating$1 && this.autoHydrate) hydrateDynamicFragmentAnchor(this, true);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
const transition = isTransitionEnabled ? this.$transition : void 0;
|
|||
|
|
const prevKey = this.current;
|
|||
|
|
const wasMounted = prevKey !== void 0;
|
|||
|
|
this.current = key;
|
|||
|
|
const prevSub = setActiveSub();
|
|||
|
|
let reusingDeferredAnchor = false;
|
|||
|
|
try {
|
|||
|
|
const parent = !isHydrating$1 ? this.getBranchParent() : null;
|
|||
|
|
const isUpdate = wasMounted || everUpdated && !!parent;
|
|||
|
|
if (isUpdate) {
|
|||
|
|
const bu = this.bu;
|
|||
|
|
if (bu) for (let i = 0; i < bu.length; i++) bu[i]();
|
|||
|
|
}
|
|||
|
|
if (transition && deferBranchUpdateDuringLeave(this, render, key, noScope, branchKey)) return;
|
|||
|
|
let removePrevious;
|
|||
|
|
if (wasMounted) {
|
|||
|
|
const scope = this.scope;
|
|||
|
|
const previous = this.nodes;
|
|||
|
|
const removeBranch = () => remove(previous, parent || void 0);
|
|||
|
|
let deferRemoval = false;
|
|||
|
|
if (scope) {
|
|||
|
|
if (this.keepAliveCtx) deferRemoval = this.keepAliveCtx.prepareBranchRemoval(this, scope, prevKey);
|
|||
|
|
else scope.stop();
|
|||
|
|
}
|
|||
|
|
if (transition && removeBranchWithLeave(this, transition, parent, render, key, noScope, branchKey)) return;
|
|||
|
|
if (deferRemoval) removePrevious = removeBranch;
|
|||
|
|
else removeBranch();
|
|||
|
|
}
|
|||
|
|
reusingDeferredAnchor = isHydrating$1 ? prepareDeferredHydrationAnchor(this, !!render) : false;
|
|||
|
|
this.renderBranch(render, transition && this.$transition, parent, key, noScope, isUpdate, removePrevious, branchKey);
|
|||
|
|
} finally {
|
|||
|
|
setActiveSub(prevSub);
|
|||
|
|
}
|
|||
|
|
if (isHydrating$1 && this.autoHydrate && !reusingDeferredAnchor) hydrateDynamicFragmentAnchor(this, render == null);
|
|||
|
|
}
|
|||
|
|
getBranchParent() {
|
|||
|
|
return this.anchor.parentNode;
|
|||
|
|
}
|
|||
|
|
renderBranch(render, transition, parent, key, noScope, notifyUpdated, removePrevious, branchKey) {
|
|||
|
|
this.branchKey = this.keyed ? key : branchKey;
|
|||
|
|
if (render) {
|
|||
|
|
const keepAliveCtx = isKeepAliveEnabled ? this.keepAliveCtx : null;
|
|||
|
|
const useScope = !noScope || !!this.fallthrough;
|
|||
|
|
if (keepAliveCtx) keepAliveCtx.runBranchRender(this, () => this.renderNodes(render, useScope, parent, transition), useScope, removePrevious);
|
|||
|
|
else {
|
|||
|
|
this.scope = useScope ? new EffectScope$1() : void 0;
|
|||
|
|
this.renderNodes(render, useScope, parent, transition);
|
|||
|
|
}
|
|||
|
|
if (this.scopeIdOwners) applyScopeIdOwners(this.scopeIdOwners);
|
|||
|
|
if (parent) {
|
|||
|
|
insert(this.nodes, parent, this.anchor);
|
|||
|
|
if (removePrevious && keepAliveCtx) keepAliveCtx.cacheBlock(this);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
this.scope = void 0;
|
|||
|
|
this.nodes = EMPTY_BLOCK;
|
|||
|
|
if (removePrevious) removePrevious();
|
|||
|
|
}
|
|||
|
|
const u = this.u;
|
|||
|
|
if (notifyUpdated && u) for (let i = 0; i < u.length; i++) u[i](this.nodes);
|
|||
|
|
}
|
|||
|
|
renderNodes(render, useScope, parent, transition) {
|
|||
|
|
try {
|
|||
|
|
this.nodes = this.runWithRenderCtx(() => {
|
|||
|
|
const nodes = (useScope ? this.scope.run(render) : render()) || EMPTY_BLOCK;
|
|||
|
|
if (parent && this.fallthrough) this.fallthrough(nodes);
|
|||
|
|
const bm = this.bm;
|
|||
|
|
if (bm) for (let i = 0; i < bm.length; i++) bm[i](nodes);
|
|||
|
|
return nodes;
|
|||
|
|
});
|
|||
|
|
} finally {
|
|||
|
|
if (isTransitionEnabled && transition) this.$transition = applyTransitionHooks(this.nodes, transition, this);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
var SlotFragment = class extends DynamicFragment {
|
|||
|
|
constructor(flags = 0, adoptAnchor) {
|
|||
|
|
super(1156, !!(process.env.NODE_ENV !== "production") ? "slot" : void 0, false, false, void 0, adoptAnchor);
|
|||
|
|
this.disposed = false;
|
|||
|
|
this.activeFallback = null;
|
|||
|
|
this.fallbackInserted = false;
|
|||
|
|
this.pendingRecheck = false;
|
|||
|
|
this.pendingRecheckForce = false;
|
|||
|
|
this.isReconciling = false;
|
|||
|
|
this.content = EMPTY_BLOCK;
|
|||
|
|
this.isUpdating = false;
|
|||
|
|
onScopeDispose$1(() => {
|
|||
|
|
this.disposed = true;
|
|||
|
|
if (this.fallbackScope) this.fallbackScope.stop();
|
|||
|
|
}, true);
|
|||
|
|
this.sharedFallback = !!(flags & 8);
|
|||
|
|
this.inheritFallback = slotInheritsFallback(flags);
|
|||
|
|
this.notifyParentBoundary = slotNotifiesBoundary(flags);
|
|||
|
|
if (this.sharedFallback) {
|
|||
|
|
if (this.slotBoundary) registerContentInvalid(this.slotBoundary, () => {
|
|||
|
|
invalidateExposedSlotContent(this);
|
|||
|
|
const anchor = this.anchor;
|
|||
|
|
const parent = anchor.parentNode;
|
|||
|
|
if (parent) {
|
|||
|
|
removeAttachedNodes$1(this.content, parent);
|
|||
|
|
if (this.activeFallback) removeAttachedNodes$1(this.activeFallback, parent);
|
|||
|
|
removeNode(anchor, parent);
|
|||
|
|
}
|
|||
|
|
}, this);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
get autoHydrate() {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
renderBranch(render, transition, parent, key, noScope, notifyUpdated, removePrevious, branchKey) {
|
|||
|
|
super.renderBranch(render, transition, parent, key, noScope, notifyUpdated, removePrevious, branchKey);
|
|||
|
|
if (!this.isUpdating) {
|
|||
|
|
this.content = this.nodes;
|
|||
|
|
recheckSlotResolution(this, false);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
get boundary() {
|
|||
|
|
if (!this.ownBoundary) {
|
|||
|
|
const parent = this.inheritFallback ? this.slotBoundary : null;
|
|||
|
|
this.ownBoundary = createSlotBoundary(this, () => parent, () => this.localFallback, (force) => markSlotResolutionDirty(this, force));
|
|||
|
|
}
|
|||
|
|
return this.ownBoundary;
|
|||
|
|
}
|
|||
|
|
insert(parent, anchor, parentSuspense) {
|
|||
|
|
this.disposed = false;
|
|||
|
|
if (!(isHydratingSlotFallback && placeAdoptedFallback(this, parent, anchor))) insert(this.nodes, parent, anchor, parentSuspense);
|
|||
|
|
if (this.activeFallback === this.nodes) this.fallbackInserted = true;
|
|||
|
|
}
|
|||
|
|
move(parent, anchor, moveType, parentComponent, parentSuspense) {
|
|||
|
|
move(this.nodes, parent, anchor, moveType, parentComponent, parentSuspense);
|
|||
|
|
if (this.activeFallback === this.nodes) this.fallbackInserted = true;
|
|||
|
|
}
|
|||
|
|
remove(parent) {
|
|||
|
|
this.disposed = true;
|
|||
|
|
if (this.fallbackScope) this.fallbackScope.stop();
|
|||
|
|
const nodes = this.nodes;
|
|||
|
|
remove(nodes, parent);
|
|||
|
|
if (this.activeFallback === nodes) {
|
|||
|
|
this.activeFallback = null;
|
|||
|
|
this.fallbackInserted = false;
|
|||
|
|
}
|
|||
|
|
this.clearContentInvalid();
|
|||
|
|
disposeSlotResolution(this, parent);
|
|||
|
|
}
|
|||
|
|
clearContentInvalid() {
|
|||
|
|
const callbacks = this.ownBoundary && this.ownBoundary.onContentInvalid;
|
|||
|
|
if (callbacks) callbacks.length = 0;
|
|||
|
|
}
|
|||
|
|
getBranchParent() {
|
|||
|
|
return this.activeFallback ? null : super.getBranchParent();
|
|||
|
|
}
|
|||
|
|
updateContent(render, key) {
|
|||
|
|
if (key !== this.current) this.clearContentInvalid();
|
|||
|
|
this.nodes = this.content;
|
|||
|
|
this.update(render, key);
|
|||
|
|
this.content = this.nodes;
|
|||
|
|
}
|
|||
|
|
updateSlot(render, fallback, key = render || fallback) {
|
|||
|
|
const prevLocalFallback = this.localFallback;
|
|||
|
|
this.localFallback = fallback;
|
|||
|
|
const boundary = this.boundary;
|
|||
|
|
const contentCtx = this.contentCtx || (this.contentCtx = deriveSlotBoundary(this.ctx, boundary));
|
|||
|
|
const slotRender = render ? () => withRenderContext(contentCtx, render) : () => EMPTY_BLOCK;
|
|||
|
|
this.isUpdating = true;
|
|||
|
|
this.pendingRecheck = false;
|
|||
|
|
try {
|
|||
|
|
const shouldForce = prevLocalFallback !== fallback;
|
|||
|
|
if (isHydrating$1) hydrateSlotFragmentContent(this, slotRender, key, shouldForce);
|
|||
|
|
else {
|
|||
|
|
this.updateContent(slotRender, key);
|
|||
|
|
recheckSlotResolution(this, shouldForce || this.pendingRecheckForce);
|
|||
|
|
}
|
|||
|
|
} finally {
|
|||
|
|
this.pendingRecheck = false;
|
|||
|
|
this.pendingRecheckForce = false;
|
|||
|
|
this.isUpdating = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
getContent() {
|
|||
|
|
return this.content;
|
|||
|
|
}
|
|||
|
|
getParentNode() {
|
|||
|
|
return this.anchor ? this.anchor.parentNode : null;
|
|||
|
|
}
|
|||
|
|
getAnchor() {
|
|||
|
|
return this.anchor || null;
|
|||
|
|
}
|
|||
|
|
isBusy() {
|
|||
|
|
return this.isUpdating;
|
|||
|
|
}
|
|||
|
|
isDisposed() {
|
|||
|
|
return this.disposed;
|
|||
|
|
}
|
|||
|
|
isContentValid() {
|
|||
|
|
return isValidSlot(this.content);
|
|||
|
|
}
|
|||
|
|
syncNodes() {
|
|||
|
|
this.nodes = resolveExposedSlotNodes(this);
|
|||
|
|
}
|
|||
|
|
notifyExposedValidityChange() {
|
|||
|
|
if (this.notifyParentBoundary && this.slotBoundary) this.slotBoundary.markDirty();
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
/**
|
|||
|
|
* Adopt the template `<!>` placeholder passed through the insertion state as
|
|||
|
|
* the fragment anchor instead of creating (and later inserting) a runtime
|
|||
|
|
* anchor. Restricted to comments: adopting any other node would remove user
|
|||
|
|
* DOM on removeFragment. Callers detect adoption by identity: the returned
|
|||
|
|
* node is the adopted anchor iff it equals the passed one.
|
|||
|
|
*/
|
|||
|
|
function resolveFragmentAnchor(adopt, anchorLabel) {
|
|||
|
|
if (adopt && adopt.nodeType === 8) {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && anchorLabel) adopt.data = anchorLabel;
|
|||
|
|
return claimUntrackedAnchor(adopt);
|
|||
|
|
}
|
|||
|
|
return claimUntrackedAnchor(!!(process.env.NODE_ENV !== "production") && anchorLabel ? /* @__PURE__ */ createComment(anchorLabel) : /* @__PURE__ */ createTextNode());
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Whether a fragment adopted the captured insertion anchor — the template
|
|||
|
|
* `<!>` placeholder — as its own, which means it rendered in place and the
|
|||
|
|
* creator must skip its trailing insert. Unrelated to hydration's
|
|||
|
|
* `isClaimedAnchor` / `skipUntrackedAnchors`, which are about anchor nodes
|
|||
|
|
* marked during a hydration pass.
|
|||
|
|
*
|
|||
|
|
* The insertion anchor must be checked non-null: append inserts capture no
|
|||
|
|
* anchor, and fragments without a client anchor (vdom interop slots, any
|
|||
|
|
* fragment during hydration) would otherwise compare undefined === undefined
|
|||
|
|
* and falsely skip their only insertion.
|
|||
|
|
*/
|
|||
|
|
function isAdoptedPlaceholder(fragmentAnchor, insertionAnchor) {
|
|||
|
|
return !!insertionAnchor && fragmentAnchor === insertionAnchor;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Shared tail for every block-creating API (`createIf`, `createFor`,
|
|||
|
|
* `createKeyedFragment`, `createDynamicComponent`, slot outlets): the block is
|
|||
|
|
* built, now hand it over to the scope that asked for it.
|
|||
|
|
*
|
|||
|
|
* Client render: insert it at the captured insertion point, unless it adopted
|
|||
|
|
* that point's `<!>` placeholder as its own anchor and therefore already
|
|||
|
|
* rendered in place. Hydration: there is nothing to insert — the block adopted
|
|||
|
|
* server nodes where they already stood — so hand back the cursor instead.
|
|||
|
|
*
|
|||
|
|
* Site-specific hydration work (claiming a leftover `<!---->`, advancing past
|
|||
|
|
* an anchor, running an interop fragment's `hydrate()`) belongs *before* this
|
|||
|
|
* call, guarded by `isHydrating`; keeping it out of here avoids allocating a
|
|||
|
|
* callback on the client-render path, which never needs one.
|
|||
|
|
*/
|
|||
|
|
function finishBlockCreation(block, anchor, cursor, insertionParent, insertionAnchor, force) {
|
|||
|
|
if (isHydrating$1) exitHydrationCursor(cursor);
|
|||
|
|
else if (insertionParent && (force || !isAdoptedPlaceholder(anchor, insertionAnchor))) insert(block, insertionParent, insertionAnchor);
|
|||
|
|
if (insertionParent) registerNestedVDOMCleanup(block);
|
|||
|
|
}
|
|||
|
|
function isFragment(val) {
|
|||
|
|
return !!(val && val.__vf);
|
|||
|
|
}
|
|||
|
|
function isInteropFragment(val) {
|
|||
|
|
return !!(val && val.__vf & 64);
|
|||
|
|
}
|
|||
|
|
function isSlotOutletFragment(val) {
|
|||
|
|
return !!(val && val.__vf & 128);
|
|||
|
|
}
|
|||
|
|
function isDynamicFragment(val) {
|
|||
|
|
return !!(val && val.__vf & 2);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* The key a fragment hands to its branch root as default: a declared key
|
|||
|
|
* (static key on a dynamic component) or the current branch key (keyed
|
|||
|
|
* fragment, dynamic component `:key`, v-if branch index).
|
|||
|
|
*/
|
|||
|
|
function getFragmentKey(frag) {
|
|||
|
|
var _frag$$key;
|
|||
|
|
return (_frag$$key = frag.$key) !== null && _frag$$key !== void 0 ? _frag$$key : frag.branchKey;
|
|||
|
|
}
|
|||
|
|
function isForFragment(val) {
|
|||
|
|
return !!(val && val.__vf & 8);
|
|||
|
|
}
|
|||
|
|
function isForBlock(val) {
|
|||
|
|
return !!(val && val.__vf & 16);
|
|||
|
|
}
|
|||
|
|
function isVaporSlotOutlet(val) {
|
|||
|
|
return !!(val && val.__vf & 4);
|
|||
|
|
}
|
|||
|
|
function isSlotResolver(val) {
|
|||
|
|
return !!(val && val.__vf & 1024);
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/teleport.ts
|
|||
|
|
let isTeleportEnabled = false;
|
|||
|
|
function enableTeleport(value) {
|
|||
|
|
isTeleportEnabled = true;
|
|||
|
|
return value;
|
|||
|
|
}
|
|||
|
|
function isVaporTeleport(value) {
|
|||
|
|
return !!(value && value.__isTeleport && value.__vapor);
|
|||
|
|
}
|
|||
|
|
function isTeleportFragment(value) {
|
|||
|
|
return !!(value && value.__vf & 32);
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/block.ts
|
|||
|
|
const EMPTY_BLOCK = EMPTY_ARR;
|
|||
|
|
function isBlock(val) {
|
|||
|
|
return val instanceof Node || isArray(val) || isVaporComponent(val) || isFragment(val);
|
|||
|
|
}
|
|||
|
|
function isValidBlock(block, componentAsValid = false) {
|
|||
|
|
if (!block) return false;
|
|||
|
|
else if (block instanceof Node) return !(block instanceof Comment) && !isClaimedAnchor(block);
|
|||
|
|
else if (isVaporComponent(block)) return componentAsValid || isValidBlock(block.block, componentAsValid);
|
|||
|
|
else if (isArray(block)) return block.length > 0 && block.some((block) => isValidBlock(block, componentAsValid));
|
|||
|
|
else {
|
|||
|
|
if (isInteropEnabled && block.isBlockValid) return block.isBlockValid(componentAsValid);
|
|||
|
|
return isValidBlock(block.nodes, componentAsValid);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function isValidSlot(block) {
|
|||
|
|
return isValidBlock(block, true);
|
|||
|
|
}
|
|||
|
|
function insert(block, parent, anchor = null, parentSuspense) {
|
|||
|
|
if (block instanceof Node) {
|
|||
|
|
insertNode(block, parent, anchor, parentSuspense);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (isVaporComponent(block)) {
|
|||
|
|
if (block.isMounted && !block.isDeactivated) insert(block.block, parent, anchor, parentSuspense);
|
|||
|
|
else mountComponent(block, parent, anchor);
|
|||
|
|
} else if (isArray(block)) for (const b of block) insert(b, parent, anchor, parentSuspense);
|
|||
|
|
else insertFragment(block, parent, anchor, parentSuspense);
|
|||
|
|
}
|
|||
|
|
function insertNode(block, parent, anchor = null, parentSuspense) {
|
|||
|
|
if (!isHydrating$1) {
|
|||
|
|
const transition = isTransitionEnabled && block instanceof Element ? block.$transition : void 0;
|
|||
|
|
if (transition) {
|
|||
|
|
const insert = () => parent.insertBefore(block, anchor);
|
|||
|
|
if (isVShowMountEnter(block, transition)) {
|
|||
|
|
transition.beforeEnter(block);
|
|||
|
|
insert();
|
|||
|
|
queuePostRenderEffect(() => transition.enter(block), void 0, parentSuspense);
|
|||
|
|
} else performTransitionEnter(block, transition, insert, parentSuspense);
|
|||
|
|
} else if (block !== anchor) parent.insertBefore(block, anchor);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function isVShowMountEnter(el, transition) {
|
|||
|
|
return transition.persisted && !!el.$vshow && !el[vShowHidden];
|
|||
|
|
}
|
|||
|
|
function insertFragment(block, parent, anchor = null, parentSuspense) {
|
|||
|
|
const blockAnchor = block.anchor;
|
|||
|
|
if (blockAnchor) {
|
|||
|
|
insertNode(blockAnchor, parent, anchor, parentSuspense);
|
|||
|
|
anchor = blockAnchor;
|
|||
|
|
}
|
|||
|
|
if (block.insert) block.insert(parent, anchor, parentSuspense, block.$transition);
|
|||
|
|
else insert(block.nodes, parent, anchor, parentSuspense);
|
|||
|
|
}
|
|||
|
|
function move(block, parent, anchor = null, moveType = 1, parentComponent, parentSuspense) {
|
|||
|
|
if (block instanceof Node) {
|
|||
|
|
if (isTransitionEnabled && block instanceof Element && block.$transition && moveType !== 2) {
|
|||
|
|
if (moveType === 0) performTransitionEnter(block, block.$transition, () => parent.insertBefore(block, anchor), parentSuspense, true);
|
|||
|
|
else performTransitionLeave(block, block.$transition, () => {
|
|||
|
|
if (moveType === 1 && parentComponent && parentComponent.isUnmounted) block.remove();
|
|||
|
|
else parent.insertBefore(block, anchor);
|
|||
|
|
}, true, true);
|
|||
|
|
} else parent.insertBefore(block, anchor);
|
|||
|
|
} else if (isVaporComponent(block)) {
|
|||
|
|
if (block.isMounted) move(block.block, parent, anchor, moveType, parentComponent, parentSuspense);
|
|||
|
|
else mountComponent(block, parent, anchor);
|
|||
|
|
} else if (isArray(block)) for (const b of block) move(b, parent, anchor, moveType, parentComponent, parentSuspense);
|
|||
|
|
else {
|
|||
|
|
if (block.anchor) {
|
|||
|
|
move(block.anchor, parent, anchor, moveType, parentComponent, parentSuspense);
|
|||
|
|
anchor = block.anchor;
|
|||
|
|
}
|
|||
|
|
if (block.move) block.move(parent, anchor, moveType, parentComponent, parentSuspense, block.$transition);
|
|||
|
|
else move(block.nodes, parent, anchor, moveType, parentComponent, parentSuspense);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function remove(block, parent) {
|
|||
|
|
if (block instanceof Node) removeNode(block, parent);
|
|||
|
|
else if (isVaporComponent(block)) unmountComponent(block, parent, isSuspenseEnabled && isInteropEnabled ? resolveUnmountSuspense(block.suspense) : block.suspense);
|
|||
|
|
else if (isArray(block)) for (let i = 0; i < block.length; i++) remove(block[i], parent);
|
|||
|
|
else removeFragment(block, parent);
|
|||
|
|
}
|
|||
|
|
function removeAttachedNodes$1(block, parent, removeAnchors = true) {
|
|||
|
|
if (block instanceof Node) {
|
|||
|
|
if (block.parentNode === parent) removeNode(block, parent);
|
|||
|
|
} else if (isVaporComponent(block)) {
|
|||
|
|
if (block.block) removeAttachedNodes$1(block.block, parent, removeAnchors);
|
|||
|
|
} else if (isArray(block)) for (let i = 0; i < block.length; i++) removeAttachedNodes$1(block[i], parent, removeAnchors);
|
|||
|
|
else {
|
|||
|
|
removeAttachedNodes$1(block.nodes, parent, removeAnchors);
|
|||
|
|
const anchor = block.anchor;
|
|||
|
|
if (removeAnchors && anchor && anchor.parentNode === parent) removeNode(anchor, parent);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function removeNode(block, parent) {
|
|||
|
|
if (isTransitionEnabled && block.$transition && block instanceof Element) performTransitionLeave(block, block.$transition, () => parent && block.parentNode === parent && parent.removeChild(block));
|
|||
|
|
else parent && parent.removeChild(block);
|
|||
|
|
}
|
|||
|
|
function removeFragment(block, parent) {
|
|||
|
|
const bum = block.bum;
|
|||
|
|
if (bum) for (let i = 0; i < bum.length; i++) bum[i]();
|
|||
|
|
if (block.remove) block.remove(parent, block.$transition);
|
|||
|
|
else remove(block.nodes, parent);
|
|||
|
|
if (block.anchor) removeNode(block.anchor, parent);
|
|||
|
|
if (block.scope) block.scope.stop();
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Block removal doesn't descend into elements, so it never reaches a block
|
|||
|
|
* mounted into one. Unmount the vdom components in its tree synchronously when
|
|||
|
|
* its owner scope is disposed, as vdom does for an element's children.
|
|||
|
|
*/
|
|||
|
|
function registerNestedVDOMCleanup(block) {
|
|||
|
|
if (isInteropEnabled && !(block instanceof Node)) onScopeDispose$1(() => unmountVDOM(block), true);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Unmounts the vdom components in a block tree whose DOM goes away without
|
|||
|
|
* block removal.
|
|||
|
|
*/
|
|||
|
|
function unmountVDOM(block) {
|
|||
|
|
if (!block || block instanceof Node) return;
|
|||
|
|
if (isVaporComponent(block)) unmountVDOM(block.block);
|
|||
|
|
else if (isArray(block)) for (let i = 0; i < block.length; i++) unmountVDOM(block[i]);
|
|||
|
|
else if (isInteropFragment(block)) block.remove();
|
|||
|
|
else unmountVDOM(block.nodes);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* dev / test only
|
|||
|
|
*/
|
|||
|
|
function normalizeBlock(block) {
|
|||
|
|
if (!!!(process.env.NODE_ENV !== "production") && true) throw new Error("normalizeBlock should not be used in production code paths");
|
|||
|
|
const nodes = [];
|
|||
|
|
if (block instanceof Node) nodes.push(block);
|
|||
|
|
else if (isArray(block)) block.forEach((child) => nodes.push(...normalizeBlock(child)));
|
|||
|
|
else if (isVaporComponent(block)) nodes.push(...normalizeBlock(block.block));
|
|||
|
|
else if (isTeleportEnabled && isTeleportFragment(block)) nodes.push(block.placeholder, block.anchor);
|
|||
|
|
else {
|
|||
|
|
nodes.push(...normalizeBlock(block.nodes));
|
|||
|
|
block.anchor && nodes.push(block.anchor);
|
|||
|
|
}
|
|||
|
|
return nodes;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* First node of a block as it appears in its own container, or `undefined`
|
|||
|
|
* when the block has no node there: an empty array of blocks, or a block
|
|||
|
|
* whose content lives elsewhere (a teleport target) and has no marker left.
|
|||
|
|
*/
|
|||
|
|
function getBlockFirstNode(block) {
|
|||
|
|
if (block instanceof Node) return block;
|
|||
|
|
else if (isArray(block)) {
|
|||
|
|
for (let i = 0; i < block.length; i++) {
|
|||
|
|
const anchor = getBlockFirstNode(block[i]);
|
|||
|
|
if (anchor) return anchor;
|
|||
|
|
}
|
|||
|
|
return;
|
|||
|
|
} else if (isVaporComponent(block)) return getBlockFirstNode(getComponentPhysicalBlock(block));
|
|||
|
|
else {
|
|||
|
|
if (isTeleportEnabled && isTeleportFragment(block)) {
|
|||
|
|
const marker = block.placeholder || block.anchor;
|
|||
|
|
if (marker) return marker;
|
|||
|
|
}
|
|||
|
|
const nodes = block.nodes;
|
|||
|
|
if (isValidBlock(nodes)) return getBlockFirstNode(nodes);
|
|||
|
|
const node = getBlockFirstNode(nodes);
|
|||
|
|
const anchor = block.anchor;
|
|||
|
|
return node && (!anchor || node.parentNode === anchor.parentNode) ? node : anchor;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function findBlockBoundary(block) {
|
|||
|
|
const boundaryBlock = isVaporComponent(block) ? getComponentPhysicalBlock(block) : block;
|
|||
|
|
const lastChild = findLastChild(boundaryBlock);
|
|||
|
|
let { parentNode, nextSibling: nextNode } = lastChild;
|
|||
|
|
if (nextNode && isRangeEnd(nextNode) && isFragmentBlock(boundaryBlock) && !isRangeEnd(lastChild) && !(lastChild.nodeType === 3 && !lastChild.data)) nextNode = nextNode.nextSibling;
|
|||
|
|
return {
|
|||
|
|
parentNode,
|
|||
|
|
nextNode
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
function findLastChild(node) {
|
|||
|
|
if (node && node instanceof Node) return node;
|
|||
|
|
else if (isArray(node)) return findLastChild(node[node.length - 1]);
|
|||
|
|
else if (isVaporComponent(node)) return findLastChild(getComponentPhysicalBlock(node));
|
|||
|
|
else {
|
|||
|
|
if (node.anchor) return node.anchor;
|
|||
|
|
return findLastChild(node.nodes);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function getComponentPhysicalBlock(instance) {
|
|||
|
|
return isSuspenseEnabled && instance.pendingBlock || instance.block;
|
|||
|
|
}
|
|||
|
|
function isFragmentBlock(block) {
|
|||
|
|
if (isArray(block)) return true;
|
|||
|
|
else if (isVaporComponent(block)) return isFragmentBlock(getComponentPhysicalBlock(block));
|
|||
|
|
else if (isFragment(block)) return isFragmentBlock(block.nodes);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/helpers/useCssVars.ts
|
|||
|
|
/**
|
|||
|
|
* Css vars are root-inherited state: the owner writes its root chain before
|
|||
|
|
* insertion, containers on that chain write the content they produce later
|
|||
|
|
* (`bm` hooks; `u` for vdom-owned interop content), and teleports are written
|
|||
|
|
* directly as outlets since their content leaves the chain.
|
|||
|
|
*/
|
|||
|
|
function useVaporCssVars(getter) {
|
|||
|
|
const instance = currentInstance;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) instance.getCssVars = getter;
|
|||
|
|
let vars = EMPTY_OBJ;
|
|||
|
|
const apply = instance.applyCssVars = (nodes) => {
|
|||
|
|
if (!isHydrating$1) setVarsOnBlock(nodes, vars);
|
|||
|
|
registerCssVarApply(nodes, apply);
|
|||
|
|
};
|
|||
|
|
const watchVars = () => watch(() => {
|
|||
|
|
vars = extend$1({}, getter());
|
|||
|
|
if (instance.ce) setVarsOnNode(instance.ce, vars);
|
|||
|
|
else setVarsOnBlock(instance.block, vars);
|
|||
|
|
const outlets = instance.cssVarOutlets;
|
|||
|
|
if (outlets) for (let i = 0; i < outlets.length; i++) setVarsOnBlock(outlets[i].nodes, vars);
|
|||
|
|
}, NOOP, { flush: "post" });
|
|||
|
|
onBeforeMount(() => {
|
|||
|
|
if (!instance.ce) registerCssVarApply(instance.block, apply);
|
|||
|
|
});
|
|||
|
|
if (isHydrating$1) onMounted(watchVars);
|
|||
|
|
else onBeforeMount(watchVars);
|
|||
|
|
}
|
|||
|
|
function setVarsOnBlock(block, vars) {
|
|||
|
|
if (block instanceof Node) setVarsOnNode(block, vars);
|
|||
|
|
else if (isArray(block)) for (let i = 0; i < block.length; i++) setVarsOnBlock(block[i], vars);
|
|||
|
|
else if (isVaporComponent(block)) setVarsOnBlock(block.block, vars);
|
|||
|
|
else if (isFragment(block) && !(isTeleportEnabled && isTeleportFragment(block))) setVarsOnBlock(block.nodes, vars);
|
|||
|
|
}
|
|||
|
|
function registerCssVarApply(block, apply) {
|
|||
|
|
if (isArray(block)) for (let i = 0; i < block.length; i++) registerCssVarApply(block[i], apply);
|
|||
|
|
else if (isVaporComponent(block)) {
|
|||
|
|
if (block.block) registerCssVarApply(block.block, apply);
|
|||
|
|
else (block.bm || (block.bm = [])).push(() => apply(block.block));
|
|||
|
|
} else if (isFragment(block) && !(isTeleportEnabled && isTeleportFragment(block))) {
|
|||
|
|
const hooks = isInteropEnabled && isInteropFragment(block) ? block.u || (block.u = []) : isDynamicFragment(block) || isForFragment(block) ? block.bm || (block.bm = []) : void 0;
|
|||
|
|
if (hooks && !hooks.includes(apply)) hooks.push(apply);
|
|||
|
|
registerCssVarApply(block.nodes, apply);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function registerCssVarOutlet(owner, frag) {
|
|||
|
|
(owner.cssVarOutlets || (owner.cssVarOutlets = [])).push(frag);
|
|||
|
|
onScopeDispose(() => remove$1(owner.cssVarOutlets, frag), true);
|
|||
|
|
}
|
|||
|
|
function applyComponentCssVars(instance) {
|
|||
|
|
let current = instance;
|
|||
|
|
while (current && current.vapor) {
|
|||
|
|
const owner = current;
|
|||
|
|
if (owner.applyCssVars && !owner.ce) owner.applyCssVars(owner.block);
|
|||
|
|
current = current.parent;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/hmr.ts
|
|||
|
|
function hmrRerender(instance) {
|
|||
|
|
if (instance.isUnmounted) return;
|
|||
|
|
if (!instance.type.render) {
|
|||
|
|
let parent = instance.parent;
|
|||
|
|
while (parent && !parent.vapor) parent = parent.parent;
|
|||
|
|
if (parent) return parent.hmrRerender();
|
|||
|
|
if (!instance.parent && !instance.ce) return instance.hmrReload(instance.type);
|
|||
|
|
}
|
|||
|
|
const { parentNode, nextNode: anchor } = findBlockBoundary(instance.block);
|
|||
|
|
const parent = parentNode;
|
|||
|
|
if (instance.renderScope) instance.renderScope.stop();
|
|||
|
|
remove(instance.block, parent);
|
|||
|
|
const prev = setCurrentInstance(instance);
|
|||
|
|
pushWarningContext(instance);
|
|||
|
|
try {
|
|||
|
|
withRenderContext(deriveSlotScopeIds(currentRenderContext, null), () => {
|
|||
|
|
runDevRender(instance);
|
|||
|
|
applyComponentFallthrough(instance);
|
|||
|
|
});
|
|||
|
|
} finally {
|
|||
|
|
popWarningContext();
|
|||
|
|
restoreCurrentInstance(prev);
|
|||
|
|
}
|
|||
|
|
applyComponentScopeIds(instance);
|
|||
|
|
applyComponentCssVars(instance);
|
|||
|
|
insert(instance.block, parent, anchor);
|
|||
|
|
}
|
|||
|
|
function hmrReload(instance, newComp) {
|
|||
|
|
const parentInstance = instance.parent;
|
|||
|
|
if (parentInstance) {
|
|||
|
|
parentInstance.hmrRerender();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
const { parentNode, nextNode: anchor } = findBlockBoundary(instance.block);
|
|||
|
|
const parent = parentNode;
|
|||
|
|
unmountComponent(instance, parent);
|
|||
|
|
const prev = setCurrentInstance(parentInstance);
|
|||
|
|
let newInstance;
|
|||
|
|
try {
|
|||
|
|
newInstance = createComponent(newComp, instance.rawProps, instance.rawSlots, instance.isSingleRoot, void 0, instance.appContext, true);
|
|||
|
|
} finally {
|
|||
|
|
restoreCurrentInstance(prev);
|
|||
|
|
}
|
|||
|
|
mountComponent(newInstance, parent, anchor);
|
|||
|
|
const app = instance.appContext.app;
|
|||
|
|
if (app && app._instance === instance) app._instance = newInstance;
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/component.ts
|
|||
|
|
function useVdomInterop(component, appContext) {
|
|||
|
|
return !!appContext.vdom && !component.__vapor;
|
|||
|
|
}
|
|||
|
|
function resolveFallthroughOwner(isSingleRoot) {
|
|||
|
|
const instance = currentInstance;
|
|||
|
|
if ((isSingleRoot || isTransitionEnabled && instance && isVaporTransition(instance.type)) && isVaporComponent(instance) && instance.type.inheritAttrs !== false && instance.hasFallthrough) return instance;
|
|||
|
|
}
|
|||
|
|
function createComponent(component, rawProps, rawSlots, isSingleRoot, once, appContext = currentInstance && currentInstance.appContext || emptyContext, managedMount = false, ce) {
|
|||
|
|
const wasInOnce = inOnce;
|
|||
|
|
if (wasInOnce && !managedMount) once = true;
|
|||
|
|
const _insertionParent = insertionParent;
|
|||
|
|
const _insertionAnchor = insertionAnchor;
|
|||
|
|
let hydration = null;
|
|||
|
|
let pendingAsyncHydration = false;
|
|||
|
|
if (isHydrating$1) hydration = enterComponentHydration(component);
|
|||
|
|
else resetInsertionState();
|
|||
|
|
const prevCtx = currentRenderContext;
|
|||
|
|
try {
|
|||
|
|
if (isSuspenseEnabled && !prevCtx.suspense && currentInstance && currentInstance.suspense) setRenderContext(deriveSuspense(prevCtx, currentInstance.suspense));
|
|||
|
|
const owner = resolveFallthroughOwner(isSingleRoot);
|
|||
|
|
if (owner) {
|
|||
|
|
const source = () => resolveFallthroughAttrs(owner);
|
|||
|
|
if (rawProps && rawProps !== EMPTY_OBJ) {
|
|||
|
|
const sources = rawProps.$;
|
|||
|
|
rawProps = extend$1({}, rawProps, { $: sources ? sources.concat(source) : [source] });
|
|||
|
|
} else rawProps = { $: [source] };
|
|||
|
|
}
|
|||
|
|
const key = (isKeepAliveEnabled || isTransitionEnabled) && rawProps ? resolveSource(rawProps.key) : void 0;
|
|||
|
|
let keepAliveCtx = null;
|
|||
|
|
if (isKeepAliveEnabled && currentInstance && currentInstance.vapor && isKeepAlive(currentInstance)) {
|
|||
|
|
const ctx = currentInstance.ctx;
|
|||
|
|
keepAliveCtx = ctx;
|
|||
|
|
const cached = !managedMount && ctx.getCachedComponent(component, key);
|
|||
|
|
if (cached) {
|
|||
|
|
if (isVaporComponent(cached) && cached.inputScope) {
|
|||
|
|
cached.rawProps = rawProps || EMPTY_OBJ;
|
|||
|
|
initInputs(cached);
|
|||
|
|
}
|
|||
|
|
const scope = getCurrentScope();
|
|||
|
|
if (isVaporComponent(cached) && cached.unmountScope !== scope) {
|
|||
|
|
cached.unmountScope = scope;
|
|||
|
|
registerUnmount(cached);
|
|||
|
|
}
|
|||
|
|
return cached;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
let asyncBoundary = false;
|
|||
|
|
if (isAsyncComponentEnabled && !isHydrating$1) {
|
|||
|
|
const resolved = component.__asyncResolved;
|
|||
|
|
if (resolved && !(isInteropEnabled && useVdomInterop(resolved, appContext))) {
|
|||
|
|
component = resolved;
|
|||
|
|
asyncBoundary = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (isTeleportEnabled && isVaporTeleport(component)) {
|
|||
|
|
const frag = component.process(rawProps, normalizeRawSlots(rawSlots), _insertionAnchor);
|
|||
|
|
if (key !== void 0) frag.$key = key;
|
|||
|
|
if (_insertionParent) {
|
|||
|
|
onScopeDispose$1(() => frag.disposeTarget(), true);
|
|||
|
|
registerNestedVDOMCleanup(frag);
|
|||
|
|
} else onScopeDispose$1(() => frag.scheduleTargetDispose(), true);
|
|||
|
|
if (!isHydrating$1) {
|
|||
|
|
if (_insertionParent) insert(frag, _insertionParent, _insertionAnchor, currentRenderContext.suspense);
|
|||
|
|
} else frag.hydrate();
|
|||
|
|
return frag;
|
|||
|
|
}
|
|||
|
|
let inputScope;
|
|||
|
|
if (keepAliveCtx && !once && !managedMount) inputScope = new EffectScope(true);
|
|||
|
|
if (isInteropEnabled && useVdomInterop(component, appContext)) {
|
|||
|
|
const frag = appContext.vdom.mount(component, currentInstance, rawProps, normalizeRawSlots(rawSlots), once, inputScope);
|
|||
|
|
if (key !== void 0) {
|
|||
|
|
frag.$key = key;
|
|||
|
|
frag.setKey(key);
|
|||
|
|
}
|
|||
|
|
if (_insertionParent) registerNestedVDOMCleanup(frag);
|
|||
|
|
if (!isHydrating$1) {
|
|||
|
|
if (_insertionParent) insert(frag, _insertionParent, _insertionAnchor, currentRenderContext.suspense);
|
|||
|
|
} else frag.hydrate();
|
|||
|
|
return frag;
|
|||
|
|
}
|
|||
|
|
const instance = new VaporComponentInstance(component, rawProps, rawSlots, appContext, ce);
|
|||
|
|
if (key !== void 0) instance.$key = key;
|
|||
|
|
if (inputScope) {
|
|||
|
|
instance.inputScope = inputScope;
|
|||
|
|
instance.hasFallthrough = true;
|
|||
|
|
}
|
|||
|
|
if (asyncBoundary) markAsyncBoundary(instance);
|
|||
|
|
if (isKeepAliveEnabled && !(isAsyncComponentEnabled && isAsyncWrapper(instance))) {
|
|||
|
|
keepAliveCtx || (keepAliveCtx = getKeepAliveContext(currentInstance));
|
|||
|
|
if (keepAliveCtx) keepAliveCtx.processShapeFlag(instance);
|
|||
|
|
}
|
|||
|
|
const outerCtx = currentRenderContext;
|
|||
|
|
setRenderContext(deriveRenderContext(outerCtx, null, outerCtx.slotBoundary, null, outerCtx.suspense));
|
|||
|
|
let hasWarningContext = false;
|
|||
|
|
let hasInitMeasure = false;
|
|||
|
|
try {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) {
|
|||
|
|
registerHMR(instance);
|
|||
|
|
instance.isSingleRoot = isSingleRoot;
|
|||
|
|
instance.hmrRerender = hmrRerender.bind(null, instance);
|
|||
|
|
instance.hmrReload = hmrReload.bind(null, instance);
|
|||
|
|
pushWarningContext(instance);
|
|||
|
|
hasWarningContext = true;
|
|||
|
|
startMeasure(instance, `init`);
|
|||
|
|
hasInitMeasure = true;
|
|||
|
|
instance.propsOptions = normalizePropsOptions(component);
|
|||
|
|
instance.emitsOptions = normalizeEmitsOptions(component);
|
|||
|
|
}
|
|||
|
|
try {
|
|||
|
|
initSlots(instance);
|
|||
|
|
initInputs(instance, once);
|
|||
|
|
} catch (error) {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) unregisterHMR(instance);
|
|||
|
|
instance.scope.stop();
|
|||
|
|
if (inputScope) inputScope.stop();
|
|||
|
|
throw error;
|
|||
|
|
}
|
|||
|
|
if (isHydrating$1 && isAsyncComponentEnabled && isAsyncWrapper(instance) && component.__asyncHydrate) {
|
|||
|
|
const setup = () => setupComponent(instance, component);
|
|||
|
|
component.__asyncHydrate(currentHydrationNode, instance, wasInOnce ? () => withOnce(setup, false) : setup);
|
|||
|
|
} else {
|
|||
|
|
if (wasInOnce) withOnce(() => setupComponent(instance, component), false);
|
|||
|
|
else setupComponent(instance, component);
|
|||
|
|
if (isHydrating$1 && isSuspenseEnabled && instance.suspense && instance.asyncDep) {
|
|||
|
|
const pendingBlock = [];
|
|||
|
|
const { claim, cursor } = hydration;
|
|||
|
|
let node = claim && claim.start || cursor.start;
|
|||
|
|
const hydrationNext = nextLogicalSibling(node);
|
|||
|
|
do {
|
|||
|
|
pendingBlock.push(node);
|
|||
|
|
node = node.nextSibling;
|
|||
|
|
} while (node !== hydrationNext);
|
|||
|
|
instance.pendingBlock = pendingBlock.length === 1 ? pendingBlock[0] : pendingBlock;
|
|||
|
|
advanceHydrationNode(pendingBlock[pendingBlock.length - 1]);
|
|||
|
|
pendingAsyncHydration = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} finally {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) {
|
|||
|
|
if (hasWarningContext) popWarningContext();
|
|||
|
|
if (hasInitMeasure) endMeasure(instance, "init");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (keepAliveCtx) instance.unmountScope = getCurrentScope();
|
|||
|
|
registerUnmount(instance);
|
|||
|
|
if (_insertionParent) registerNestedVDOMCleanup(instance);
|
|||
|
|
if (!managedMount && (_insertionParent || isHydrating$1)) mountComponent(instance, _insertionParent, _insertionAnchor);
|
|||
|
|
return instance;
|
|||
|
|
} finally {
|
|||
|
|
setRenderContext(prevCtx);
|
|||
|
|
if (hydration) exitComponentHydration(hydration, !pendingAsyncHydration);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Open a component's SSR range: locate its start and claim its markers.
|
|||
|
|
* Shared by creation and by the deferred render of an async setup, which
|
|||
|
|
* re-enters the range once setup has settled.
|
|||
|
|
*/
|
|||
|
|
function enterComponentHydration(component) {
|
|||
|
|
const claim = component.__multiRoot ? createFragmentClaim() : void 0;
|
|||
|
|
const cursor = enterHydrationCursor(claim);
|
|||
|
|
const close = claim && claim.start ? locateEndAnchor(claim.start) : null;
|
|||
|
|
if (close) claimAnchor(close);
|
|||
|
|
return {
|
|||
|
|
claim,
|
|||
|
|
cursor,
|
|||
|
|
close
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Hand the cursor back; with `finalizeBoundary` the unclaimed tail of the
|
|||
|
|
* range is trimmed first and the cursor moves past the close marker.
|
|||
|
|
*/
|
|||
|
|
function exitComponentHydration({ close, cursor }, finalizeBoundary) {
|
|||
|
|
if (finalizeBoundary) {
|
|||
|
|
trimHydrationBoundary(close);
|
|||
|
|
if (close && currentHydrationNode === close) advanceHydrationNode(close);
|
|||
|
|
}
|
|||
|
|
exitHydrationCursor(cursor);
|
|||
|
|
}
|
|||
|
|
function setupComponent(instance, component) {
|
|||
|
|
const prevInstance = setCurrentInstance(instance);
|
|||
|
|
const prevSub = setActiveSub();
|
|||
|
|
const setupFn = isFunction(component) ? component : component.setup;
|
|||
|
|
const setupResult = setupFn ? callWithErrorHandling(setupFn, instance, 0, [instance.props, instance]) || EMPTY_OBJ : component.__cssModules || EMPTY_OBJ;
|
|||
|
|
const isAsyncSetup = isPromise(setupResult);
|
|||
|
|
if ((isAsyncSetup || instance.sp) && !(isAsyncComponentEnabled && isAsyncWrapper(instance))) markAsyncBoundary(instance);
|
|||
|
|
if (isAsyncSetup) {
|
|||
|
|
instance.asyncDep = setupResult;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && !instance.suspense) {
|
|||
|
|
var _getComponentName;
|
|||
|
|
const name = (_getComponentName = getComponentName(component)) !== null && _getComponentName !== void 0 ? _getComponentName : "Anonymous";
|
|||
|
|
warn(`Component <${name}>: setup function returned a promise, but no <Suspense> boundary was found in the parent component tree. A component with async setup() must be nested in a <Suspense> in order to be rendered.`);
|
|||
|
|
}
|
|||
|
|
} else handleSetupResult(setupResult, component, instance);
|
|||
|
|
setActiveSub(prevSub);
|
|||
|
|
restoreCurrentInstance(prevInstance);
|
|||
|
|
}
|
|||
|
|
let isApplyingFallthroughProps = false;
|
|||
|
|
function shouldUseFunctionalFallthrough(component) {
|
|||
|
|
return isFunction(component) && !component.props && !(isTransitionEnabled && isVaporTransition(component));
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* The single source of truth for the attrs a component may fall through to
|
|||
|
|
* its effective root — used both for the root element render effect and for
|
|||
|
|
* forwarding into a root component's props. Functional components without
|
|||
|
|
* declared props only pass class / style / event listeners; v-model
|
|||
|
|
* listeners with a corresponding declared prop never fall through (the
|
|||
|
|
* component handles the v-model itself — #1543, #1643, #1989). Never
|
|||
|
|
* returns undefined so consumers can always diff away stale keys.
|
|||
|
|
*/
|
|||
|
|
function resolveFallthroughAttrs(instance) {
|
|||
|
|
const attrs = shouldUseFunctionalFallthrough(instance.type) ? getFunctionalFallthrough(instance.attrs) || EMPTY_OBJ : instance.attrs;
|
|||
|
|
const propsOptions = normalizePropsOptions(instance.type)[0];
|
|||
|
|
if (propsOptions) {
|
|||
|
|
for (const key in attrs) if (isModelListener(key)) return filterModelListeners(attrs, propsOptions);
|
|||
|
|
}
|
|||
|
|
return attrs;
|
|||
|
|
}
|
|||
|
|
function applyFallthroughProps(el, attrs) {
|
|||
|
|
isApplyingFallthroughProps = true;
|
|||
|
|
try {
|
|||
|
|
patchDynamicProps(el, attrs);
|
|||
|
|
} finally {
|
|||
|
|
isApplyingFallthroughProps = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* dev only
|
|||
|
|
*/
|
|||
|
|
function createDevSetupStateProxy(setupState) {
|
|||
|
|
return new Proxy(setupState, { get(target, key, receiver) {
|
|||
|
|
if (isString(key) && !key.startsWith("__v") && !hasOwn(toRaw(setupState), key)) warn(`Property ${JSON.stringify(key)} was accessed during render but is not defined on instance.`);
|
|||
|
|
return Reflect.get(target, key, receiver);
|
|||
|
|
} });
|
|||
|
|
}
|
|||
|
|
function callRender(render, instance, setupState) {
|
|||
|
|
return callWithErrorHandling(render, instance, 1, [
|
|||
|
|
setupState,
|
|||
|
|
instance.props,
|
|||
|
|
instance.emit,
|
|||
|
|
instance.attrs,
|
|||
|
|
instance.slots
|
|||
|
|
]);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* dev only
|
|||
|
|
* Runs devRender with everything it creates owned by a fresh per-render
|
|||
|
|
* scope, so HMR rerender can tear down one generation by stopping the
|
|||
|
|
* scope - including components nested inside elements, which the block
|
|||
|
|
* graph cannot reach.
|
|||
|
|
*/
|
|||
|
|
function runDevRender(instance) {
|
|||
|
|
instance.accessedAttrs = instance.props === instance.attrs;
|
|||
|
|
(instance.renderScope = new EffectScope()).run(() => devRender(instance));
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* dev only
|
|||
|
|
*/
|
|||
|
|
function devRender(instance) {
|
|||
|
|
const prev = setCurrentRenderingInstance(instance);
|
|||
|
|
try {
|
|||
|
|
instance.block = (instance.type.render ? callRender(instance.type.render, instance, instance.setupState) : callWithErrorHandling(isFunction(instance.type) ? instance.type : instance.type.setup, instance, 0, [instance.props, {
|
|||
|
|
slots: instance.slots,
|
|||
|
|
attrs: instance.attrs,
|
|||
|
|
emit: instance.emit,
|
|||
|
|
expose: instance.expose
|
|||
|
|
}])) || [];
|
|||
|
|
} finally {
|
|||
|
|
setCurrentRenderingInstance(prev);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
const emptyContext = {
|
|||
|
|
app: null,
|
|||
|
|
config: {},
|
|||
|
|
provides: /*@__PURE__*/ Object.create(null)
|
|||
|
|
};
|
|||
|
|
var VaporComponentInstance = class {
|
|||
|
|
constructor(comp, rawProps, rawSlots, appContext, ce) {
|
|||
|
|
this.effectCount = 0;
|
|||
|
|
this.vapor = true;
|
|||
|
|
this.uid = nextUid();
|
|||
|
|
this.type = comp;
|
|||
|
|
this.parent = currentInstance;
|
|||
|
|
if (currentInstance) {
|
|||
|
|
this.root = currentInstance.root;
|
|||
|
|
this.appContext = currentInstance.appContext;
|
|||
|
|
this.provides = currentInstance.provides;
|
|||
|
|
this.ids = currentInstance.ids;
|
|||
|
|
} else {
|
|||
|
|
this.root = this;
|
|||
|
|
this.appContext = appContext || emptyContext;
|
|||
|
|
this.provides = Object.create(this.appContext.provides);
|
|||
|
|
this.ids = [
|
|||
|
|
"",
|
|||
|
|
0,
|
|||
|
|
0
|
|||
|
|
];
|
|||
|
|
}
|
|||
|
|
this.block = null;
|
|||
|
|
this.scope = new EffectScope(true);
|
|||
|
|
this.emit = emit.bind(null, this);
|
|||
|
|
this.expose = expose.bind(null, this);
|
|||
|
|
this.refs = EMPTY_OBJ;
|
|||
|
|
this.emitted = this.exposed = this.exposeProxy = this.propsDefaults = null;
|
|||
|
|
this.suspense = null;
|
|||
|
|
this.suspenseId = 0;
|
|||
|
|
if (isSuspenseEnabled) {
|
|||
|
|
const suspense = this.suspense = currentRenderContext.suspense;
|
|||
|
|
this.suspenseId = suspense ? suspense.pendingId : 0;
|
|||
|
|
}
|
|||
|
|
this.asyncDep = null;
|
|||
|
|
this.asyncResolved = false;
|
|||
|
|
this.isMounted = this.isUnmounted = this.isUpdating = this.isDeactivated = false;
|
|||
|
|
this.propsValues = Object.create(null);
|
|||
|
|
this.rawValues = INITIAL_RAW_VALUES;
|
|||
|
|
this.propsDeps = void 0;
|
|||
|
|
this.hasDynamicProps = true;
|
|||
|
|
this.rawProps = rawProps || EMPTY_OBJ;
|
|||
|
|
this.hasFallthrough = !!ce || hasFallthroughAttrs(comp, this.rawProps);
|
|||
|
|
const [propsHandlers, attrsHandlers] = getPropsProxyHandlers(comp);
|
|||
|
|
this.attrs = new Proxy(this, attrsHandlers);
|
|||
|
|
this.props = comp.props ? new Proxy(this, propsHandlers) : isFunction(comp) ? this.attrs : EMPTY_OBJ;
|
|||
|
|
const normalizedRawSlots = normalizeRawSlots(rawSlots);
|
|||
|
|
this.rawSlots = normalizedRawSlots || EMPTY_OBJ;
|
|||
|
|
this.slots = normalizedRawSlots ? new Proxy(normalizedRawSlots, dynamicSlotsProxyHandlers) : EMPTY_OBJ;
|
|||
|
|
this.scopeId = getCurrentScopeId();
|
|||
|
|
this.slotScopeIds = currentRenderContext.slotScopeIds;
|
|||
|
|
if (ce) ce(this);
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) {
|
|||
|
|
if (this.props === this.attrs) this.accessedAttrs = true;
|
|||
|
|
else {
|
|||
|
|
const attrs = this.attrs;
|
|||
|
|
const instance = this;
|
|||
|
|
this.attrs = new Proxy(attrs, { get(target, key, receiver) {
|
|||
|
|
instance.accessedAttrs = true;
|
|||
|
|
return Reflect.get(target, key, receiver);
|
|||
|
|
} });
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
rawKeys() {
|
|||
|
|
const vnode = isInteropEnabled && this.interopVNode;
|
|||
|
|
return Object.keys(vnode ? vnode.props || EMPTY_OBJ : this.rawValues);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
function isVaporComponent(value) {
|
|||
|
|
return value instanceof VaporComponentInstance;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Resolve an asset component by name before passing it to the fallback helper;
|
|||
|
|
* a string passed directly to `createComponentWithFallback` is plain element
|
|||
|
|
* fallback, not a component name.
|
|||
|
|
*/
|
|||
|
|
function createAssetComponent(name, rawProps, rawSlots, isSingleRoot, once, maybeSelfReference, ns, appContext) {
|
|||
|
|
return createComponentWithFallback(resolveComponent(name, maybeSelfReference), rawProps, rawSlots, isSingleRoot, once, ns, appContext);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Used when a component cannot be resolved at compile time
|
|||
|
|
* and needs rely on runtime resolution - where it might fallback to a plain
|
|||
|
|
* element if the resolution fails.
|
|||
|
|
*/
|
|||
|
|
function createComponentWithFallback(comp, rawProps, rawSlots, isSingleRoot, once, ns, appContext) {
|
|||
|
|
if (comp === NULL_DYNAMIC_COMPONENT) {
|
|||
|
|
if (isHydrating$1 && currentHydrationNode) {
|
|||
|
|
if (isReusableNullComponentAnchor(currentHydrationNode)) {
|
|||
|
|
const node = currentHydrationNode;
|
|||
|
|
if (isComment(node, "")) advanceHydrationNode(node);
|
|||
|
|
return node;
|
|||
|
|
}
|
|||
|
|
const nextAnchor = nextLogicalSibling(currentHydrationNode);
|
|||
|
|
if (nextAnchor && isReusableNullComponentAnchor(nextAnchor)) return nextAnchor;
|
|||
|
|
}
|
|||
|
|
return !!(process.env.NODE_ENV !== "production") ? /* @__PURE__ */ createComment("ndc") : /* @__PURE__ */ createTextNode("");
|
|||
|
|
}
|
|||
|
|
if (!isString(comp)) return createComponent(comp, rawProps, rawSlots, isSingleRoot, once, appContext);
|
|||
|
|
return createPlainElement(comp, rawProps, rawSlots, isSingleRoot, once, ns);
|
|||
|
|
}
|
|||
|
|
function isReusableNullComponentAnchor(node) {
|
|||
|
|
return isComment(node, "") || !!(process.env.NODE_ENV !== "production") && (isComment(node, "dynamic-component") || isComment(node, "async component") || isComment(node, "keyed"));
|
|||
|
|
}
|
|||
|
|
function createPlainElement(comp, rawProps, rawSlots, isSingleRoot, once, ns) {
|
|||
|
|
rawSlots = normalizeRawSlots(rawSlots);
|
|||
|
|
const _insertionParent = insertionParent;
|
|||
|
|
const _insertionAnchor = insertionAnchor;
|
|||
|
|
let hydrationCursor = null;
|
|||
|
|
if (isHydrating$1) hydrationCursor = enterHydrationCursor();
|
|||
|
|
else resetInsertionState();
|
|||
|
|
const defaultSlot = rawSlots && getSlot(rawSlots, "default");
|
|||
|
|
const hasDynamicSlots = !!rawSlots && !!rawSlots.$;
|
|||
|
|
const adoptHydrationChildren = !!defaultSlot;
|
|||
|
|
const hydrationTemplate = hasDynamicSlots && !defaultSlot ? `<${comp}><!></${comp}>` : `<${comp}/>`;
|
|||
|
|
const el = isHydrating$1 ? adoptTemplate(currentHydrationNode, hydrationTemplate, adoptHydrationChildren, ns) : /* @__PURE__ */ createElement(comp, ns);
|
|||
|
|
el.$root = isSingleRoot;
|
|||
|
|
if ((isKeepAliveEnabled || isTransitionEnabled) && rawProps) {
|
|||
|
|
const key = resolveSource(rawProps.key);
|
|||
|
|
if (key !== void 0) el.$key = key;
|
|||
|
|
}
|
|||
|
|
if (!isHydrating$1 || isRecreatedNode(el)) {
|
|||
|
|
const scopeId = getCurrentScopeId();
|
|||
|
|
if (scopeId) el.setAttribute(scopeId, "");
|
|||
|
|
const slotScopeIds = currentRenderContext.slotScopeIds;
|
|||
|
|
if (slotScopeIds) setElementScopeIds(el, slotScopeIds);
|
|||
|
|
}
|
|||
|
|
if (rawProps) {
|
|||
|
|
const isSVG = ns === 1;
|
|||
|
|
const setFn = () => patchDynamicProps(el, resolveDynamicProps(rawProps), isSVG, isHydrating$1 ? getStaticBindingKeys(rawProps) : void 0);
|
|||
|
|
if (once) setFn();
|
|||
|
|
else renderEffect(setFn);
|
|||
|
|
}
|
|||
|
|
if (rawSlots) {
|
|||
|
|
let nextNode = null;
|
|||
|
|
if (isHydrating$1) {
|
|||
|
|
nextNode = nextLogicalSibling(el);
|
|||
|
|
let child = el.firstChild;
|
|||
|
|
if (rawSlots.$ && !child) child = el.appendChild(claimAnchor(!!(process.env.NODE_ENV !== "production") ? /* @__PURE__ */ createComment("") : /* @__PURE__ */ createTextNode()));
|
|||
|
|
setCurrentHydrationNode(child);
|
|||
|
|
}
|
|||
|
|
if (rawSlots.$) {
|
|||
|
|
const frag = new DynamicFragment(512, !!(process.env.NODE_ENV !== "production") ? isHydrating$1 ? "" : "slot" : void 0);
|
|||
|
|
if (isHydrating$1) locateHydrationNode();
|
|||
|
|
renderEffect(() => frag.update(getSlot(rawSlots, "default")));
|
|||
|
|
if (!isHydrating$1) insert(frag, el);
|
|||
|
|
registerNestedVDOMCleanup(frag);
|
|||
|
|
} else {
|
|||
|
|
const slot = getSlot(rawSlots, "default");
|
|||
|
|
if (slot) {
|
|||
|
|
let end;
|
|||
|
|
if (isHydrating$1) {
|
|||
|
|
end = el.appendChild(claimAnchor(/* @__PURE__ */ createComment("nce")));
|
|||
|
|
if (!currentHydrationNode) setCurrentHydrationNode(end);
|
|||
|
|
}
|
|||
|
|
const block = slot();
|
|||
|
|
if (end) el.removeChild(end);
|
|||
|
|
if (!isHydrating$1) insert(block, el);
|
|||
|
|
registerNestedVDOMCleanup(block);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (isHydrating$1) setCurrentHydrationNode(nextNode);
|
|||
|
|
}
|
|||
|
|
finishBlockCreation(el, void 0, hydrationCursor, _insertionParent, _insertionAnchor);
|
|||
|
|
return el;
|
|||
|
|
}
|
|||
|
|
function mountComponent(instance, parent, anchor) {
|
|||
|
|
if (isSuspenseEnabled && instance.suspense && instance.asyncDep && !instance.asyncResolved) {
|
|||
|
|
if (instance.asyncDepRegistered) {
|
|||
|
|
if (instance.pendingBlock) insert(instance.pendingBlock, parent, anchor);
|
|||
|
|
else if (instance.block) insert(instance.block, parent, anchor);
|
|||
|
|
if (isKeepAliveEnabled && instance.shapeFlag & 512) instance.isDeactivated = false;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
const suspense = instance.suspense;
|
|||
|
|
const deferred = isKeepAliveEnabled && deferKeepAliveRenderEffects(instance);
|
|||
|
|
const hydrating = isHydrating$1;
|
|||
|
|
if (!hydrating) {
|
|||
|
|
instance.block = /* @__PURE__ */ createComment("");
|
|||
|
|
insert(instance.block, parent, anchor);
|
|||
|
|
}
|
|||
|
|
instance.asyncDepRegistered = true;
|
|||
|
|
const component = instance.type;
|
|||
|
|
let asyncSetupFinished = false;
|
|||
|
|
const finishAsyncSetup = (setupResult) => {
|
|||
|
|
if (asyncSetupFinished) return;
|
|||
|
|
asyncSetupFinished = true;
|
|||
|
|
instance.asyncResolved = true;
|
|||
|
|
const handleResult = () => {
|
|||
|
|
const prevInstance = setCurrentInstance(instance);
|
|||
|
|
const prevSub = setActiveSub();
|
|||
|
|
try {
|
|||
|
|
handleSetupResult(setupResult, component, instance);
|
|||
|
|
} finally {
|
|||
|
|
setActiveSub(prevSub);
|
|||
|
|
restoreCurrentInstance(prevInstance);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
try {
|
|||
|
|
const pendingBlock = hydrating ? instance.pendingBlock : instance.block;
|
|||
|
|
const { parentNode, nextNode } = findBlockBoundary(pendingBlock);
|
|||
|
|
const renderAndMount = () => {
|
|||
|
|
handleResult();
|
|||
|
|
mountComponent(instance, parentNode, nextNode);
|
|||
|
|
};
|
|||
|
|
if (hydrating) hydrateNode(getBlockFirstNode(pendingBlock), () => {
|
|||
|
|
const hydration = enterComponentHydration(component);
|
|||
|
|
try {
|
|||
|
|
withDeferredHydrationBoundary(renderAndMount);
|
|||
|
|
} finally {
|
|||
|
|
exitComponentHydration(hydration, true);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
else {
|
|||
|
|
renderAndMount();
|
|||
|
|
remove(pendingBlock, parentNode);
|
|||
|
|
}
|
|||
|
|
} finally {
|
|||
|
|
if (hydrating) instance.pendingBlock = void 0;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
suspense.registerDep(instance, (setupResult) => {
|
|||
|
|
if (deferred) {
|
|||
|
|
if (deferred.pendingRoot === instance) deferred.pendingRoot = void 0;
|
|||
|
|
if (!deferred.flushQueued) {
|
|||
|
|
deferred.flushQueued = true;
|
|||
|
|
queuePostRenderEffect(deferred.flushJob, void 0, deferred.suspense);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
finishAsyncSetup(setupResult);
|
|||
|
|
});
|
|||
|
|
if (deferred) {
|
|||
|
|
const state = deferred;
|
|||
|
|
instance.asyncDep.catch(NOOP).then((setupResult) => {
|
|||
|
|
if (asyncSetupFinished) return;
|
|||
|
|
if (!instance.isUnmounted && !suspense.isUnmounted && !suspense.pendingBranch) finishAsyncSetup(setupResult);
|
|||
|
|
if (!state.flushQueued && state.pendingRoot === instance) settleDeferredKeepAliveUpdates(state);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (isKeepAliveEnabled && instance.shapeFlag & 512 && instance.isMounted) {
|
|||
|
|
instance.parent.ctx.activate(instance, parent, anchor);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
const { root, type } = instance;
|
|||
|
|
if (root && root.ce && root.ce._hasShadowRoot()) root.ce._injectChildStyle(type, instance.parent ? instance.parent.type : void 0);
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) startMeasure(instance, `mount`);
|
|||
|
|
if (instance.bm) invokeArrayFns(instance.bm);
|
|||
|
|
if (!isHydrating$1) {
|
|||
|
|
applyComponentScopeIds(instance);
|
|||
|
|
insert(instance.block, parent, anchor, instance.suspense);
|
|||
|
|
} else hydrateComponentScopeIds(instance);
|
|||
|
|
if (instance.m) queuePostRenderEffect(instance.m, void 0, instance.suspense);
|
|||
|
|
if (isKeepAliveEnabled && instance.shapeFlag & 256 && instance.a) queuePostRenderEffect(instance.a, void 0, instance.suspense);
|
|||
|
|
instance.isMounted = true;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) endMeasure(instance, `mount`);
|
|||
|
|
}
|
|||
|
|
function registerUnmount(instance) {
|
|||
|
|
const scope = instance.unmountScope;
|
|||
|
|
onScopeDispose$1(() => {
|
|||
|
|
if (scope && instance.unmountScope === scope) instance.unmountScope = void 0;
|
|||
|
|
unmountComponent(instance, void 0, isInteropEnabled ? resolveUnmountSuspense(instance.suspense) : instance.suspense);
|
|||
|
|
}, true);
|
|||
|
|
}
|
|||
|
|
function unmountComponent(instance, parentNode, parentSuspense = instance.suspense) {
|
|||
|
|
if (isSuspenseEnabled && isInteropEnabled && currentUnmountSuspense !== parentSuspense) {
|
|||
|
|
runWithUnmountSuspense(parentSuspense, () => unmountComponent(instance, parentNode, parentSuspense));
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (isKeepAliveEnabled && instance.shapeFlag & 256 && instance.parent && instance.parent.vapor && instance.parent.ctx) {
|
|||
|
|
if (parentNode) instance.parent.ctx.deactivate(instance, parentSuspense);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
const pendingAsyncSetup = !!instance.asyncDep && !instance.asyncResolved;
|
|||
|
|
if (!instance.isUnmounted) {
|
|||
|
|
const hasLifecycle = instance.isMounted || pendingAsyncSetup;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) unregisterHMR(instance);
|
|||
|
|
if (hasLifecycle) {
|
|||
|
|
invalidateMount(instance.m);
|
|||
|
|
invalidateMount(instance.a);
|
|||
|
|
if (instance.bum) invokeArrayFns(instance.bum);
|
|||
|
|
}
|
|||
|
|
if (isKeepAliveEnabled) {
|
|||
|
|
const inputScope = instance.inputScope;
|
|||
|
|
if (inputScope) inputScope.stop();
|
|||
|
|
}
|
|||
|
|
instance.scope.stop();
|
|||
|
|
if (hasLifecycle && instance.um) queuePostRenderEffect(instance.um, void 0, parentSuspense);
|
|||
|
|
instance.isUnmounted = true;
|
|||
|
|
}
|
|||
|
|
if (isSuspenseEnabled && pendingAsyncSetup) {
|
|||
|
|
if (instance.pendingBlock) {
|
|||
|
|
if (parentNode) {
|
|||
|
|
const pendingBlock = instance.pendingBlock;
|
|||
|
|
const { parentNode: blockParent } = findBlockBoundary(pendingBlock);
|
|||
|
|
if (blockParent) remove(pendingBlock, blockParent);
|
|||
|
|
instance.pendingBlock = void 0;
|
|||
|
|
}
|
|||
|
|
} else if (instance.block instanceof Comment) {
|
|||
|
|
const blockParent = instance.block.parentNode;
|
|||
|
|
if (blockParent) remove(instance.block, blockParent);
|
|||
|
|
}
|
|||
|
|
} else if (parentNode) {
|
|||
|
|
if (instance.block) remove(instance.block, parentNode);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function getExposed(instance) {
|
|||
|
|
if (instance.exposed) return instance.exposeProxy || (instance.exposeProxy = new Proxy(markRaw(instance.exposed), {
|
|||
|
|
get: (target, key) => unref(target[key]),
|
|||
|
|
set: (target, key, value, receiver) => {
|
|||
|
|
const oldValue = target[key];
|
|||
|
|
if (isRef(oldValue) && !isRef(value)) {
|
|||
|
|
oldValue.value = value;
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
return Reflect.set(target, key, value, receiver);
|
|||
|
|
}
|
|||
|
|
}));
|
|||
|
|
}
|
|||
|
|
function getRootElement(block, visitor) {
|
|||
|
|
if (block instanceof Element) return block;
|
|||
|
|
if (isVaporComponent(block)) {
|
|||
|
|
if (visitor) {
|
|||
|
|
if (visitor.onComponent && visitor.onComponent(block)) return;
|
|||
|
|
if (visitor.stopAtComponent) return;
|
|||
|
|
}
|
|||
|
|
return getRootElement(block.block, visitor);
|
|||
|
|
}
|
|||
|
|
if (isFragment(block) && !(isTeleportEnabled && isTeleportFragment(block))) {
|
|||
|
|
if (visitor) {
|
|||
|
|
if (visitor.excludeSlotOutlets && isSlotOutletFragment(block)) return;
|
|||
|
|
if (isDynamicFragment(block) && visitor.onDynamicFragment && visitor.onDynamicFragment(block)) return;
|
|||
|
|
if (isInteropEnabled && visitor.onInteropFragment && isInteropFragment(block) && visitor.onInteropFragment(block)) return;
|
|||
|
|
}
|
|||
|
|
return getRootElement(block.nodes, visitor);
|
|||
|
|
}
|
|||
|
|
if (isArray(block)) {
|
|||
|
|
const single = singleRootOf(block);
|
|||
|
|
return single === void 0 ? void 0 : getRootElement(single, visitor);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function singleRootOf(nodes) {
|
|||
|
|
let single;
|
|||
|
|
let hasComment = false;
|
|||
|
|
for (const b of nodes) {
|
|||
|
|
if (b instanceof Comment) {
|
|||
|
|
hasComment = true;
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
if (single !== void 0) return;
|
|||
|
|
single = b;
|
|||
|
|
}
|
|||
|
|
return hasComment ? single : void 0;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Descends the same effective-root rules as getRootElement but stops at the
|
|||
|
|
* first component instead of resolving an element. Used to verify `child`
|
|||
|
|
* sits on `parent`'s root chain when the chain passes through fragments
|
|||
|
|
* (where `parent.block === child` cannot see the link).
|
|||
|
|
*/
|
|||
|
|
function getRootChainComponent(block) {
|
|||
|
|
while (true) {
|
|||
|
|
if (isVaporComponent(block)) return block;
|
|||
|
|
if (isFragment(block) && !(isTeleportEnabled && isTeleportFragment(block))) {
|
|||
|
|
if (isSlotOutletFragment(block)) return;
|
|||
|
|
block = block.nodes;
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
if (isArray(block)) {
|
|||
|
|
const single = singleRootOf(block);
|
|||
|
|
if (single === void 0) return;
|
|||
|
|
block = single;
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function handleSetupResult(setupResult, component, instance) {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) pushWarningContext(instance);
|
|||
|
|
if (isBlock(setupResult)) instance.block = setupResult;
|
|||
|
|
else if (isFunction(setupResult) && instance.asyncDep) instance.block = callWithErrorHandling(setupResult, instance, 1) || [];
|
|||
|
|
else if (isFunction(component)) {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) warn(`Functional vapor component must return a block directly.`);
|
|||
|
|
instance.block = [];
|
|||
|
|
} else if (!component.render) {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) warn(`Vapor component setup() returned non-block value, and has no render function.`);
|
|||
|
|
instance.block = [];
|
|||
|
|
} else {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") || __VUE_PROD_DEVTOOLS__) instance.devtoolsRawSetupState = setupResult;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) {
|
|||
|
|
instance.setupState = createDevSetupStateProxy(proxyRefs(setupResult));
|
|||
|
|
runDevRender(instance);
|
|||
|
|
} else instance.block = callRender(component.render, instance, setupResult) || [];
|
|||
|
|
}
|
|||
|
|
applyComponentFallthrough(instance);
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) popWarningContext();
|
|||
|
|
}
|
|||
|
|
function applyComponentFallthrough(instance) {
|
|||
|
|
if (instance.hasFallthrough && instance.type.inheritAttrs !== false) applyFallthroughAttrs(instance.block, instance, !!(process.env.NODE_ENV !== "production") ? instance.renderScope : void 0);
|
|||
|
|
}
|
|||
|
|
function applyFallthroughAttrs(block, instance, scope) {
|
|||
|
|
const state = new FallthroughResolveState(scope);
|
|||
|
|
const root = resolveFallthroughRoot(block, state);
|
|||
|
|
const { fragments, innermost, hasSlotOutlet } = state;
|
|||
|
|
if (fragments) for (const frag of fragments) registerDynamicFragmentFallthroughAttrs(frag, instance);
|
|||
|
|
if (root && !hasSlotOutlet) {
|
|||
|
|
let ownerScope = scope;
|
|||
|
|
if (innermost) ownerScope = innermost.scope || (innermost.scope = state.parentScope ? state.parentScope.run(() => new EffectScope()) : new EffectScope());
|
|||
|
|
const applyEffect = () => renderEffect(() => applyFallthroughProps(root, resolveFallthroughAttrs(instance)));
|
|||
|
|
ownerScope ? ownerScope.run(applyEffect) : applyEffect();
|
|||
|
|
} else if (!!(process.env.NODE_ENV !== "production")) {
|
|||
|
|
const accessedAttrs = instance.accessedAttrs;
|
|||
|
|
const fallthroughAttrs = resolveFallthroughAttrs(instance);
|
|||
|
|
if (Object.keys(fallthroughAttrs).length && (hasSlotOutlet || fragments && state.hasNonSingleRoot || isTeleportEnabled && containsTeleportFragment(block) || !accessedAttrs && (block instanceof Text || isArray(block) && block.length))) warnExtraneousAttributes(instance.attrs);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
var FallthroughResolveState = class {
|
|||
|
|
constructor(parentScope) {
|
|||
|
|
this.stopAtComponent = true;
|
|||
|
|
this.parentScope = parentScope;
|
|||
|
|
}
|
|||
|
|
onDynamicFragment(frag) {
|
|||
|
|
if (frag.__vf & 4) {
|
|||
|
|
this.hasSlotOutlet = true;
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
(this.fragments || (this.fragments = [])).push(frag);
|
|||
|
|
if (this.innermost && this.innermost.scope) this.parentScope = this.innermost.scope;
|
|||
|
|
this.innermost = frag;
|
|||
|
|
}
|
|||
|
|
onInteropFragment(frag) {
|
|||
|
|
if (isSlotOutletFragment(frag)) return this.hasSlotOutlet = true;
|
|||
|
|
return !!frag.vnode;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
function resolveFallthroughRoot(block, state) {
|
|||
|
|
const root = getRootElement(block, state);
|
|||
|
|
const { innermost } = state;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && !root && innermost) {
|
|||
|
|
const { nodes } = innermost;
|
|||
|
|
state.hasNonSingleRoot = isArray(nodes) && nodes.some((child) => !(child instanceof Comment));
|
|||
|
|
}
|
|||
|
|
return root;
|
|||
|
|
}
|
|||
|
|
function containsTeleportFragment(block) {
|
|||
|
|
if (isTeleportFragment(block)) return true;
|
|||
|
|
if (isArray(block)) return block.some((child) => !(child instanceof Comment) && containsTeleportFragment(child));
|
|||
|
|
return isFragment(block) && containsTeleportFragment(block.nodes);
|
|||
|
|
}
|
|||
|
|
function registerDynamicFragmentFallthroughAttrs(frag, instance) {
|
|||
|
|
if (frag.fallthrough) return;
|
|||
|
|
frag.fallthrough = (nodes) => applyFallthroughAttrs(nodes, instance, frag.scope);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* A deferred state stays live while its async root is pending or its flush is
|
|||
|
|
* queued for the same Suspense generation. The flush is requeued if that
|
|||
|
|
* generation is discarded, so `flushQueued` cannot strand buffered updates.
|
|||
|
|
*/
|
|||
|
|
function isDeferredKeepAliveStateLive(state) {
|
|||
|
|
const suspense = state.suspense;
|
|||
|
|
if (suspense.isUnmounted || state.pendingId !== suspense.pendingId) return false;
|
|||
|
|
if (state.flushQueued) return true;
|
|||
|
|
const root = state.pendingRoot;
|
|||
|
|
return !!root && !root.isUnmounted;
|
|||
|
|
}
|
|||
|
|
function settleDeferredKeepAliveUpdates(state, currentJob) {
|
|||
|
|
const { effects, owners } = state;
|
|||
|
|
state.effects = [];
|
|||
|
|
state.owners = [];
|
|||
|
|
state.pendingRoot = void 0;
|
|||
|
|
for (let i = 0; i < owners.length; i++) if (owners[i].deferredKeepAliveUpdates === state) owners[i].deferredKeepAliveUpdates = void 0;
|
|||
|
|
if (currentJob && !effects.includes(currentJob)) effects.push(currentJob);
|
|||
|
|
if (effects.length > 1) effects.sort((a, b) => a.order - b.order);
|
|||
|
|
for (let i = 0; i < effects.length; i++) {
|
|||
|
|
const job = effects[i];
|
|||
|
|
callWithErrorHandling(job, job.i, job.i ? 15 : 14);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function deferKeepAliveRenderEffects(instance) {
|
|||
|
|
const suspense = instance.suspense;
|
|||
|
|
const owners = [];
|
|||
|
|
let keepAlive;
|
|||
|
|
if (isHydrating$1) {
|
|||
|
|
const owner = instance.parent;
|
|||
|
|
if (owner && owner.vapor && isKeepAlive(owner) && owner.suspense === suspense) {
|
|||
|
|
keepAlive = owner;
|
|||
|
|
owners.push(keepAlive);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
let child = instance;
|
|||
|
|
let owner = instance.parent;
|
|||
|
|
while (owner && owner.vapor && owner.suspense === suspense) {
|
|||
|
|
const vaporOwner = owner;
|
|||
|
|
let root = vaporOwner.block;
|
|||
|
|
while (isDynamicFragment(root) && !(root.__vf & 4)) root = root.nodes;
|
|||
|
|
if (root !== child) return;
|
|||
|
|
owners.push(vaporOwner);
|
|||
|
|
if (isKeepAlive(owner)) keepAlive = vaporOwner;
|
|||
|
|
child = vaporOwner;
|
|||
|
|
owner = vaporOwner.parent;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (!keepAlive) return;
|
|||
|
|
let deferred = keepAlive.deferredKeepAliveUpdates;
|
|||
|
|
if (!deferred || deferred.suspense !== suspense || deferred.pendingId !== instance.suspenseId) {
|
|||
|
|
const flushJob = () => {
|
|||
|
|
state.flushQueued = false;
|
|||
|
|
if (keepAlive.deferredKeepAliveUpdates !== state || state.pendingRoot) return;
|
|||
|
|
settleDeferredKeepAliveUpdates(state);
|
|||
|
|
};
|
|||
|
|
flushJob.flags = 8;
|
|||
|
|
const state = {
|
|||
|
|
effects: [],
|
|||
|
|
owners: [],
|
|||
|
|
suspense,
|
|||
|
|
pendingId: instance.suspenseId,
|
|||
|
|
pendingRoot: instance,
|
|||
|
|
flushQueued: false,
|
|||
|
|
flushJob
|
|||
|
|
};
|
|||
|
|
deferred = state;
|
|||
|
|
} else deferred.pendingRoot = instance;
|
|||
|
|
for (let i = 0; i < owners.length; i++) {
|
|||
|
|
const owner = owners[i];
|
|||
|
|
if (owner.deferredKeepAliveUpdates !== deferred) {
|
|||
|
|
owner.deferredKeepAliveUpdates = deferred;
|
|||
|
|
deferred.owners.push(owner);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return deferred;
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/apiCreateApp.ts
|
|||
|
|
let _createApp;
|
|||
|
|
const rootInstances = /* @__PURE__ */ new WeakMap();
|
|||
|
|
const mountApp = (app, container) => {
|
|||
|
|
optimizePropertyLookup();
|
|||
|
|
if (container.nodeType === 1) {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && container.childNodes.length) warn("mount target container is not empty and will be cleared.");
|
|||
|
|
container.textContent = "";
|
|||
|
|
}
|
|||
|
|
const instance = app._ceComponent || createComponent(app._component, app._props, null, false, false, app._context, true);
|
|||
|
|
mountComponent(instance, container);
|
|||
|
|
flushOnAppMount();
|
|||
|
|
rootInstances.set(app, instance);
|
|||
|
|
return instance;
|
|||
|
|
};
|
|||
|
|
let _hydrateApp;
|
|||
|
|
const hydrateApp = (app, container) => {
|
|||
|
|
if (!container.hasChildNodes()) {
|
|||
|
|
(process.env.NODE_ENV !== "production" || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && warn("Attempting to hydrate existing markup but container is empty. Performing full mount instead.");
|
|||
|
|
return mountApp(app, container);
|
|||
|
|
}
|
|||
|
|
optimizePropertyLookup();
|
|||
|
|
let instance;
|
|||
|
|
withHydration(container, () => {
|
|||
|
|
instance = app._ceComponent || createComponent(app._component, app._props, null, false, false, app._context, true);
|
|||
|
|
mountComponent(instance, container);
|
|||
|
|
flushOnAppMount();
|
|||
|
|
});
|
|||
|
|
rootInstances.set(app, instance);
|
|||
|
|
return instance;
|
|||
|
|
};
|
|||
|
|
const unmountApp = (app) => {
|
|||
|
|
const instance = !!(process.env.NODE_ENV !== "production") && app._instance || rootInstances.get(app);
|
|||
|
|
unmountComponent(instance, app._container);
|
|||
|
|
flushOnAppMount(instance);
|
|||
|
|
rootInstances.delete(app);
|
|||
|
|
};
|
|||
|
|
function prepareApp() {
|
|||
|
|
initFeatureFlags();
|
|||
|
|
const target = getGlobalThis();
|
|||
|
|
target.__VUE__ = true;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") || __VUE_PROD_DEVTOOLS__) setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__, target);
|
|||
|
|
}
|
|||
|
|
function postPrepareApp(app) {
|
|||
|
|
app.vapor = true;
|
|||
|
|
const mount = app.mount;
|
|||
|
|
app.mount = (container, ...args) => {
|
|||
|
|
container = normalizeContainer(container);
|
|||
|
|
if (!container) return;
|
|||
|
|
const proxy = mount(container, ...args);
|
|||
|
|
if (container instanceof Element) {
|
|||
|
|
container.removeAttribute("v-cloak");
|
|||
|
|
container.setAttribute("data-v-app", "");
|
|||
|
|
}
|
|||
|
|
return proxy;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
const createVaporApp = (comp, props) => {
|
|||
|
|
prepareApp();
|
|||
|
|
if (!_createApp) _createApp = createAppAPI(mountApp, unmountApp, getExposed);
|
|||
|
|
const app = _createApp(comp, props);
|
|||
|
|
postPrepareApp(app);
|
|||
|
|
return app;
|
|||
|
|
};
|
|||
|
|
const createVaporSSRApp = (comp, props) => {
|
|||
|
|
setIsHydratingEnabled(true);
|
|||
|
|
prepareApp();
|
|||
|
|
if (!_hydrateApp) _hydrateApp = createAppAPI(hydrateApp, unmountApp, getExposed);
|
|||
|
|
const app = _hydrateApp(comp, props);
|
|||
|
|
postPrepareApp(app);
|
|||
|
|
return app;
|
|||
|
|
};
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/apiDefineComponent.ts
|
|||
|
|
/*@__NO_SIDE_EFFECTS__*/
|
|||
|
|
function defineVaporComponent(comp, extraOptions) {
|
|||
|
|
if (isFunction(comp)) return /*@__PURE__*/ (() => extend$1({ name: comp.name }, extraOptions, {
|
|||
|
|
setup: comp,
|
|||
|
|
__vapor: true
|
|||
|
|
}))();
|
|||
|
|
comp.__vapor = true;
|
|||
|
|
return comp;
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/apiDefineAsyncComponent.ts
|
|||
|
|
function defineVaporAsyncComponent(source) {
|
|||
|
|
enableAsyncComponent();
|
|||
|
|
const { load, getResolvedComp, setPendingRequest, source: { loadingComponent, errorComponent, delay, hydrate: hydrateStrategy, timeout, suspensible = true } } = createAsyncComponentContext(source);
|
|||
|
|
return /* @__PURE__ */ defineVaporComponent({
|
|||
|
|
name: "VaporAsyncComponentWrapper",
|
|||
|
|
__asyncLoader: load,
|
|||
|
|
__asyncHydrate(el, instance, hydrate) {
|
|||
|
|
if (!isHydrating$1) return;
|
|||
|
|
const endAnchor = isRangeStart(el) ? locateEndAnchor(el) : null;
|
|||
|
|
let nodes;
|
|||
|
|
if (endAnchor) {
|
|||
|
|
const end = /* @__PURE__ */ _next(endAnchor);
|
|||
|
|
const range = nodes = [el];
|
|||
|
|
let cur = el;
|
|||
|
|
while (true) {
|
|||
|
|
let n = /* @__PURE__ */ _next(cur);
|
|||
|
|
if (n && n !== end) range.push(cur = n);
|
|||
|
|
else break;
|
|||
|
|
}
|
|||
|
|
} else nodes = el;
|
|||
|
|
const prev = setCurrentInstance(instance);
|
|||
|
|
try {
|
|||
|
|
const frag = new DynamicFragment(0, !!(process.env.NODE_ENV !== "production") ? "async component" : void 0);
|
|||
|
|
frag.nodes = nodes;
|
|||
|
|
instance.block = frag;
|
|||
|
|
} finally {
|
|||
|
|
restoreCurrentInstance(prev);
|
|||
|
|
}
|
|||
|
|
instance.isMounted = true;
|
|||
|
|
setCurrentHydrationNode(nextLogicalSibling(el));
|
|||
|
|
performAsyncHydrate(el, instance, () => hydrateNode(el, () => withDeferredHydrationBoundary(hydrate)), getResolvedComp, load, hydrateStrategy, false);
|
|||
|
|
},
|
|||
|
|
get __asyncResolved() {
|
|||
|
|
return getResolvedComp();
|
|||
|
|
},
|
|||
|
|
setup() {
|
|||
|
|
const instance = currentInstance;
|
|||
|
|
markAsyncBoundary(instance);
|
|||
|
|
const placeholder = instance.block;
|
|||
|
|
let frag;
|
|||
|
|
if (isHydrating$1 && isDynamicFragment(placeholder)) {
|
|||
|
|
frag = placeholder;
|
|||
|
|
frag.nodes = EMPTY_BLOCK;
|
|||
|
|
locateHydrationNode();
|
|||
|
|
} else {
|
|||
|
|
frag = new DynamicFragment(0, !!(process.env.NODE_ENV !== "production") ? "async component" : void 0);
|
|||
|
|
if (isHydrating$1) locateHydrationNode();
|
|||
|
|
}
|
|||
|
|
let resolvedComp = getResolvedComp();
|
|||
|
|
if (resolvedComp) {
|
|||
|
|
frag.update(() => createInnerComp(resolvedComp, instance));
|
|||
|
|
if (frag === placeholder) {
|
|||
|
|
const u = frag.u;
|
|||
|
|
if (u) u.forEach((hook) => hook(frag.nodes));
|
|||
|
|
}
|
|||
|
|
return frag;
|
|||
|
|
}
|
|||
|
|
const onError = (err) => {
|
|||
|
|
setPendingRequest(null);
|
|||
|
|
handleError(err, instance, 13, !errorComponent);
|
|||
|
|
};
|
|||
|
|
if (suspensible && instance.suspense) {
|
|||
|
|
const renderBranch = (render) => {
|
|||
|
|
if (!instance.isUnmounted) instance.scope.run(() => frag.update(render));
|
|||
|
|
};
|
|||
|
|
return load().then(() => {
|
|||
|
|
resolvedComp = getResolvedComp();
|
|||
|
|
if (resolvedComp) renderBranch(() => createInnerComp(resolvedComp, instance));
|
|||
|
|
return frag;
|
|||
|
|
}).catch((err) => {
|
|||
|
|
onError(err);
|
|||
|
|
if (errorComponent) renderBranch(() => createErrorComp(errorComponent, instance, () => err));
|
|||
|
|
return frag;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
const { loaded, error, delayed } = useAsyncComponentState(delay, timeout, onError, instance);
|
|||
|
|
load().then(() => {
|
|||
|
|
if (instance.isUnmounted) return;
|
|||
|
|
loaded.value = true;
|
|||
|
|
}).catch((err) => {
|
|||
|
|
if (instance.isUnmounted) {
|
|||
|
|
setPendingRequest(null);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
onError(err);
|
|||
|
|
error.value = err;
|
|||
|
|
});
|
|||
|
|
renderEffect(() => {
|
|||
|
|
resolvedComp = getResolvedComp();
|
|||
|
|
let render;
|
|||
|
|
let key;
|
|||
|
|
if (loaded.value && resolvedComp) {
|
|||
|
|
render = () => createInnerComp(resolvedComp, instance);
|
|||
|
|
key = 1;
|
|||
|
|
} else if (error.value && errorComponent) {
|
|||
|
|
render = () => createErrorComp(errorComponent, instance, () => error.value);
|
|||
|
|
key = 2;
|
|||
|
|
} else if (loadingComponent && !delayed.value) {
|
|||
|
|
render = () => createInnerComp(loadingComponent, instance);
|
|||
|
|
key = 3;
|
|||
|
|
}
|
|||
|
|
frag.update(render, key);
|
|||
|
|
if (isKeepAliveEnabled && frag.keepAliveCtx) frag.keepAliveCtx.cacheBlock();
|
|||
|
|
});
|
|||
|
|
return frag;
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* The block an async wrapper has settled on, or undefined while it is
|
|||
|
|
* unresolved or (under deferred hydration) resolved but not set up yet.
|
|||
|
|
* Consumers reading through the wrapper treat undefined as unresolved.
|
|||
|
|
*/
|
|||
|
|
function getAsyncWrapperInner(instance) {
|
|||
|
|
const frag = instance.block;
|
|||
|
|
if (isDynamicFragment(frag) && frag.current !== void 0 && instance.type.__asyncResolved) return frag.nodes;
|
|||
|
|
}
|
|||
|
|
function createErrorComp(comp, parent, getError) {
|
|||
|
|
return createInnerComp(comp, parent, {
|
|||
|
|
error: getError,
|
|||
|
|
$: [() => trackRawValues(parent)]
|
|||
|
|
}, {});
|
|||
|
|
}
|
|||
|
|
function createInnerComp(comp, parent, rawProps = { $: [() => trackRawValues(parent)] }, rawSlots = parent.rawSlots) {
|
|||
|
|
const prevInstance = setCurrentInstance(parent);
|
|||
|
|
try {
|
|||
|
|
return createComponent(comp, rawProps, rawSlots, void 0, void 0, parent.appContext);
|
|||
|
|
} finally {
|
|||
|
|
restoreCurrentInstance(prevInstance);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/components/Transition.ts
|
|||
|
|
let registered = false;
|
|||
|
|
const ensureTransitionHooksRegistered = () => {
|
|||
|
|
if (!registered) {
|
|||
|
|
registered = true;
|
|||
|
|
registerTransitionHooks(applyTransitionHooksImpl, applyTransitionLeaveHooksImpl, deferBranchUpdateDuringLeaveImpl, removeBranchWithLeaveImpl);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
const hydrateTransitionImpl = (suspense) => {
|
|||
|
|
if (!currentHydrationNode || !isTemplateNode(currentHydrationNode)) return;
|
|||
|
|
const templateNode = currentHydrationNode;
|
|||
|
|
const { content, parentNode } = templateNode;
|
|||
|
|
const { firstChild } = content;
|
|||
|
|
if (firstChild) {
|
|||
|
|
let transitionEl;
|
|||
|
|
for (let node = firstChild; node; node = node.nextSibling) if (node instanceof Element) {
|
|||
|
|
transitionEl = node;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
parentNode.insertBefore(content, templateNode);
|
|||
|
|
parentNode.removeChild(templateNode);
|
|||
|
|
updateLastLocatedLogicalChild(parentNode, templateNode, firstChild);
|
|||
|
|
setCurrentHydrationNode(firstChild);
|
|||
|
|
if (transitionEl instanceof HTMLElement || transitionEl instanceof SVGElement) {
|
|||
|
|
const originalDisplay = transitionEl.style.display;
|
|||
|
|
transitionEl.style.display = "none";
|
|||
|
|
return (hooks) => {
|
|||
|
|
hooks.beforeEnter(transitionEl);
|
|||
|
|
transitionEl.style.display = originalDisplay;
|
|||
|
|
queuePostRenderEffect(() => hooks.enter(transitionEl), void 0, suspense);
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
const decorate$1 = (t) => {
|
|||
|
|
t.displayName = displayName;
|
|||
|
|
t.props = TransitionPropsValidators;
|
|||
|
|
t.__vapor = true;
|
|||
|
|
return t;
|
|||
|
|
};
|
|||
|
|
const VaporTransition = /*@__PURE__*/ decorate$1((props, { slots, expose }) => {
|
|||
|
|
expose();
|
|||
|
|
ensureTransitionHooksRegistered();
|
|||
|
|
const instance = currentInstance;
|
|||
|
|
const performAppear = isHydrating$1 ? hydrateTransitionImpl(instance.suspense) : void 0;
|
|||
|
|
const state = useTransitionState();
|
|||
|
|
const { mode } = props;
|
|||
|
|
process.env.NODE_ENV !== "production" && checkTransitionMode(mode);
|
|||
|
|
const resolvedProps = computed(() => resolveTransitionProps(props));
|
|||
|
|
const propsProxy = new Proxy({}, { get(_, key) {
|
|||
|
|
return resolvedProps.value[key];
|
|||
|
|
} });
|
|||
|
|
const shouldPerformAppear = !!props.appear && !!performAppear;
|
|||
|
|
if (instance.rawSlots.$) {
|
|||
|
|
const frag = new DynamicFragment(0, !!(process.env.NODE_ENV !== "production") ? "transition" : void 0);
|
|||
|
|
if (isHydrating$1) locateHydrationNode();
|
|||
|
|
state.root = frag;
|
|||
|
|
let isMounted = false;
|
|||
|
|
renderEffect(() => {
|
|||
|
|
if (!frag.$transition) frag.$transition = resolveTransitionHooks(frag, propsProxy, state, instance);
|
|||
|
|
else frag.$transition.mode = resolvedProps.value.mode;
|
|||
|
|
const prevNodes = frag.nodes;
|
|||
|
|
frag.update(slots.default);
|
|||
|
|
if (isMounted && frag.nodes === prevNodes && !state.isLeaving) frag.$transition = applyTransitionHooksImpl(frag.nodes, frag.$transition, void 0, true);
|
|||
|
|
if (!isMounted && shouldPerformAppear) performAppear(frag.$transition);
|
|||
|
|
isMounted = true;
|
|||
|
|
});
|
|||
|
|
return frag;
|
|||
|
|
}
|
|||
|
|
const children = slots.default && slots.default() || [];
|
|||
|
|
state.root = children;
|
|||
|
|
const hooks = {
|
|||
|
|
__vapor: true,
|
|||
|
|
state,
|
|||
|
|
props: propsProxy,
|
|||
|
|
instance
|
|||
|
|
};
|
|||
|
|
let isMounted = false;
|
|||
|
|
renderEffect(() => {
|
|||
|
|
const appliedHooks = applyTransitionHooksImpl(children, hooks, void 0, isMounted);
|
|||
|
|
if (!isMounted) {
|
|||
|
|
isMounted = true;
|
|||
|
|
if (shouldPerformAppear) performAppear(appliedHooks);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
return children;
|
|||
|
|
});
|
|||
|
|
const transitionTypeMap = /* @__PURE__ */ new WeakMap();
|
|||
|
|
function getTransitionType(block) {
|
|||
|
|
const type = transitionTypeMap.get(block);
|
|||
|
|
if (type !== void 0) return type;
|
|||
|
|
if (block instanceof Element) return block.localName;
|
|||
|
|
if (isInteropEnabled && isFragment(block) && block.getTransitionType) {
|
|||
|
|
const type = block.getTransitionType();
|
|||
|
|
if (type !== void 0) return type;
|
|||
|
|
}
|
|||
|
|
return block;
|
|||
|
|
}
|
|||
|
|
function setTransitionType(block, type) {
|
|||
|
|
transitionTypeMap.set(block, type);
|
|||
|
|
}
|
|||
|
|
function getLeavingNodesForType(state, block) {
|
|||
|
|
const { leavingNodes } = state;
|
|||
|
|
const type = getTransitionType(block);
|
|||
|
|
let nodes = leavingNodes.get(type);
|
|||
|
|
if (!nodes) {
|
|||
|
|
nodes = Object.create(null);
|
|||
|
|
leavingNodes.set(type, nodes);
|
|||
|
|
}
|
|||
|
|
return nodes;
|
|||
|
|
}
|
|||
|
|
function getLeaveElement(block) {
|
|||
|
|
const el = getTransitionElement(block);
|
|||
|
|
if (el) return el;
|
|||
|
|
if (isFragment(block) && !isArray(block.nodes) && (block.nodes instanceof Element || isFragment(block.nodes))) return getLeaveElement(block.nodes);
|
|||
|
|
}
|
|||
|
|
const transitionKeys = /* @__PURE__ */ new WeakMap();
|
|||
|
|
function getTransitionKey(block) {
|
|||
|
|
return transitionKeys.get(block);
|
|||
|
|
}
|
|||
|
|
function setTransitionKey(block, key) {
|
|||
|
|
transitionKeys.set(block, key);
|
|||
|
|
}
|
|||
|
|
const getTransitionHooksContext = (block, state) => {
|
|||
|
|
const key = String(getTransitionKey(block));
|
|||
|
|
const leavingNodes = getLeavingNodesForType(state, block);
|
|||
|
|
return {
|
|||
|
|
isLeaving: () => leavingNodes[key] === block,
|
|||
|
|
setLeavingNodeCache: () => {
|
|||
|
|
leavingNodes[key] = block;
|
|||
|
|
},
|
|||
|
|
unsetLeavingNodeCache: () => {
|
|||
|
|
if (leavingNodes[key] === block) delete leavingNodes[key];
|
|||
|
|
},
|
|||
|
|
earlyRemove: () => {
|
|||
|
|
const leavingNode = leavingNodes[key];
|
|||
|
|
if (leavingNode && getTransitionKey(leavingNode) === getTransitionKey(block)) {
|
|||
|
|
const el = getLeaveElement(leavingNode);
|
|||
|
|
if (el && el[leaveCbKey]) el[leaveCbKey]();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
};
|
|||
|
|
function resolveTransitionHooks(block, props, state, instance) {
|
|||
|
|
const context = getTransitionHooksContext(block, state);
|
|||
|
|
const hooks = baseResolveTransitionHooks(context, props, state, instance);
|
|||
|
|
hooks.__vapor = true;
|
|||
|
|
hooks.persisted = hooks.persisted || !!state.persisted;
|
|||
|
|
hooks.state = state;
|
|||
|
|
hooks.props = props;
|
|||
|
|
hooks.instance = instance;
|
|||
|
|
return hooks;
|
|||
|
|
}
|
|||
|
|
function applyTransitionHooksImpl(block, hooks, owner, refresh = false) {
|
|||
|
|
if (isArray(block)) {
|
|||
|
|
block = block.filter((b) => !(b instanceof Comment));
|
|||
|
|
if (block.length === 1) block = block[0];
|
|||
|
|
else if (block.length === 0) return hooks;
|
|||
|
|
}
|
|||
|
|
if (hooks.applyGroup && (isForFragment(block) || isVaporSlotOutlet(block) || isVaporComponent(block) && isVaporSlotOutlet(block.block))) {
|
|||
|
|
hooks.applyGroup(block, hooks.props, hooks.state, hooks.instance);
|
|||
|
|
return hooks;
|
|||
|
|
}
|
|||
|
|
const fragments = [];
|
|||
|
|
const child = resolveTransitionBlock(block, (fragment) => {
|
|||
|
|
fragments.push(fragment);
|
|||
|
|
if (refresh && fragment.$transition) hooks = fragment.$transition;
|
|||
|
|
}, owner);
|
|||
|
|
if (refresh && child && child.$transition) hooks = child.$transition;
|
|||
|
|
if (!child) {
|
|||
|
|
fragments.forEach((f) => f.$transition = hooks);
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && fragments.length === 0) warn("Transition component has no valid child element");
|
|||
|
|
return hooks;
|
|||
|
|
}
|
|||
|
|
const { props, instance, state, delayedLeave } = hooks;
|
|||
|
|
state.persisted = isPersistedRoot(state.root);
|
|||
|
|
const resolvedHooks = resolveTransitionHooks(child, props, state, instance);
|
|||
|
|
resolvedHooks.delayedLeave = delayedLeave;
|
|||
|
|
child.$transition = resolvedHooks;
|
|||
|
|
fragments.forEach((f) => f.$transition = resolvedHooks);
|
|||
|
|
return resolvedHooks;
|
|||
|
|
}
|
|||
|
|
function isPersistedRoot(block) {
|
|||
|
|
while (block) {
|
|||
|
|
if (block.$vshow) return true;
|
|||
|
|
if (isVaporComponent(block)) {
|
|||
|
|
if (isVaporTransition(block.type)) return false;
|
|||
|
|
block = isAsyncComponentEnabled && isAsyncWrapper(block) ? getAsyncWrapperInner(block) : block.block;
|
|||
|
|
} else if (isArray(block)) block = block.find((b) => !(b instanceof Comment));
|
|||
|
|
else if (isFragment(block) && (isVaporSlotOutlet(block) || !(isDynamicFragment(block) || isForFragment(block)))) block = block.nodes;
|
|||
|
|
else return false;
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
function applyTransitionLeaveHooksImpl(block, enterHooks, afterLeaveCb) {
|
|||
|
|
const leavingBlock = findTransitionBlock(block);
|
|||
|
|
if (!leavingBlock) return false;
|
|||
|
|
const { props, state, instance } = enterHooks;
|
|||
|
|
const leavingHooks = resolveTransitionHooks(leavingBlock, props, state, instance);
|
|||
|
|
leavingBlock.$transition = leavingHooks;
|
|||
|
|
const { mode } = props;
|
|||
|
|
if (mode === "out-in") {
|
|||
|
|
state.isLeaving = true;
|
|||
|
|
leavingHooks.afterLeave = () => {
|
|||
|
|
state.isLeaving = false;
|
|||
|
|
afterLeaveCb();
|
|||
|
|
leavingBlock.$transition = void 0;
|
|||
|
|
delete leavingHooks.afterLeave;
|
|||
|
|
};
|
|||
|
|
} else if (mode === "in-out") leavingHooks.delayLeave = (block, earlyRemove, delayedLeave) => {
|
|||
|
|
const leavingNodes = getLeavingNodesForType(state, leavingBlock);
|
|||
|
|
const leavingKey = String(getTransitionKey(leavingBlock));
|
|||
|
|
leavingNodes[leavingKey] = leavingBlock;
|
|||
|
|
const delayedLeaveCb = createDelayedLeave(leavingBlock, delayedLeave);
|
|||
|
|
block[leaveCbKey] = () => {
|
|||
|
|
delayedLeaveCb(true);
|
|||
|
|
earlyRemove();
|
|||
|
|
block[leaveCbKey] = void 0;
|
|||
|
|
leavingBlock.$transition = void 0;
|
|||
|
|
if (leavingNodes[leavingKey] === leavingBlock) delete leavingNodes[leavingKey];
|
|||
|
|
};
|
|||
|
|
enterHooks.delayedLeave = delayedLeaveCb;
|
|||
|
|
};
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
function createDelayedLeave(block, leave) {
|
|||
|
|
return (cancelled) => {
|
|||
|
|
if (!leave) return;
|
|||
|
|
const cb = leave;
|
|||
|
|
const leavingBlock = block;
|
|||
|
|
leave = block = void 0;
|
|||
|
|
if (!cancelled) {
|
|||
|
|
cb();
|
|||
|
|
leavingBlock.$transition = void 0;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
function deferBranchUpdateDuringLeaveImpl(frag, render, key, noScope, branchKey) {
|
|||
|
|
if (!frag.$transition.state.isLeaving) return false;
|
|||
|
|
const pending = frag.pending;
|
|||
|
|
if (pending) {
|
|||
|
|
pending.render = render;
|
|||
|
|
pending.key = key;
|
|||
|
|
pending.noScope = noScope;
|
|||
|
|
pending.branchKey = branchKey;
|
|||
|
|
} else frag.pending = {
|
|||
|
|
render,
|
|||
|
|
key,
|
|||
|
|
noScope,
|
|||
|
|
branchKey
|
|||
|
|
};
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
function removeBranchWithLeaveImpl(frag, transition, parent, render, key, noScope, branchKey) {
|
|||
|
|
const mode = transition.mode;
|
|||
|
|
if (mode && !transition.persisted && (mode !== "in-out" || render) && (mode !== "out-in" || isValidBlock(frag.nodes))) {
|
|||
|
|
const instance = currentInstance;
|
|||
|
|
let enterHooks = transition;
|
|||
|
|
if (mode === "in-out") enterHooks = frag.$transition = extend$1({}, transition);
|
|||
|
|
applyTransitionLeaveHooksImpl(frag.nodes, enterHooks, () => {
|
|||
|
|
if (transition.state.isUnmounting) return;
|
|||
|
|
const prevInstance = setCurrentInstance(instance);
|
|||
|
|
try {
|
|||
|
|
const pending = frag.pending;
|
|||
|
|
if (pending) {
|
|||
|
|
frag.pending = void 0;
|
|||
|
|
frag.renderBranch(pending.render, transition, parent, pending.key, pending.noScope, true, void 0, pending.branchKey);
|
|||
|
|
} else frag.renderBranch(render, transition, parent, key, noScope, true, void 0, branchKey);
|
|||
|
|
} finally {
|
|||
|
|
restoreCurrentInstance(prevInstance);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
if (mode === "out-in") {
|
|||
|
|
parent && remove(frag.nodes, parent);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
const ROOT_KEY_CONTEXT = { key: void 0 };
|
|||
|
|
const keyContexts = /* @__PURE__ */ new WeakMap();
|
|||
|
|
const KEY_CONTEXT_OWNER = 34;
|
|||
|
|
function transitionTypeOf(block) {
|
|||
|
|
return isAsyncComponentEnabled && block.type.__asyncResolved || block.type;
|
|||
|
|
}
|
|||
|
|
function withDefaultKey(ctx, key) {
|
|||
|
|
return ctx.type || key == null ? ctx : { key };
|
|||
|
|
}
|
|||
|
|
function isUnresolvedAsyncWrapper(block) {
|
|||
|
|
return isAsyncComponentEnabled && isAsyncWrapper(block) && getAsyncWrapperInner(block) === void 0;
|
|||
|
|
}
|
|||
|
|
function enterComponentKeyContext(ctx, block, unresolved = isUnresolvedAsyncWrapper(block)) {
|
|||
|
|
var _block$$key;
|
|||
|
|
if (ctx.type) return ctx;
|
|||
|
|
return unresolved ? withDefaultKey(ctx, block.$key) : {
|
|||
|
|
key: (_block$$key = block.$key) !== null && _block$$key !== void 0 ? _block$$key : ctx.key,
|
|||
|
|
type: transitionTypeOf(block)
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
function enterFragmentKeyContext(frag, ctx, key = getFragmentKey(frag)) {
|
|||
|
|
if (frag.__vf & KEY_CONTEXT_OWNER) keyContexts.set(frag, ctx);
|
|||
|
|
return withDefaultKey(ctx, key);
|
|||
|
|
}
|
|||
|
|
function resolveChildIdentity(child, ctx) {
|
|||
|
|
var _child$$key;
|
|||
|
|
transitionKeys.set(child, ctx.type ? ctx.key : (_child$$key = child.$key) !== null && _child$$key !== void 0 ? _child$$key : ctx.key);
|
|||
|
|
if (ctx.type) setTransitionType(child, ctx.type);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Resolve the transition child of `block` together with its identity.
|
|||
|
|
* `owner` is the fragment whose content `block` is.
|
|||
|
|
*/
|
|||
|
|
function resolveTransitionBlock(block, onFragment, owner) {
|
|||
|
|
const ctx = owner ? withDefaultKey(keyContexts.get(owner) || ROOT_KEY_CONTEXT, getFragmentKey(owner)) : ROOT_KEY_CONTEXT;
|
|||
|
|
const children = [];
|
|||
|
|
collectTransitionBlocks$1(block, onFragment, children, ctx);
|
|||
|
|
return children[0];
|
|||
|
|
}
|
|||
|
|
/** Locate the transition child of `block` without touching its identity. */
|
|||
|
|
function findTransitionBlock(block) {
|
|||
|
|
const children = [];
|
|||
|
|
collectTransitionBlocks$1(block, void 0, children, void 0);
|
|||
|
|
return children[0];
|
|||
|
|
}
|
|||
|
|
function collectTransitionBlocks$1(block, onFragment, children, ctx) {
|
|||
|
|
if (block instanceof Node) {
|
|||
|
|
if (block instanceof Element) {
|
|||
|
|
children.push(block);
|
|||
|
|
if (ctx) resolveChildIdentity(block, ctx);
|
|||
|
|
}
|
|||
|
|
} else if (isVaporComponent(block)) collectComponentTransitionBlocks(block, onFragment, children, ctx);
|
|||
|
|
else if (isArray(block)) collectArrayTransitionBlocks(block, onFragment, children, ctx);
|
|||
|
|
else if (isFragment(block)) collectFragmentTransitionBlocks(block, onFragment, children, ctx);
|
|||
|
|
}
|
|||
|
|
function collectComponentTransitionBlocks(block, onFragment, children, ctx) {
|
|||
|
|
if (isKeepAliveEnabled && isKeepAlive(block)) {
|
|||
|
|
collectTransitionBlocks$1(block.block, onFragment, children, ctx);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
const async = isAsyncComponentEnabled && isAsyncWrapper(block);
|
|||
|
|
const inner = async ? getAsyncWrapperInner(block) : void 0;
|
|||
|
|
if (ctx) ctx = enterComponentKeyContext(ctx, block, async && inner === void 0);
|
|||
|
|
if (async) {
|
|||
|
|
if (inner === void 0) {
|
|||
|
|
if (isFragment(block.block)) {
|
|||
|
|
if (onFragment) onFragment(block.block);
|
|||
|
|
if (ctx) keyContexts.set(block.block, ctx);
|
|||
|
|
}
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
collectTransitionBlocks$1(inner, onFragment, children, ctx);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (isVaporTransition(block.type)) return;
|
|||
|
|
collectTransitionBlocks$1(block.block, onFragment, children, ctx);
|
|||
|
|
}
|
|||
|
|
function collectArrayTransitionBlocks(block, onFragment, children, ctx) {
|
|||
|
|
let hasFound = false;
|
|||
|
|
for (const c of block) {
|
|||
|
|
if (c instanceof Comment) continue;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && hasFound) {
|
|||
|
|
warn("<transition> can only be used on a single element or component. Use <transition-group> for lists.");
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
const nested = [];
|
|||
|
|
collectTransitionBlocks$1(c, onFragment, nested, ctx);
|
|||
|
|
if (nested.length) children.push(nested[0]);
|
|||
|
|
hasFound = true;
|
|||
|
|
if (!!!(process.env.NODE_ENV !== "production")) break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function collectFragmentTransitionBlocks(block, onFragment, children, ctx) {
|
|||
|
|
if (isInteropEnabled && block.hasVDOMContent && block.hasVDOMContent()) {
|
|||
|
|
children.push(block);
|
|||
|
|
if (ctx) {
|
|||
|
|
resolveChildIdentity(block, ctx);
|
|||
|
|
if (!ctx.type) {
|
|||
|
|
const type = block.getTransitionType();
|
|||
|
|
if (type !== void 0) setTransitionType(block, type);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (onFragment) onFragment(block);
|
|||
|
|
collectTransitionBlocks$1(block.nodes, onFragment, children, ctx && enterFragmentKeyContext(block, ctx));
|
|||
|
|
}
|
|||
|
|
function setTransitionHooks$1(block, hooks) {
|
|||
|
|
if (isVaporComponent(block)) {
|
|||
|
|
block = findTransitionBlock(block.block);
|
|||
|
|
if (!block) return;
|
|||
|
|
}
|
|||
|
|
block.$transition = hooks;
|
|||
|
|
}
|
|||
|
|
function isValidTransitionBlock(block) {
|
|||
|
|
return block instanceof Element || !!(isInteropEnabled && isFragment(block) && block.hasVDOMContent && block.hasVDOMContent());
|
|||
|
|
}
|
|||
|
|
function getTransitionElement(block) {
|
|||
|
|
if (block instanceof Element) return block;
|
|||
|
|
if (isInteropEnabled && isFragment(block) && block.getTransitionElement) return block.getTransitionElement();
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/refCleanup.ts
|
|||
|
|
/**
|
|||
|
|
* Stores ref cleanup functions keyed by the element/component they are set on.
|
|||
|
|
* Shared between apiTemplateRef.ts (writes) and KeepAlive deactivate (reads).
|
|||
|
|
*/
|
|||
|
|
const refCleanups = /* @__PURE__ */ new WeakMap();
|
|||
|
|
function invalidatePendingRef(el) {
|
|||
|
|
const c = refCleanups.get(el);
|
|||
|
|
if (c && c.job) {
|
|||
|
|
c.job.flags = c.job.flags | 4;
|
|||
|
|
c.job = void 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Synchronously clear the ref for an element being deactivated by KeepAlive.
|
|||
|
|
* In VDOM core, refs are cleared during unmount before the deactivation check.
|
|||
|
|
* Since Vapor's KeepAlive retains scopes (skipping onScopeDispose), we need
|
|||
|
|
* this explicit sync cleanup path.
|
|||
|
|
*/
|
|||
|
|
function unsetRef(el) {
|
|||
|
|
invalidatePendingRef(el);
|
|||
|
|
const c = refCleanups.get(el);
|
|||
|
|
if (c) c.fn();
|
|||
|
|
}
|
|||
|
|
const VaporKeepAlive = /*@__PURE__*/ withKeepAliveEnabled(/* @__PURE__ */ defineVaporComponent({
|
|||
|
|
name: "VaporKeepAlive",
|
|||
|
|
__isKeepAlive: true,
|
|||
|
|
props: {
|
|||
|
|
include: [
|
|||
|
|
String,
|
|||
|
|
RegExp,
|
|||
|
|
Array
|
|||
|
|
],
|
|||
|
|
exclude: [
|
|||
|
|
String,
|
|||
|
|
RegExp,
|
|||
|
|
Array
|
|||
|
|
],
|
|||
|
|
max: [String, Number]
|
|||
|
|
},
|
|||
|
|
setup(props, { slots, expose }) {
|
|||
|
|
let exposed;
|
|||
|
|
expose(exposed);
|
|||
|
|
if (!slots.default) return;
|
|||
|
|
const keepAliveInstance = currentInstance;
|
|||
|
|
const cache = /* @__PURE__ */ new Map();
|
|||
|
|
const keys = /* @__PURE__ */ new Set();
|
|||
|
|
const storageContainer = /* @__PURE__ */ createElement("div");
|
|||
|
|
const keptAliveScopes = /* @__PURE__ */ new Map();
|
|||
|
|
const resolveCacheKeyFromBlock = (block, interop, branchKey) => {
|
|||
|
|
var _ref3, _$key;
|
|||
|
|
if (interop && isInteropEnabled) {
|
|||
|
|
var _ref, _ref2, _frag$$key;
|
|||
|
|
const frag = block;
|
|||
|
|
return (_ref = (_ref2 = (_frag$$key = frag.$key) !== null && _frag$$key !== void 0 ? _frag$$key : frag.vnode.key) !== null && _ref2 !== void 0 ? _ref2 : branchKey) !== null && _ref !== void 0 ? _ref : frag.vnode.type;
|
|||
|
|
}
|
|||
|
|
return (_ref3 = (_$key = block.$key) !== null && _$key !== void 0 ? _$key : branchKey) !== null && _ref3 !== void 0 ? _ref3 : block.type;
|
|||
|
|
};
|
|||
|
|
let current;
|
|||
|
|
let rootFragment;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") || __VUE_PROD_DEVTOOLS__) {
|
|||
|
|
keepAliveInstance.__v_cache = cache;
|
|||
|
|
keepAliveInstance.__v_keptAliveScopes = keptAliveScopes;
|
|||
|
|
}
|
|||
|
|
const addCacheKey = (key) => {
|
|||
|
|
const { max } = props;
|
|||
|
|
keys.add(key);
|
|||
|
|
if (max && keys.size > parseInt(max, 10)) pruneCacheEntry(keys.values().next().value);
|
|||
|
|
};
|
|||
|
|
const innerCacheBlock = (key, block, isCurrent) => {
|
|||
|
|
if (cache.has(key)) {
|
|||
|
|
if (isCurrent) {
|
|||
|
|
keys.delete(key);
|
|||
|
|
keys.add(key);
|
|||
|
|
}
|
|||
|
|
} else addCacheKey(key);
|
|||
|
|
cache.set(key, block);
|
|||
|
|
if (isCurrent) current = block;
|
|||
|
|
};
|
|||
|
|
const cacheBlock = (block = keepAliveInstance.block) => {
|
|||
|
|
if (isDynamicFragment(block)) {
|
|||
|
|
const transition = block.$transition;
|
|||
|
|
if (transition && transition.mode === "out-in" && transition.state.isLeaving) return;
|
|||
|
|
}
|
|||
|
|
const [innerBlock, interop, branchKey] = getInnerBlock(block);
|
|||
|
|
if (!innerBlock) return;
|
|||
|
|
const cacheKey = resolveCacheKeyFromBlock(innerBlock, interop, branchKey);
|
|||
|
|
if (!shouldCache(innerBlock, props, interop)) {
|
|||
|
|
if (cache.has(cacheKey)) pruneCacheEntry(cacheKey);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
setShapeFlag(innerBlock, interop, cache.has(cacheKey));
|
|||
|
|
const { currentBlock, currentKey } = getCurrentBlockState();
|
|||
|
|
innerCacheBlock(cacheKey, innerBlock, currentBlock === innerBlock || currentKey === cacheKey);
|
|||
|
|
};
|
|||
|
|
const processShapeFlag = (block, requireKeptAlive = false) => {
|
|||
|
|
const [innerBlock, interop, branchKey] = getInnerBlock(block);
|
|||
|
|
if (!innerBlock || requireKeptAlive && !isKeptAlive(innerBlock, interop) || !shouldCache(innerBlock, props, interop)) return false;
|
|||
|
|
const cacheKey = resolveCacheKeyFromBlock(innerBlock, interop, branchKey);
|
|||
|
|
setShapeFlag(innerBlock, interop, cache.has(cacheKey));
|
|||
|
|
return cacheKey;
|
|||
|
|
};
|
|||
|
|
const pruneCache = (filter) => {
|
|||
|
|
cache.forEach((cached, key) => {
|
|||
|
|
const instance = getInstanceFromCache(cached);
|
|||
|
|
if (!instance) return;
|
|||
|
|
const name = getComponentName(isAsyncWrapper(instance) ? instance.type.__asyncResolved || {} : instance.type);
|
|||
|
|
if (name && !filter(name)) pruneCacheEntry(key);
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
const deleteScope = (key) => {
|
|||
|
|
const scope = keptAliveScopes.get(key);
|
|||
|
|
if (scope) {
|
|||
|
|
keptAliveScopes.delete(key);
|
|||
|
|
for (const [k, s] of keptAliveScopes) if (s === scope) {
|
|||
|
|
keptAliveScopes.delete(k);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return scope;
|
|||
|
|
};
|
|||
|
|
const cacheScope = (cacheKey, scopeLookupKey, scope) => {
|
|||
|
|
const prevScope = keptAliveScopes.get(cacheKey);
|
|||
|
|
if (prevScope && prevScope !== scope) {
|
|||
|
|
const staleScope = deleteScope(cacheKey);
|
|||
|
|
if (staleScope) staleScope.stop();
|
|||
|
|
}
|
|||
|
|
keptAliveScopes.set(cacheKey, scope);
|
|||
|
|
if (scopeLookupKey !== cacheKey) keptAliveScopes.set(scopeLookupKey, scope);
|
|||
|
|
};
|
|||
|
|
const pruneCacheEntry = (key) => {
|
|||
|
|
const cached = cache.get(key);
|
|||
|
|
if (cached && (!current || cached !== current)) {
|
|||
|
|
unsetShapeFlag(cached);
|
|||
|
|
const parentNode = findBlockBoundary(cached).parentNode;
|
|||
|
|
if (parentNode) remove(cached, parentNode);
|
|||
|
|
} else if (current) unsetShapeFlag(current);
|
|||
|
|
cache.delete(key);
|
|||
|
|
keys.delete(key);
|
|||
|
|
const scope = deleteScope(key);
|
|||
|
|
if (scope) scope.stop();
|
|||
|
|
};
|
|||
|
|
watch(() => [props.include, props.exclude], ([include, exclude]) => {
|
|||
|
|
include && pruneCache((name) => matches(include, name));
|
|||
|
|
exclude && pruneCache((name) => !matches(exclude, name));
|
|||
|
|
cacheBlock();
|
|||
|
|
}, {
|
|||
|
|
flush: "post",
|
|||
|
|
deep: true
|
|||
|
|
});
|
|||
|
|
onMounted(cacheBlock);
|
|||
|
|
onUpdated(cacheBlock);
|
|||
|
|
const getCurrentBlockState = () => {
|
|||
|
|
const block = keepAliveInstance.block;
|
|||
|
|
const [currentBlock, interop, branchKey] = getInnerBlock(block);
|
|||
|
|
return {
|
|||
|
|
currentBlock,
|
|||
|
|
interop,
|
|||
|
|
currentKey: currentBlock && resolveCacheKeyFromBlock(currentBlock, interop, branchKey)
|
|||
|
|
};
|
|||
|
|
};
|
|||
|
|
onBeforeUnmount(() => {
|
|||
|
|
const { currentBlock, interop, currentKey } = getCurrentBlockState();
|
|||
|
|
const deactivateCached = (cached) => {
|
|||
|
|
unsetShapeFlag(cached);
|
|||
|
|
const instance = getInstanceFromCache(cached);
|
|||
|
|
if (instance) {
|
|||
|
|
const da = instance.da;
|
|||
|
|
da && queuePostRenderEffect(da, void 0, keepAliveInstance.suspense);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
let matched = false;
|
|||
|
|
cache.forEach((cached, key) => {
|
|||
|
|
if (currentKey === key) {
|
|||
|
|
matched = true;
|
|||
|
|
deactivateCached(cached);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
unsetShapeFlag(cached);
|
|||
|
|
const parentNode = findBlockBoundary(cached).parentNode;
|
|||
|
|
remove(cached, parentNode || void 0);
|
|||
|
|
});
|
|||
|
|
if (!matched && currentBlock && isKeptAlive(currentBlock, interop)) deactivateCached(currentBlock);
|
|||
|
|
keptAliveScopes.forEach((scope) => scope.stop());
|
|||
|
|
keptAliveScopes.clear();
|
|||
|
|
});
|
|||
|
|
const keepAliveCtx = {
|
|||
|
|
getStorageContainer: () => storageContainer,
|
|||
|
|
getCachedComponent: (comp, key) => {
|
|||
|
|
if (isInteropEnabled && isVNode(comp)) {
|
|||
|
|
var _ref4, _comp$key;
|
|||
|
|
return cache.get((_ref4 = (_comp$key = comp.key) !== null && _comp$key !== void 0 ? _comp$key : currentCacheKey) !== null && _ref4 !== void 0 ? _ref4 : comp.type);
|
|||
|
|
}
|
|||
|
|
const branchKey = key !== null && key !== void 0 ? key : currentCacheKey;
|
|||
|
|
return branchKey != null ? cache.get(branchKey) : cache.get(comp) || cache.get(comp.__asyncResolved);
|
|||
|
|
},
|
|||
|
|
activate: (instance, parentNode, anchor, parentSuspense) => {
|
|||
|
|
current = instance;
|
|||
|
|
activate$1(instance, parentNode, anchor, parentSuspense);
|
|||
|
|
},
|
|||
|
|
deactivate: (instance, parentSuspense) => {
|
|||
|
|
current = void 0;
|
|||
|
|
deactivate$1(instance, storageContainer, parentSuspense);
|
|||
|
|
},
|
|||
|
|
prepareBranchRemoval(frag, scope, prevKey) {
|
|||
|
|
if (frag !== rootFragment) {
|
|||
|
|
scope.stop();
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
const fragKey = getFragmentKey(frag);
|
|||
|
|
const cacheKey = withCurrentCacheKey(fragKey, () => processShapeFlag(frag.nodes, true));
|
|||
|
|
if (cacheKey === false) {
|
|||
|
|
scope.stop();
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
if (isDynamicFragment(frag.nodes)) {
|
|||
|
|
scope.stop();
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
scope.pause();
|
|||
|
|
cacheScope(cacheKey, fragKey !== null && fragKey !== void 0 ? fragKey : prevKey, scope);
|
|||
|
|
return true;
|
|||
|
|
},
|
|||
|
|
runBranchRender(frag, fn, useScope, removePrevious) {
|
|||
|
|
const fragKey = getFragmentKey(frag);
|
|||
|
|
const cachedScope = useScope ? deleteScope(fragKey !== null && fragKey !== void 0 ? fragKey : frag.current) : void 0;
|
|||
|
|
frag.scope = useScope ? cachedScope || new EffectScope$1() : void 0;
|
|||
|
|
if (cachedScope) cachedScope.resume();
|
|||
|
|
let incomingCacheKey = false;
|
|||
|
|
const run = () => {
|
|||
|
|
try {
|
|||
|
|
fn();
|
|||
|
|
} finally {
|
|||
|
|
incomingCacheKey = processShapeFlag(frag.nodes);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
try {
|
|||
|
|
withCurrentCacheKey(fragKey, run);
|
|||
|
|
if (removePrevious && incomingCacheKey !== false && !cache.has(incomingCacheKey)) addCacheKey(incomingCacheKey);
|
|||
|
|
} finally {
|
|||
|
|
if (removePrevious) removePrevious();
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
processShapeFlag,
|
|||
|
|
cacheBlock
|
|||
|
|
};
|
|||
|
|
if (isInteropEnabled) keepAliveCtx.clearCurrent = (block) => {
|
|||
|
|
if (current === block) current = void 0;
|
|||
|
|
};
|
|||
|
|
keepAliveInstance.ctx = keepAliveCtx;
|
|||
|
|
let children = slots.default();
|
|||
|
|
rootFragment = registerDynamicFragmentHooks(children, keepAliveCtx);
|
|||
|
|
if (isArray(children)) {
|
|||
|
|
children = children.filter((child) => !(child instanceof Comment));
|
|||
|
|
if (children.length === 1) rootFragment = registerDynamicFragmentHooks(children[0], keepAliveCtx);
|
|||
|
|
if (children.length > 1) {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) warn(`KeepAlive should contain exactly one component child.`);
|
|||
|
|
return children;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return children;
|
|||
|
|
}
|
|||
|
|
}));
|
|||
|
|
function registerDynamicFragmentHooks(block, keepAliveCtx) {
|
|||
|
|
if (!isDynamicFragment(block)) return;
|
|||
|
|
(block.u || (block.u = [])).unshift(() => {
|
|||
|
|
if (block.$transition && block.$transition.mode === "out-in") keepAliveCtx.cacheBlock(block);
|
|||
|
|
});
|
|||
|
|
return block;
|
|||
|
|
}
|
|||
|
|
const shouldCache = (block, props, interop = false) => {
|
|||
|
|
const isAsync = isAsyncWrapper(interop ? block.vnode : block);
|
|||
|
|
const type = interop && isInteropEnabled ? block.vnode.type : block.type;
|
|||
|
|
if (isAsync && !type.__asyncResolved) return !props.include;
|
|||
|
|
const { include, exclude } = props;
|
|||
|
|
const name = getComponentName(isAsync ? type.__asyncResolved : type);
|
|||
|
|
return !(include && (!name || !matches(include, name)) || exclude && name && matches(exclude, name));
|
|||
|
|
};
|
|||
|
|
function setShapeFlag(block, interop, cached) {
|
|||
|
|
if (interop && isInteropEnabled) {
|
|||
|
|
if (cached) block.vnode.shapeFlag |= 512;
|
|||
|
|
block.vnode.shapeFlag |= 256;
|
|||
|
|
} else {
|
|||
|
|
if (cached) block.shapeFlag |= 512;
|
|||
|
|
block.shapeFlag |= 256;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
const unsetShapeFlag = (cached) => {
|
|||
|
|
if (isVaporComponent(cached)) {
|
|||
|
|
resetShapeFlag(cached);
|
|||
|
|
if (isAsyncComponentEnabled && isAsyncWrapper(cached)) {
|
|||
|
|
const [inner] = getInnerBlock(cached.block);
|
|||
|
|
if (inner && isVaporComponent(inner)) resetShapeFlag(inner);
|
|||
|
|
}
|
|||
|
|
} else if (isInteropEnabled) {
|
|||
|
|
const vnode = cached.vnode;
|
|||
|
|
resetShapeFlag(vnode);
|
|||
|
|
if (isVaporComponent(vnode.component)) unsetShapeFlag(vnode.component);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
function isKeptAlive(cached, interop) {
|
|||
|
|
if (interop && isInteropEnabled && isInteropFragment(cached)) return !!(cached.vnode.shapeFlag & 256);
|
|||
|
|
return !!(cached.shapeFlag & 256);
|
|||
|
|
}
|
|||
|
|
function getInnerBlock(block, branchKey = currentCacheKey) {
|
|||
|
|
if (isVaporComponent(block)) return [
|
|||
|
|
block,
|
|||
|
|
false,
|
|||
|
|
branchKey
|
|||
|
|
];
|
|||
|
|
else if (isInteropEnabled && isInteropFragment(block)) return [
|
|||
|
|
block,
|
|||
|
|
true,
|
|||
|
|
branchKey
|
|||
|
|
];
|
|||
|
|
else if (isFragment(block)) {
|
|||
|
|
var _getFragmentKey;
|
|||
|
|
return getInnerBlock(block.nodes, (_getFragmentKey = getFragmentKey(block)) !== null && _getFragmentKey !== void 0 ? _getFragmentKey : branchKey);
|
|||
|
|
}
|
|||
|
|
return [
|
|||
|
|
void 0,
|
|||
|
|
false,
|
|||
|
|
branchKey
|
|||
|
|
];
|
|||
|
|
}
|
|||
|
|
function getInstanceFromCache(cached) {
|
|||
|
|
if (isVaporComponent(cached)) return cached;
|
|||
|
|
if (isInteropEnabled) return cached.vnode.component;
|
|||
|
|
}
|
|||
|
|
function activate$1(instance, parentNode, anchor, parentSuspense = instance.suspense) {
|
|||
|
|
const inputScope = instance.inputScope;
|
|||
|
|
if (inputScope) inputScope.resume();
|
|||
|
|
move(instance, parentNode, anchor, 0, instance, parentSuspense);
|
|||
|
|
queuePostRenderEffect(() => {
|
|||
|
|
instance.isDeactivated = false;
|
|||
|
|
if (instance.a) invokeArrayFns(instance.a);
|
|||
|
|
}, void 0, parentSuspense);
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") || __VUE_PROD_DEVTOOLS__) devtoolsComponentAdded(instance);
|
|||
|
|
}
|
|||
|
|
function deactivate$1(instance, container, parentSuspense = instance.suspense) {
|
|||
|
|
const inputScope = instance.inputScope;
|
|||
|
|
if (inputScope) inputScope.pause();
|
|||
|
|
unsetRef(instance);
|
|||
|
|
invalidateMount(instance.m);
|
|||
|
|
invalidateMount(instance.a);
|
|||
|
|
move(instance, container, null, 1, instance, parentSuspense);
|
|||
|
|
queuePostRenderEffect(() => {
|
|||
|
|
if (instance.da) invokeArrayFns(instance.da);
|
|||
|
|
instance.isDeactivated = true;
|
|||
|
|
}, void 0, parentSuspense);
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") || __VUE_PROD_DEVTOOLS__) devtoolsComponentAdded(instance);
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/vdomInterop.ts
|
|||
|
|
const EMPTY_VNODES = EMPTY_ARR;
|
|||
|
|
function getRawTransitionChild(vnode) {
|
|||
|
|
if (!vnode) return;
|
|||
|
|
const children = getTransitionRawChildren([vnode]);
|
|||
|
|
return children.length === 1 ? children[0] : void 0;
|
|||
|
|
}
|
|||
|
|
function isVaporTransitionHooks(hooks) {
|
|||
|
|
return !!hooks && hooks.__vapor === true;
|
|||
|
|
}
|
|||
|
|
function getVaporInstance(vnode) {
|
|||
|
|
return vnode.component;
|
|||
|
|
}
|
|||
|
|
function prepareInteropSlotTransition(frag, vnode, forwarded, previous, resumeAfterLeave, delayedLeaveSource) {
|
|||
|
|
const transition = frag.$transition;
|
|||
|
|
const instance = frag.renderInstance;
|
|||
|
|
if (transition && !isVaporTransitionHooks(transition)) {
|
|||
|
|
setTransitionHooks(vnode, transition);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (transition && transition.applyGroup) return;
|
|||
|
|
if (!transition && !(forwarded && instance && isVaporTransition(instance.type))) return;
|
|||
|
|
const branch = resolveTransitionChild([vnode], true);
|
|||
|
|
if (!transition) return branch;
|
|||
|
|
return prepareTransitionSwitch(previous, branch, transition.props, transition.state, transition.instance, resumeAfterLeave, delayedLeaveSource || transition) || createCommentVNode();
|
|||
|
|
}
|
|||
|
|
function getInteropTransitionType(vnode) {
|
|||
|
|
const child = getRawTransitionChild(vnode);
|
|||
|
|
return child && child.type;
|
|||
|
|
}
|
|||
|
|
function vnodeKeyOf(vnode) {
|
|||
|
|
var _vnode$key;
|
|||
|
|
return (_vnode$key = vnode.key) !== null && _vnode$key !== void 0 ? _vnode$key : void 0;
|
|||
|
|
}
|
|||
|
|
function getVNodeKey(vnode) {
|
|||
|
|
const child = getRawTransitionChild(vnode);
|
|||
|
|
return child && vnodeKeyOf(child);
|
|||
|
|
}
|
|||
|
|
function getInteropTransitionElement(vnode) {
|
|||
|
|
if (!vnode) return;
|
|||
|
|
const component = vnode.component;
|
|||
|
|
if (isVaporComponent(component)) {
|
|||
|
|
const block = component.block && findTransitionBlock(component.block);
|
|||
|
|
return block && getTransitionElement(block);
|
|||
|
|
}
|
|||
|
|
if (vnode.el instanceof Element) return vnode.el;
|
|||
|
|
if (component) return getInteropTransitionElement(component.subTree);
|
|||
|
|
if (vnode.type === Fragment) {
|
|||
|
|
const child = getRawTransitionChild(vnode);
|
|||
|
|
if (child) return getInteropTransitionElement(child);
|
|||
|
|
} else if (vnode.shapeFlag & 64 && isArray(vnode.children)) {
|
|||
|
|
const child = resolveTransitionChild(vnode.children);
|
|||
|
|
if (child) return getInteropTransitionElement(child);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function interopRawProps(vnode) {
|
|||
|
|
const rawProps = {};
|
|||
|
|
const props = vnode.props;
|
|||
|
|
for (const key in props) if (!isReservedProp(key)) rawProps[key] = props[key];
|
|||
|
|
rawProps[interopKey] = true;
|
|||
|
|
return rawProps;
|
|||
|
|
}
|
|||
|
|
const vaporInteropImpl = {
|
|||
|
|
applyCssVars(vnode, vars) {
|
|||
|
|
setVarsOnBlock(vnode.vb || getVaporInstance(vnode).block, vars);
|
|||
|
|
},
|
|||
|
|
mount(vnode, container, anchor, parentComponent, parentSuspense) {
|
|||
|
|
const selfAnchor = vnode.anchor = /* @__PURE__ */ createTextNode();
|
|||
|
|
vnode.el = selfAnchor;
|
|||
|
|
container.insertBefore(selfAnchor, anchor);
|
|||
|
|
const prev = currentInstance;
|
|||
|
|
simpleSetCurrentInstance(parentComponent);
|
|||
|
|
const rawProps = interopRawProps(vnode);
|
|||
|
|
const slotsRef = shallowRef(normalizeInteropSlots(vnode.children));
|
|||
|
|
const rawSlots = createInteropRawSlots(slotsRef);
|
|||
|
|
const prevCtx = currentRenderContext;
|
|||
|
|
if (isSuspenseEnabled && parentSuspense) setRenderContext(deriveSuspense(prevCtx, parentSuspense));
|
|||
|
|
const instance = vnode.component = createComponent(vnode.type, rawProps, rawSlots, void 0, void 0, parentComponent ? parentComponent.appContext : vnode.appContext, true);
|
|||
|
|
instance.rawSlotsRef = slotsRef;
|
|||
|
|
instance.emitsOptions = normalizeEmitsOptions(instance.type);
|
|||
|
|
const vnodeHookState = ensureVNodeHookState(instance, vnode);
|
|||
|
|
setInteropComponentScopeIds(instance, vnode);
|
|||
|
|
if (parentComponent && isKeepAlive(parentComponent)) {
|
|||
|
|
enableKeepAlive();
|
|||
|
|
instance.shapeFlag = vnode.shapeFlag;
|
|||
|
|
}
|
|||
|
|
if (vnode.transition) {
|
|||
|
|
ensureTransitionHooksRegistered();
|
|||
|
|
(instance.bm || (instance.bm = [])).push(() => {
|
|||
|
|
const transition = vnodeHookState.vnode.transition;
|
|||
|
|
if (transition) setTransitionHooks$1(instance, transition);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
setRenderContext(prevCtx);
|
|||
|
|
const pendingSetup = isPendingInteropSetup(instance);
|
|||
|
|
const rootEl = !pendingSetup && resolveInteropRootEl(instance);
|
|||
|
|
if (rootEl) vnode.el = rootEl;
|
|||
|
|
const asyncWrapper = isAsyncWrapper(vnode);
|
|||
|
|
const vnodeHooks = asyncWrapper ? null : vnode.props;
|
|||
|
|
if (pendingSetup || vnode.dirs || vnodeHooks && vnodeHooks.onVnodeBeforeMount) registerAfterInteropSetup(instance, pendingSetup, () => {
|
|||
|
|
(instance.bm || (instance.bm = [])).push(() => {
|
|||
|
|
const mountVNode = vnodeHookState.vnode;
|
|||
|
|
const hooks = asyncWrapper ? null : mountVNode.props;
|
|||
|
|
if (pendingSetup) {
|
|||
|
|
const rootEl = resolveInteropRootEl(instance);
|
|||
|
|
if (rootEl) mountVNode.el = rootEl;
|
|||
|
|
const mountedHook = hooks && hooks.onVnodeMounted;
|
|||
|
|
if (mountedHook) (instance.m || (instance.m = [])).push(() => invokeInteropVNodeHook(instance, mountedHook, mountVNode));
|
|||
|
|
}
|
|||
|
|
invokeInteropVNodeHook(instance, hooks && hooks.onVnodeBeforeMount, mountVNode);
|
|||
|
|
if (!mountVNode.dirs) return;
|
|||
|
|
const [owner, el] = resolveInteropDirsRoot(instance, vnodeHookState, instance, getInteropDirsOwner(vnodeHookState, instance, mountVNode));
|
|||
|
|
if (el) {
|
|||
|
|
mountInteropDirsRoot(instance, owner, el);
|
|||
|
|
mountVNode.el = el;
|
|||
|
|
} else if (!!(process.env.NODE_ENV !== "production") && !isPendingInteropDirsRoot(owner.comp)) warnNonElementRootDirs();
|
|||
|
|
});
|
|||
|
|
if (vnodeHookState.vnode.dirs) (instance.bum || (instance.bum = [])).push(() => unmountInteropDirs(instance, vnodeHookState, instance));
|
|||
|
|
});
|
|||
|
|
mountComponent(instance, container, selfAnchor);
|
|||
|
|
if (!pendingSetup) queueInteropVNodeHook(instance, vnodeHooks && vnodeHooks.onVnodeMounted, vnode, parentSuspense);
|
|||
|
|
simpleSetCurrentInstance(prev);
|
|||
|
|
return instance;
|
|||
|
|
},
|
|||
|
|
update(n1, n2, shouldUpdate) {
|
|||
|
|
n2.component = n1.component;
|
|||
|
|
n2.el = n1.el;
|
|||
|
|
n2.anchor = n1.anchor;
|
|||
|
|
const instance = getVaporInstance(n2);
|
|||
|
|
const vnodeHookState = ensureVNodeHookState(instance, n2);
|
|||
|
|
if (shouldUpdate) {
|
|||
|
|
const rootEl = getRootElement(instance);
|
|||
|
|
if (rootEl) n2.el = rootEl;
|
|||
|
|
if (n2.transition && instance.block) {
|
|||
|
|
ensureTransitionHooksRegistered();
|
|||
|
|
setTransitionHooks$1(instance, n2.transition);
|
|||
|
|
}
|
|||
|
|
updateInteropVNode(instance, vnodeHookState, n2, n1);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
unmount(vnode, doRemove, parentSuspense) {
|
|||
|
|
if (isSuspenseEnabled && currentUnmountSuspense !== parentSuspense) {
|
|||
|
|
runWithUnmountSuspense(parentSuspense, () => vaporInteropImpl.unmount(vnode, doRemove, parentSuspense));
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
const container = doRemove ? vnode.anchor.parentNode : void 0;
|
|||
|
|
const instance = getVaporInstance(vnode);
|
|||
|
|
let slotStartAnchor = null;
|
|||
|
|
if (instance) {
|
|||
|
|
const anchor = vnode.anchor;
|
|||
|
|
const vnodeHooks = isAsyncWrapper(vnode) ? null : vnode.props;
|
|||
|
|
invokeInteropVNodeHook(instance, vnodeHooks && vnodeHooks.onVnodeBeforeUnmount, vnode);
|
|||
|
|
if (instance.block) {
|
|||
|
|
unmountComponent(instance, container, parentSuspense);
|
|||
|
|
if (!doRemove) {
|
|||
|
|
const blockContainer = needsHostParentForRemove(instance.block) ? anchor && anchor.parentNode : void 0;
|
|||
|
|
remove(instance.block, blockContainer);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
unmountComponent(instance, container, parentSuspense);
|
|||
|
|
if (!doRemove) instance.pendingBlock = void 0;
|
|||
|
|
}
|
|||
|
|
queueInteropVNodeHook(instance, vnodeHooks && vnodeHooks.onVnodeUnmounted, vnode, parentSuspense);
|
|||
|
|
} else if (vnode.vb) {
|
|||
|
|
const anchor = vnode.anchor;
|
|||
|
|
if (vnode.el && vnode.el !== anchor && isRangeStart(vnode.el)) slotStartAnchor = vnode.el;
|
|||
|
|
const blockContainer = container || (needsHostParentForRemove(vnode.vb) ? anchor && anchor.parentNode : void 0);
|
|||
|
|
stopVaporSlotScope(vnode);
|
|||
|
|
remove(vnode.vb, blockContainer);
|
|||
|
|
}
|
|||
|
|
if (doRemove) {
|
|||
|
|
if (slotStartAnchor) {
|
|||
|
|
const parent = slotStartAnchor.parentNode;
|
|||
|
|
if (parent) remove(slotStartAnchor, parent);
|
|||
|
|
}
|
|||
|
|
const anchor = vnode.anchor;
|
|||
|
|
const parent = anchor.parentNode;
|
|||
|
|
if (parent) remove(anchor, parent);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
/**
|
|||
|
|
* vapor slot in vdom
|
|||
|
|
*/
|
|||
|
|
slot(n1, n2, container, anchor, parentComponent, parentSuspense, slotScopeIds) {
|
|||
|
|
if (!n1) {
|
|||
|
|
const slotBlock = renderVaporSlot(n2, parentComponent, parentSuspense, slotScopeIds);
|
|||
|
|
const selfAnchor = (isFragment(slotBlock) ? slotBlock.anchor : void 0) || /* @__PURE__ */ createTextNode();
|
|||
|
|
insert(n2.el = n2.anchor = selfAnchor, container, anchor);
|
|||
|
|
insert(n2.vb = slotBlock, container, selfAnchor, parentSuspense);
|
|||
|
|
} else if (!n1.vs || !n2.vs || !n1.vs.slot || !n2.vs.slot || n2.vs.slot !== n1.vs.slot) {
|
|||
|
|
const selfAnchor = n1.anchor;
|
|||
|
|
const parent = selfAnchor.parentNode;
|
|||
|
|
const nextSibling = selfAnchor.nextSibling;
|
|||
|
|
const rangeStartAnchor = n1.el && n1.el !== selfAnchor && isRangeStart(n1.el) ? n1.el : void 0;
|
|||
|
|
const oldBlockOwnsAnchor = isFragment(n1.vb) && n1.vb.anchor === selfAnchor;
|
|||
|
|
stopVaporSlotScope(n1);
|
|||
|
|
remove(n1.vb, parent);
|
|||
|
|
const slotBlock = renderVaporSlot(n2, parentComponent, parentSuspense, slotScopeIds);
|
|||
|
|
let newAnchor = isFragment(slotBlock) ? slotBlock.anchor : void 0;
|
|||
|
|
let insertAnchor = nextSibling;
|
|||
|
|
if (newAnchor) {
|
|||
|
|
if (!oldBlockOwnsAnchor) remove(selfAnchor, parent);
|
|||
|
|
} else if (oldBlockOwnsAnchor) newAnchor = /* @__PURE__ */ createTextNode();
|
|||
|
|
else {
|
|||
|
|
newAnchor = selfAnchor;
|
|||
|
|
insertAnchor = selfAnchor;
|
|||
|
|
}
|
|||
|
|
insert(n2.anchor = newAnchor, parent, insertAnchor);
|
|||
|
|
n2.el = rangeStartAnchor || newAnchor;
|
|||
|
|
insert(n2.vb = slotBlock, parent, newAnchor, parentSuspense);
|
|||
|
|
} else {
|
|||
|
|
const vs1 = n1.vs;
|
|||
|
|
const vs2 = n2.vs;
|
|||
|
|
n2.el = n1.el;
|
|||
|
|
n2.anchor = n1.anchor;
|
|||
|
|
n2.vb = n1.vb;
|
|||
|
|
(vs2.ref = vs1.ref).value = n2.props;
|
|||
|
|
vs2.scope = vs1.scope;
|
|||
|
|
syncInteropVaporSlotState(n1, n2);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
move(vnode, container, anchor, moveType, parentSuspense) {
|
|||
|
|
const block = vnode.vb || vnode.component;
|
|||
|
|
const pendingRangeOwnsFragmentStart = isVaporComponent(block) && !!block.pendingBlock;
|
|||
|
|
if (vnode.el && vnode.el !== vnode.anchor && isRangeStart(vnode.el) && !pendingRangeOwnsFragmentStart) move(vnode.el, container, anchor, moveType, void 0, parentSuspense);
|
|||
|
|
move(block, container, anchor, moveType, void 0, parentSuspense);
|
|||
|
|
move(vnode.anchor, container, anchor, moveType, void 0, parentSuspense);
|
|||
|
|
},
|
|||
|
|
hydrate(vnode, node, container, anchor, parentComponent, parentSuspense) {
|
|||
|
|
if (!isHydrating$1 && !isHydrating && !isHydratingEnabled) return node;
|
|||
|
|
let instance;
|
|||
|
|
hydrateNode(node, () => {
|
|||
|
|
instance = this.mount(vnode, container, anchor, parentComponent, parentSuspense);
|
|||
|
|
});
|
|||
|
|
if (instance && instance.asyncDep && !instance.asyncResolved) vnode.el = node;
|
|||
|
|
return anchor;
|
|||
|
|
},
|
|||
|
|
hydrateSlot(vnode, node, parentComponent, parentSuspense, slotScopeIds) {
|
|||
|
|
if (!isHydrating$1 && !isHydrating && !isHydratingEnabled) return node;
|
|||
|
|
const isFallbackRange = isComment(node, "(");
|
|||
|
|
const close = isFallbackRange ? locateEndAnchor(node) : isRangeEnd(node) ? node : isRangeStart(node) && node.nextSibling && isRangeEnd(node.nextSibling) ? node.nextSibling : null;
|
|||
|
|
if (close) {
|
|||
|
|
const ownsRange = close !== node;
|
|||
|
|
mountSlotWithoutHydration(vnode, ownsRange ? node : null, close, parentComponent, parentSuspense, slotScopeIds, isFallbackRange ? {
|
|||
|
|
depth: 0,
|
|||
|
|
first: node.nextSibling,
|
|||
|
|
close
|
|||
|
|
} : void 0);
|
|||
|
|
return ownsRange ? close.nextSibling : close;
|
|||
|
|
}
|
|||
|
|
const container = /* @__PURE__ */ parentNode(node);
|
|||
|
|
let createdAnchor = false;
|
|||
|
|
let resumeNode = null;
|
|||
|
|
hydrateNode(node, () => {
|
|||
|
|
vnode.vb = renderVaporSlot(vnode, parentComponent, parentSuspense, slotScopeIds);
|
|||
|
|
const fragmentAnchor = isFragment(vnode.vb) && vnode.vb.anchor;
|
|||
|
|
let anchor = fragmentAnchor || currentHydrationNode;
|
|||
|
|
const wrapped = isRangeStart(node) && isRangeEnd(anchor);
|
|||
|
|
if (!fragmentAnchor && !wrapped) {
|
|||
|
|
createdAnchor = true;
|
|||
|
|
resumeNode = anchor && /* @__PURE__ */ parentNode(anchor) === container ? anchor : null;
|
|||
|
|
anchor = /* @__PURE__ */ createTextNode();
|
|||
|
|
container.insertBefore(anchor, resumeNode);
|
|||
|
|
}
|
|||
|
|
if (isRangeStart(node) && isRangeEnd(anchor)) {
|
|||
|
|
vnode.el = node;
|
|||
|
|
vnode.anchor = anchor;
|
|||
|
|
} else vnode.anchor = vnode.el = anchor;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && !vnode.anchor) throw new Error(`Failed to locate slot anchor. this is likely a Vue internal bug.`);
|
|||
|
|
});
|
|||
|
|
if (createdAnchor) return resumeNode;
|
|||
|
|
return isRangeStart(node) ? vnode.anchor.nextSibling : vnode.anchor;
|
|||
|
|
},
|
|||
|
|
hydrateSlotOutlet(outlet, open, parentComponent, parentSuspense, slotScopeIds) {
|
|||
|
|
if (!isHydrating$1 && !isHydrating && !isHydratingEnabled) return open.nextSibling;
|
|||
|
|
return hydrateOutletFallback(outlet.children, open.nextSibling, locateEndAnchor(open), 0, parentComponent, parentSuspense, slotScopeIds);
|
|||
|
|
},
|
|||
|
|
attachSlotOutlet,
|
|||
|
|
setTransitionHooks(component, hooks) {
|
|||
|
|
ensureTransitionHooksRegistered();
|
|||
|
|
setTransitionHooks$1(component, hooks);
|
|||
|
|
},
|
|||
|
|
activate(vnode, container, anchor, parentComponent, parentSuspense) {
|
|||
|
|
const cached = parentComponent.ctx.getCachedComponent(vnode);
|
|||
|
|
vnode.el = cached.el;
|
|||
|
|
vnode.component = cached.component;
|
|||
|
|
vnode.anchor = cached.anchor;
|
|||
|
|
const instance = getVaporInstance(vnode);
|
|||
|
|
const vnodeHookState = ensureVNodeHookState(instance, vnode);
|
|||
|
|
const rootEl = getRootElement(instance);
|
|||
|
|
if (rootEl) vnode.el = rootEl;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && vnode.dirs && !rootEl) warnNonElementRootDirs();
|
|||
|
|
if (shouldUpdateComponent(cached, vnode)) updateInteropVNode(instance, vnodeHookState, vnode, cached);
|
|||
|
|
activate$1(instance, container, anchor, parentSuspense);
|
|||
|
|
insert(vnode.anchor, container, anchor);
|
|||
|
|
queueInteropVNodeHook(instance, vnode.props && vnode.props.onVnodeMounted, vnode, parentSuspense);
|
|||
|
|
},
|
|||
|
|
deactivate(vnode, container, parentSuspense) {
|
|||
|
|
const instance = getVaporInstance(vnode);
|
|||
|
|
deactivate$1(instance, container, parentSuspense);
|
|||
|
|
insert(vnode.anchor, container);
|
|||
|
|
queueInteropVNodeHook(instance, vnode.props && vnode.props.onVnodeUnmounted, vnode, parentSuspense);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
const vaporSlotPropsProxyHandler = {
|
|||
|
|
get(target, key) {
|
|||
|
|
return target.value[key];
|
|||
|
|
},
|
|||
|
|
has(target, key) {
|
|||
|
|
return key in target.value;
|
|||
|
|
},
|
|||
|
|
ownKeys(target) {
|
|||
|
|
return Reflect.ownKeys(target.value);
|
|||
|
|
},
|
|||
|
|
getOwnPropertyDescriptor(target, key) {
|
|||
|
|
if (key in target.value) return {
|
|||
|
|
enumerable: true,
|
|||
|
|
configurable: true
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
const vaporSlotWrappersCache = /* @__PURE__ */ new WeakMap();
|
|||
|
|
const vaporSlotsProxyHandler = {
|
|||
|
|
get(target, key) {
|
|||
|
|
const slot = isString(key) && !isInternalSlotKey(key) ? getSlot(target, key) : target[key];
|
|||
|
|
if (isFunction(slot)) {
|
|||
|
|
slot[rawVaporSlotKey] = slot;
|
|||
|
|
let wrappers = vaporSlotWrappersCache.get(target);
|
|||
|
|
if (!wrappers) vaporSlotWrappersCache.set(target, wrappers = /* @__PURE__ */ new Map());
|
|||
|
|
const cached = wrappers.get(key);
|
|||
|
|
if (cached && cached.slot === slot) return cached.wrapped;
|
|||
|
|
const wrapped = (props) => [renderSlot({ [key]: slot }, key, props)];
|
|||
|
|
wrapped[rawVaporSlotKey] = slot;
|
|||
|
|
wrapped._n = true;
|
|||
|
|
wrappers.set(key, {
|
|||
|
|
slot,
|
|||
|
|
wrapped
|
|||
|
|
});
|
|||
|
|
return wrapped;
|
|||
|
|
}
|
|||
|
|
return slot;
|
|||
|
|
},
|
|||
|
|
ownKeys(target) {
|
|||
|
|
return Array.from(dynamicSlotsProxyHandlers.ownKeys(target)).filter((key) => isString(key) && !isInternalSlotKey(key));
|
|||
|
|
},
|
|||
|
|
getOwnPropertyDescriptor(target, key) {
|
|||
|
|
if (!isString(key) || isInternalSlotKey(key)) return;
|
|||
|
|
return dynamicSlotsProxyHandlers.getOwnPropertyDescriptor(target, key);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
let vdomHydrateNode;
|
|||
|
|
function resolveVNodeRange(vnode) {
|
|||
|
|
const { type, shapeFlag, el, anchor } = vnode;
|
|||
|
|
if (shapeFlag & 64 && el && anchor && anchor !== el) return [el, anchor];
|
|||
|
|
if ((type === Static || type === Fragment) && anchor) return el && anchor !== el ? [el, anchor] : [anchor, anchor];
|
|||
|
|
if (shapeFlag & 6) {
|
|||
|
|
const subTree = vnode.component && vnode.component.subTree;
|
|||
|
|
if (subTree) return resolveVNodeRange(subTree);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function resolveVNodeNodes(vnode) {
|
|||
|
|
if (vnode.component && isVaporComponent(vnode.component)) {
|
|||
|
|
const block = vnode.component.block;
|
|||
|
|
if (block) {
|
|||
|
|
const anchor = vnode.anchor;
|
|||
|
|
if (anchor) return [block, anchor];
|
|||
|
|
return block;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (vnode.type === VaporSlot && vnode.vb) {
|
|||
|
|
const { el, anchor, vb } = vnode;
|
|||
|
|
if (!anchor) return vb;
|
|||
|
|
return el && el !== anchor && isRangeStart(el) ? [
|
|||
|
|
el,
|
|||
|
|
vb,
|
|||
|
|
anchor
|
|||
|
|
] : [vb, anchor];
|
|||
|
|
}
|
|||
|
|
const vnodeRange = resolveVNodeRange(vnode);
|
|||
|
|
if (vnodeRange) {
|
|||
|
|
const nodeRange = [];
|
|||
|
|
let n = vnodeRange[0];
|
|||
|
|
while (n) {
|
|||
|
|
nodeRange.push(n);
|
|||
|
|
if (n === vnodeRange[1]) break;
|
|||
|
|
n = n.nextSibling;
|
|||
|
|
}
|
|||
|
|
return nodeRange;
|
|||
|
|
}
|
|||
|
|
if (vnode.shapeFlag & 6) {
|
|||
|
|
const subTree = vnode.component && vnode.component.subTree;
|
|||
|
|
if (subTree) return resolveVNodeNodes(subTree);
|
|||
|
|
}
|
|||
|
|
return vnode.el;
|
|||
|
|
}
|
|||
|
|
function removeAttachedNodes(block, parent) {
|
|||
|
|
if (block instanceof Node) {
|
|||
|
|
if (block.parentNode === parent) remove(block, parent);
|
|||
|
|
} else if (isArray(block)) for (let i = 0; i < block.length; i++) removeAttachedNodes(block[i], parent);
|
|||
|
|
}
|
|||
|
|
function trackFragmentVNodeUpdates(frag, vnode, syncNodes) {
|
|||
|
|
vnode.ibu = () => {
|
|||
|
|
if (frag.bu) frag.bu.forEach((hook) => hook());
|
|||
|
|
};
|
|||
|
|
vnode.iu = () => {
|
|||
|
|
syncNodes();
|
|||
|
|
if (frag.u) frag.u.forEach((hook) => hook(frag.nodes));
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Shared content cell for interop fragments. Hosts write the subset they
|
|||
|
|
* own — do not read a field the host does not maintain (`valid` stays false
|
|||
|
|
* where validity is derived live from the nodes; `nodes` stays EMPTY_BLOCK
|
|||
|
|
* where the fragment's own `nodes` is the snapshot).
|
|||
|
|
*
|
|||
|
|
* `resolved` implements the optimistic-validity rule every interop fragment
|
|||
|
|
* shares: nodes stay unresolved until the first sync (on insert / after
|
|||
|
|
* patch), and validity reports true until then to keep a host boundary from
|
|||
|
|
* mounting its fallback before the content exists. This keeps the common
|
|||
|
|
* (valid) case free — an empty result is corrected later when the resolve
|
|||
|
|
* path notifies the boundary to recheck; starting invalid would instead
|
|||
|
|
* mount-then-teardown the fallback on every interop mount. Hydration starts
|
|||
|
|
* resolved (SSR nodes exist).
|
|||
|
|
*/
|
|||
|
|
var InteropContentState = class {
|
|||
|
|
constructor() {
|
|||
|
|
this.nodes = EMPTY_BLOCK;
|
|||
|
|
this.valid = false;
|
|||
|
|
this.resolved = isHydrating$1;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
function createVNodeFragment(vnode) {
|
|||
|
|
const frag = createInteropFragment(EMPTY_BLOCK, vnode);
|
|||
|
|
frag.$key = vnodeKeyOf(vnode);
|
|||
|
|
const content = new InteropContentState();
|
|||
|
|
const syncNodes = () => {
|
|||
|
|
frag.nodes = resolveVNodeNodes(frag.vnode);
|
|||
|
|
content.resolved = true;
|
|||
|
|
};
|
|||
|
|
frag.isBlockValid = (componentAsValid) => content.resolved ? isValidBlock(frag.nodes, componentAsValid) : true;
|
|||
|
|
trackFragmentVNodeUpdates(frag, vnode, syncNodes);
|
|||
|
|
return {
|
|||
|
|
frag,
|
|||
|
|
syncNodes
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Mount a vnode as a dynamic component branch (`<component :is="vnode">`
|
|||
|
|
* in a vapor template). The KeepAlive lookup, fallthrough and hydration of
|
|||
|
|
* the vnode live here so the dynamic component only sees a block.
|
|||
|
|
*/
|
|||
|
|
function mountDynamicVNode(internals, vnode, parentComponent, isSingleRoot, rawProps, once) {
|
|||
|
|
if (parentComponent && isKeepAlive(parentComponent)) {
|
|||
|
|
const cached = parentComponent.ctx.getCachedComponent(vnode.type, vnode.key);
|
|||
|
|
if (cached) {
|
|||
|
|
if (cached.patchVNode) cached.patchVNode(vnode);
|
|||
|
|
return cached;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (once && rawProps) rawProps = snapshotRawProps(rawProps);
|
|||
|
|
const owner = resolveFallthroughOwner(isSingleRoot);
|
|||
|
|
if (owner) {
|
|||
|
|
const source = () => resolveFallthroughAttrs(owner);
|
|||
|
|
const sources = rawProps && rawProps.$;
|
|||
|
|
rawProps = extend$1({}, rawProps, { $: sources ? sources.concat(source) : [source] });
|
|||
|
|
}
|
|||
|
|
const frag = mountVNode(internals, vnode, parentComponent, rawProps ? new Proxy(rawProps, rawPropsProxyHandlers) : void 0, once && !owner);
|
|||
|
|
if (isHydrating$1) {
|
|||
|
|
locateHydrationNode(shouldConsumeFragmentStart(vnode) ? createFragmentClaim() : void 0);
|
|||
|
|
frag.hydrate();
|
|||
|
|
}
|
|||
|
|
return frag;
|
|||
|
|
}
|
|||
|
|
function shouldConsumeFragmentStart(vnode) {
|
|||
|
|
if (vnode.type === Fragment) return false;
|
|||
|
|
if (vnode.shapeFlag & 6) {
|
|||
|
|
const type = vnode.type;
|
|||
|
|
return !!type.__vapor && !type.__multiRoot;
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Mount VNode in vapor
|
|||
|
|
*/
|
|||
|
|
function mountVNode(internals, vnode, parentComponent, extraProps, staticExtraProps) {
|
|||
|
|
let suspense = currentRenderContext.suspense || parentComponent && parentComponent.suspense;
|
|||
|
|
let baseVNode = vnode;
|
|||
|
|
const withExtraProps = (base) => {
|
|||
|
|
const cloned = cloneVNode(base, extraProps, true);
|
|||
|
|
if (cloned.key !== base.key) {
|
|||
|
|
var _base$key;
|
|||
|
|
cloned.key = base.key;
|
|||
|
|
cloned.props.key = (_base$key = base.key) !== null && _base$key !== void 0 ? _base$key : void 0;
|
|||
|
|
}
|
|||
|
|
return cloned;
|
|||
|
|
};
|
|||
|
|
if (extraProps) vnode = withExtraProps(baseVNode);
|
|||
|
|
const { frag, syncNodes } = createVNodeFragment(vnode);
|
|||
|
|
let isMounted = false;
|
|||
|
|
let mountedParentNode;
|
|||
|
|
let mountedAnchor = null;
|
|||
|
|
let namespace;
|
|||
|
|
let isUnmounted = false;
|
|||
|
|
const unmount = (parentNode, transition) => {
|
|||
|
|
if (isUnmounted) {
|
|||
|
|
if (parentNode) {
|
|||
|
|
removeAttachedNodes(resolveVNodeNodes(vnode), parentNode);
|
|||
|
|
if (vnode.anchor && vnode.anchor.parentNode === parentNode) remove(vnode.anchor, parentNode);
|
|||
|
|
}
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (transition) setTransitionHooks(vnode, transition);
|
|||
|
|
const parentSuspense = resolveUnmountSuspense(suspense);
|
|||
|
|
if (vnode.shapeFlag & 256) {
|
|||
|
|
const keepAliveCtx = parentComponent.ctx;
|
|||
|
|
keepAliveCtx.clearCurrent(frag);
|
|||
|
|
const storageContainer = keepAliveCtx.getStorageContainer();
|
|||
|
|
if (vnode.type.__vapor) {
|
|||
|
|
deactivate$1(vnode.component, storageContainer, parentSuspense);
|
|||
|
|
insert(vnode.anchor, storageContainer);
|
|||
|
|
} else deactivate(vnode, storageContainer, internals, parentComponent, parentSuspense);
|
|||
|
|
} else {
|
|||
|
|
isUnmounted = true;
|
|||
|
|
internals.um(vnode, parentComponent, parentSuspense, !!parentNode);
|
|||
|
|
}
|
|||
|
|
if (vnode.anchor && parentNode && vnode.anchor.parentNode === parentNode) remove(vnode.anchor, parentNode);
|
|||
|
|
};
|
|||
|
|
frag.hydrate = () => {
|
|||
|
|
if (!isHydrating$1) return;
|
|||
|
|
hydrateVNode(vnode, parentComponent, frag.slotScopeIds, suspense);
|
|||
|
|
isMounted = true;
|
|||
|
|
const anchorNode = vnode.anchor || vnode.el;
|
|||
|
|
if (anchorNode && anchorNode.parentNode) {
|
|||
|
|
mountedParentNode = anchorNode.parentNode;
|
|||
|
|
namespace = getContainerType(mountedParentNode);
|
|||
|
|
}
|
|||
|
|
syncNodes();
|
|||
|
|
};
|
|||
|
|
const place = (parentNode, anchor, parentSuspense, transition, moveType = 2) => {
|
|||
|
|
if (isHydrating$1) return;
|
|||
|
|
if (parentSuspense !== void 0) suspense = parentSuspense;
|
|||
|
|
const operationSuspense = suspense;
|
|||
|
|
if (vnode.shapeFlag & 512) {
|
|||
|
|
if (vnode.type.__vapor) {
|
|||
|
|
activate$1(vnode.component, parentNode, anchor, operationSuspense);
|
|||
|
|
insert(vnode.anchor, parentNode, anchor);
|
|||
|
|
} else activate(vnode, parentNode, anchor, internals, parentComponent, operationSuspense, void 0, false);
|
|||
|
|
return;
|
|||
|
|
} else {
|
|||
|
|
const prev = currentInstance;
|
|||
|
|
simpleSetCurrentInstance(null);
|
|||
|
|
if (!isMounted) {
|
|||
|
|
if (transition) setTransitionHooks(vnode, transition);
|
|||
|
|
namespace = getContainerType(parentNode);
|
|||
|
|
internals.p(null, vnode, parentNode, anchor, parentComponent, operationSuspense, namespace, frag.slotScopeIds);
|
|||
|
|
isMounted = true;
|
|||
|
|
} else {
|
|||
|
|
if (transition && moveType !== 2) setTransitionHooks(vnode, transition);
|
|||
|
|
internals.m(vnode, parentNode, anchor, moveType, parentComponent, operationSuspense);
|
|||
|
|
}
|
|||
|
|
simpleSetCurrentInstance(prev);
|
|||
|
|
mountedParentNode = parentNode;
|
|||
|
|
mountedAnchor = anchor;
|
|||
|
|
}
|
|||
|
|
syncNodes();
|
|||
|
|
if (isMounted && frag.u) frag.u.forEach((hook) => hook(frag.nodes));
|
|||
|
|
};
|
|||
|
|
frag.insert = (parentNode, anchor, parentSuspense, transition) => place(parentNode, anchor, parentSuspense, transition);
|
|||
|
|
frag.move = (parentNode, anchor, moveType, _parentComponent, parentSuspense, transition) => place(parentNode, anchor, parentSuspense, transition, moveType);
|
|||
|
|
const update = () => {
|
|||
|
|
const next = extraProps ? withExtraProps(baseVNode) : baseVNode;
|
|||
|
|
if (!mountedParentNode) return;
|
|||
|
|
const previous = vnode;
|
|||
|
|
if (frag.$transition) setTransitionHooks(next, frag.$transition);
|
|||
|
|
if (previous.vaporScopeIds) setVNodeVaporScopeIds(next, previous.vaporScopeIds);
|
|||
|
|
next.shapeFlag |= previous.shapeFlag & 768;
|
|||
|
|
vnode = next;
|
|||
|
|
trackFragmentVNodeUpdates(frag, vnode, syncNodes);
|
|||
|
|
frag.vnode = vnode;
|
|||
|
|
frag.$key = vnodeKeyOf(vnode);
|
|||
|
|
const prevInstance = currentInstance;
|
|||
|
|
simpleSetCurrentInstance(null);
|
|||
|
|
internals.p(previous, vnode, mountedParentNode, mountedAnchor, parentComponent, suspense, namespace, frag.slotScopeIds);
|
|||
|
|
simpleSetCurrentInstance(prevInstance);
|
|||
|
|
syncNodes();
|
|||
|
|
};
|
|||
|
|
frag.patchVNode = (next) => {
|
|||
|
|
if (next.type !== baseVNode.type) return;
|
|||
|
|
baseVNode = next;
|
|||
|
|
const prevSub = setActiveSub();
|
|||
|
|
try {
|
|||
|
|
update();
|
|||
|
|
} finally {
|
|||
|
|
setActiveSub(prevSub);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
if (extraProps && !staticExtraProps) renderEffect(update);
|
|||
|
|
frag.remove = unmount;
|
|||
|
|
return frag;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Mount vdom component in vapor
|
|||
|
|
*/
|
|||
|
|
function createVDOMComponent(internals, component, parentComponent, rawProps, rawSlots, once, inputScope) {
|
|||
|
|
let suspense = currentRenderContext.suspense || parentComponent && parentComponent.suspense;
|
|||
|
|
const useBridge = shouldUseRendererBridge(component);
|
|||
|
|
const comp = useBridge ? ensureRendererBridge(component) : component;
|
|||
|
|
let propsInstance;
|
|||
|
|
let rawValues = EMPTY_OBJ;
|
|||
|
|
let isMounted = false;
|
|||
|
|
let cells;
|
|||
|
|
const isolated = rawSlots && isolateSlotSources(rawSlots);
|
|||
|
|
if (isolated) {
|
|||
|
|
rawSlots = isolated[0];
|
|||
|
|
cells = isolated[1];
|
|||
|
|
}
|
|||
|
|
let hasDynamicProps = !once && (!!cells || hasDynamicPropsSource(rawProps || EMPTY_OBJ));
|
|||
|
|
if (hasDynamicProps) inputScope || (inputScope = effectScope(true));
|
|||
|
|
const prevInstance = setCurrentInstance(parentComponent, inputScope);
|
|||
|
|
let vnode;
|
|||
|
|
try {
|
|||
|
|
if (!hasDynamicProps) {
|
|||
|
|
rawValues = collectInputs(rawProps || EMPTY_OBJ, cells);
|
|||
|
|
if (cells) deliverInputs(void 0, void 0, cells);
|
|||
|
|
} else {
|
|||
|
|
const effect = new RenderEffect(() => {
|
|||
|
|
const prevInner = setCurrentInstance(parentComponent, inputScope);
|
|||
|
|
try {
|
|||
|
|
rawValues = collectProps(rawProps || EMPTY_OBJ, rawValues.style);
|
|||
|
|
if (cells) collectSlotSources(cells);
|
|||
|
|
} finally {
|
|||
|
|
restoreCurrentInstance(prevInner);
|
|||
|
|
}
|
|||
|
|
if (effect.active && (propsInstance || cells)) deliverInputs(propsInstance, rawValues, cells);
|
|||
|
|
}, true);
|
|||
|
|
effect.run();
|
|||
|
|
if (!effect.deps) {
|
|||
|
|
effect.stop();
|
|||
|
|
hasDynamicProps = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
vnode = createVNode(comp, rawValues);
|
|||
|
|
} catch (error) {
|
|||
|
|
if (inputScope) inputScope.stop();
|
|||
|
|
throw error;
|
|||
|
|
} finally {
|
|||
|
|
restoreCurrentInstance(prevInstance);
|
|||
|
|
}
|
|||
|
|
const { frag, syncNodes } = createVNodeFragment(vnode);
|
|||
|
|
frag.inputScope = inputScope;
|
|||
|
|
onScopeDispose(() => {
|
|||
|
|
if (!isMounted && inputScope) inputScope.stop();
|
|||
|
|
}, true);
|
|||
|
|
const keepAliveCtx = isKeepAliveEnabled ? getKeepAliveContext(parentComponent) : null;
|
|||
|
|
if (keepAliveCtx) {
|
|||
|
|
keepAliveCtx.processShapeFlag(frag);
|
|||
|
|
if (component.__asyncLoader) {
|
|||
|
|
let disposed = false;
|
|||
|
|
onScopeDispose(() => disposed = true);
|
|||
|
|
component.__asyncLoader().then(() => {
|
|||
|
|
if (!disposed) keepAliveCtx.cacheBlock(frag);
|
|||
|
|
}).catch(NOOP);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (!once && component.__asyncLoader && rawSlots && rawSlots.$) renderEffect(() => {
|
|||
|
|
dynamicSlotsProxyHandlers.ownKeys(rawSlots);
|
|||
|
|
const instance = vnode.component;
|
|||
|
|
if (instance && instance.isMounted) instance.update();
|
|||
|
|
}, true);
|
|||
|
|
vnode.vi = (instance) => {
|
|||
|
|
const prev = currentInstance;
|
|||
|
|
simpleSetCurrentInstance(parentComponent);
|
|||
|
|
const wrapper = propsInstance = new VaporComponentInstance(useBridge ? comp : {
|
|||
|
|
props: instance.propsOptions[0],
|
|||
|
|
__propsOptions: instance.propsOptions
|
|||
|
|
}, void 0, rawSlots, parentComponent ? parentComponent.appContext : void 0);
|
|||
|
|
simpleSetCurrentInstance(prev);
|
|||
|
|
wrapper.interopVNode = vnode;
|
|||
|
|
wrapper.hasDynamicProps = hasDynamicProps;
|
|||
|
|
instance.scope.run(() => {
|
|||
|
|
onScopeDispose(() => {
|
|||
|
|
if (inputScope) inputScope.stop();
|
|||
|
|
wrapper.scope.stop();
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
try {
|
|||
|
|
deliverInputs(wrapper, rawValues);
|
|||
|
|
} catch (error) {
|
|||
|
|
if (inputScope) inputScope.stop();
|
|||
|
|
wrapper.scope.stop();
|
|||
|
|
throw error;
|
|||
|
|
}
|
|||
|
|
const attrs = createInternalObject();
|
|||
|
|
const isFilteredAttr = (key) => typeof key === "string" && (isReservedProp(key) || isEmitListener(instance.emitsOptions, key));
|
|||
|
|
instance.attrs = new Proxy(attrs, {
|
|||
|
|
get(_, key) {
|
|||
|
|
if (isFilteredAttr(key)) return;
|
|||
|
|
return wrapper.attrs[key];
|
|||
|
|
},
|
|||
|
|
has(_, key) {
|
|||
|
|
return !isFilteredAttr(key) && key in wrapper.attrs;
|
|||
|
|
},
|
|||
|
|
ownKeys() {
|
|||
|
|
return Reflect.ownKeys(wrapper.attrs).filter((key) => !isFilteredAttr(key));
|
|||
|
|
},
|
|||
|
|
getOwnPropertyDescriptor(_, key) {
|
|||
|
|
if (!isFilteredAttr(key) && key in wrapper.attrs) return {
|
|||
|
|
enumerable: true,
|
|||
|
|
configurable: true
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
instance.props = vnode.shapeFlag & 2 && !comp.props ? instance.attrs : shallowReactive(wrapper.props);
|
|||
|
|
instance.slots = wrapper.rawSlots === EMPTY_OBJ ? createInternalObject() : new Proxy(wrapper.rawSlots, vaporSlotsProxyHandler);
|
|||
|
|
if (component.__asyncLoader && wrapper.rawSlots !== EMPTY_OBJ) {
|
|||
|
|
vnode.children = instance.slots;
|
|||
|
|
vnode.shapeFlag |= 32;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
let rawRef;
|
|||
|
|
let isUnmounted = false;
|
|||
|
|
let isDomRemoved = false;
|
|||
|
|
const removeDom = (parentNode) => {
|
|||
|
|
if (!parentNode || isDomRemoved) return;
|
|||
|
|
removeAttachedNodes(resolveVNodeNodes(vnode), parentNode);
|
|||
|
|
isDomRemoved = true;
|
|||
|
|
};
|
|||
|
|
const unmount = (parentNode, transition) => {
|
|||
|
|
if (isUnmounted) {
|
|||
|
|
if (!transition) removeDom(parentNode);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (transition) setTransitionHooks(vnode, transition);
|
|||
|
|
const parentSuspense = resolveUnmountSuspense(suspense);
|
|||
|
|
if (vnode.shapeFlag & 256) {
|
|||
|
|
if (rawRef) setRef(rawRef, null, null, vnode, true);
|
|||
|
|
if (frag.inputScope) frag.inputScope.pause();
|
|||
|
|
keepAliveCtx.clearCurrent(frag);
|
|||
|
|
deactivate(vnode, keepAliveCtx.getStorageContainer(), internals, parentComponent, parentSuspense);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
isUnmounted = true;
|
|||
|
|
isMounted = false;
|
|||
|
|
if (inputScope) inputScope.stop();
|
|||
|
|
internals.um(vnode, parentComponent, parentSuspense, !!parentNode);
|
|||
|
|
if (!transition) removeDom(parentNode);
|
|||
|
|
};
|
|||
|
|
frag.hydrate = () => {
|
|||
|
|
if (!isHydrating$1) return;
|
|||
|
|
hydrateVNode(vnode, parentComponent, frag.slotScopeIds, suspense);
|
|||
|
|
isMounted = true;
|
|||
|
|
syncNodes();
|
|||
|
|
};
|
|||
|
|
vnode.scopeId = getCurrentScopeId() || null;
|
|||
|
|
vnode.slotScopeIds = currentRenderContext.slotScopeIds;
|
|||
|
|
const place = (parentNode, anchor, parentSuspense, transition, moveType = 2) => {
|
|||
|
|
if (isHydrating$1) return;
|
|||
|
|
if (parentSuspense !== void 0) suspense = parentSuspense;
|
|||
|
|
const operationSuspense = suspense;
|
|||
|
|
if (vnode.shapeFlag & 512) {
|
|||
|
|
if (frag.inputScope) frag.inputScope.resume();
|
|||
|
|
activate(vnode, parentNode, anchor, internals, parentComponent, operationSuspense, void 0, false);
|
|||
|
|
} else {
|
|||
|
|
const prev = currentInstance;
|
|||
|
|
simpleSetCurrentInstance(null);
|
|||
|
|
if (!isMounted) {
|
|||
|
|
if (transition) setTransitionHooks(vnode, transition);
|
|||
|
|
internals.mt(vnode, parentNode, anchor, parentComponent, operationSuspense, getContainerType(parentNode), false);
|
|||
|
|
if (rawRef) setRef(rawRef, null, operationSuspense, vnode);
|
|||
|
|
isMounted = true;
|
|||
|
|
} else {
|
|||
|
|
if (transition && moveType !== 2) setTransitionHooks(vnode, transition);
|
|||
|
|
internals.m(vnode, parentNode, anchor, moveType, parentComponent, operationSuspense);
|
|||
|
|
}
|
|||
|
|
simpleSetCurrentInstance(prev);
|
|||
|
|
}
|
|||
|
|
syncNodes();
|
|||
|
|
if (isMounted && frag.u) frag.u.forEach((hook) => hook(frag.nodes));
|
|||
|
|
};
|
|||
|
|
frag.insert = (parentNode, anchor, parentSuspense, transition) => place(parentNode, anchor, parentSuspense, transition);
|
|||
|
|
frag.move = (parentNode, anchor, moveType, _parentComponent, parentSuspense, transition) => place(parentNode, anchor, parentSuspense, transition, moveType);
|
|||
|
|
frag.remove = unmount;
|
|||
|
|
frag.setRef = (instance, ref, refFor, refKey) => {
|
|||
|
|
const oldRawRef = rawRef;
|
|||
|
|
rawRef = normalizeRef({
|
|||
|
|
ref,
|
|||
|
|
ref_for: refFor,
|
|||
|
|
ref_key: refKey
|
|||
|
|
}, instance);
|
|||
|
|
vnode.ref = rawRef;
|
|||
|
|
if (isMounted) {
|
|||
|
|
let target = vnode;
|
|||
|
|
if ((component.__asyncResolved || oldRawRef === void 0 && isAsyncWrapper(vnode) && !(vnode.shapeFlag & 512)) && vnode.component.subTree.component) {
|
|||
|
|
target = vnode.component.subTree;
|
|||
|
|
target.ref = rawRef;
|
|||
|
|
}
|
|||
|
|
if (rawRef) setRef(rawRef, oldRawRef || null, suspense, target);
|
|||
|
|
else if (oldRawRef) setRef(oldRawRef, null, null, target, true);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
return frag;
|
|||
|
|
}
|
|||
|
|
const rendererBridgeCache = /* @__PURE__ */ new WeakMap();
|
|||
|
|
/**
|
|||
|
|
* Teleport/Suspense are renderer primitives (`__isTeleport` / `__isSuspense`),
|
|||
|
|
* not regular components with their own render pipeline.
|
|||
|
|
*
|
|||
|
|
* We wrap them with a tiny functional bridge so they can pass through the
|
|||
|
|
* interop component mount path while preserving built-in vnode semantics.
|
|||
|
|
*/
|
|||
|
|
function shouldUseRendererBridge(component) {
|
|||
|
|
return !!(component.__isTeleport || component.__isSuspense);
|
|||
|
|
}
|
|||
|
|
function ensureRendererBridge(component) {
|
|||
|
|
let bridge = rendererBridgeCache.get(component);
|
|||
|
|
if (!bridge) rendererBridgeCache.set(component, bridge = (props, { slots }) => createVNode(component, props, slots));
|
|||
|
|
return bridge;
|
|||
|
|
}
|
|||
|
|
function hasValidVNodeContent(vnode) {
|
|||
|
|
return !!ensureValidVNode(vnode.type === Fragment && isArray(vnode.children) ? vnode.children : [vnode]);
|
|||
|
|
}
|
|||
|
|
function trackSlotVNodeUpdatesWithRefresh(vnode, refresh, beforeUpdate) {
|
|||
|
|
const track = (node) => {
|
|||
|
|
if (beforeUpdate) node.ibu = beforeUpdate;
|
|||
|
|
node.iu = refresh;
|
|||
|
|
if (node.type === Fragment && isArray(node.children)) node.children.forEach((child) => {
|
|||
|
|
if (isVNode(child)) track(child);
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
track(vnode);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Construction point for the interop hosts' resolution state — the shared
|
|||
|
|
* bookkeeping fields plus the host-specific hooks. (SlotFragment, the third
|
|||
|
|
* host, implements SlotResolutionState directly as a class.)
|
|||
|
|
*/
|
|||
|
|
function createSlotResolutionState(boundary, hooks) {
|
|||
|
|
return extend$1({
|
|||
|
|
boundary,
|
|||
|
|
activeFallback: null,
|
|||
|
|
fallbackInserted: false,
|
|||
|
|
pendingRecheck: false,
|
|||
|
|
pendingRecheckForce: false,
|
|||
|
|
isReconciling: false
|
|||
|
|
}, hooks);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Exposes `$transition` through the outlet fragment so BaseTransition state
|
|||
|
|
* stays on the fragment; hooks inherited from VDOM BaseTransition are
|
|||
|
|
* filtered out on read because they belong to its own state machine.
|
|||
|
|
* Enumerable + configurable to match an object-literal accessor pair.
|
|||
|
|
*/
|
|||
|
|
function installInteropTransitionAccessor(state, frag) {
|
|||
|
|
Object.defineProperty(state, "$transition", {
|
|||
|
|
enumerable: true,
|
|||
|
|
configurable: true,
|
|||
|
|
get() {
|
|||
|
|
const transition = frag.$transition;
|
|||
|
|
return transition && isVaporTransitionHooks(transition) ? transition : void 0;
|
|||
|
|
},
|
|||
|
|
set(transition) {
|
|||
|
|
frag.$transition = transition;
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
function renderVDOMSlot(internals, slotsRef, name, props, parentComponent, options = EMPTY_OBJ) {
|
|||
|
|
const { fallback, flags = 0, adoptAnchor } = options;
|
|||
|
|
const once = !!(flags & 2);
|
|||
|
|
const sharedFallback = !!(flags & 8);
|
|||
|
|
const forwarded = isForwardedSlot(flags);
|
|||
|
|
const inheritFallback = slotInheritsFallback(flags);
|
|||
|
|
const notifiesBoundary = slotNotifiesBoundary(flags);
|
|||
|
|
let suspense = currentRenderContext.suspense || parentComponent.suspense;
|
|||
|
|
const frag = createInteropFragment(EMPTY_BLOCK, null, 128);
|
|||
|
|
const slotBoundary = frag.slotBoundary;
|
|||
|
|
const content = new InteropContentState();
|
|||
|
|
const scope = effectScope();
|
|||
|
|
let localFallback;
|
|||
|
|
let rendered = null;
|
|||
|
|
let isMounted = false;
|
|||
|
|
let currentParentNode = null;
|
|||
|
|
let slotNamespace;
|
|||
|
|
let currentAnchor = null;
|
|||
|
|
let sharedContentStorage;
|
|||
|
|
let disposed = false;
|
|||
|
|
let pendingInOutVNode;
|
|||
|
|
let pendingOutIn;
|
|||
|
|
let isContentUpdateRecheck = false;
|
|||
|
|
let slotResolutionState;
|
|||
|
|
frag.isBlockValid = (componentAsValid) => {
|
|||
|
|
if (!content.resolved) return true;
|
|||
|
|
return slotResolutionState.activeFallback ? isValidBlock(slotResolutionState.activeFallback, componentAsValid) : content.valid;
|
|||
|
|
};
|
|||
|
|
const parentBoundary = inheritFallback ? slotBoundary : null;
|
|||
|
|
const boundary = createSlotBoundary(frag, () => parentBoundary, () => localFallback, (force) => markSlotResolutionDirty(slotResolutionState, force), [cleanupInvalidContent]);
|
|||
|
|
const contentBoundary = forwarded || fallback ? boundary : null;
|
|||
|
|
slotResolutionState = createSlotResolutionState(boundary, {
|
|||
|
|
getContent: () => content.nodes,
|
|||
|
|
getParentNode: () => currentParentNode,
|
|||
|
|
getAnchor: () => currentAnchor,
|
|||
|
|
isBusy: () => false,
|
|||
|
|
isDisposed: () => disposed,
|
|||
|
|
isContentValid: () => content.valid,
|
|||
|
|
syncNodes: () => {
|
|||
|
|
frag.nodes = resolveExposedSlotNodes(slotResolutionState);
|
|||
|
|
},
|
|||
|
|
notifyExposedValidityChange: () => {
|
|||
|
|
if (notifiesBoundary && !isContentUpdateRecheck && slotBoundary) slotBoundary.markDirty();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
installInteropTransitionAccessor(slotResolutionState, frag);
|
|||
|
|
if (sharedFallback && slotBoundary) registerContentInvalid(slotBoundary, parkSharedContent, frag);
|
|||
|
|
if (notifiesBoundary) trackSlotBoundaryDirtying(frag, sharedFallback ? void 0 : cleanupInvalidContent);
|
|||
|
|
localFallback = fallback ? once ? () => withOnce(() => fallback(internals, parentComponent)) : () => fallback(internals, parentComponent) : void 0;
|
|||
|
|
const place = (parentNode, anchor, parentSuspense, moveType) => {
|
|||
|
|
if (isHydrating$1) return;
|
|||
|
|
if (parentSuspense !== void 0) suspense = parentSuspense;
|
|||
|
|
if (localFallback && !inheritFallback && !frag.anchor) {
|
|||
|
|
frag.anchor = resolveFragmentAnchor(adoptAnchor, void 0);
|
|||
|
|
if (frag.anchor !== adoptAnchor) parentNode.insertBefore(frag.anchor, anchor);
|
|||
|
|
anchor = frag.anchor;
|
|||
|
|
}
|
|||
|
|
const sharedContentParked = !!sharedContentStorage;
|
|||
|
|
currentParentNode = parentNode;
|
|||
|
|
currentAnchor = anchor;
|
|||
|
|
if (!isMounted) {
|
|||
|
|
slotNamespace = getContainerType(parentNode);
|
|||
|
|
scope.run(render);
|
|||
|
|
isMounted = true;
|
|||
|
|
} else {
|
|||
|
|
if (sharedContentParked) {
|
|||
|
|
insert(frag.nodes, parentNode, anchor, suspense);
|
|||
|
|
sharedContentStorage = void 0;
|
|||
|
|
if (slotResolutionState.activeFallback) slotResolutionState.fallbackInserted = true;
|
|||
|
|
} else if (isVNode(rendered)) internals.m(rendered, parentNode, anchor, moveType === void 0 ? 2 : moveType, parentComponent, suspense);
|
|||
|
|
else if (rendered) {
|
|||
|
|
if (moveType === void 0) insert(rendered, parentNode, anchor, suspense);
|
|||
|
|
else move(rendered, parentNode, anchor, moveType, void 0, suspense);
|
|||
|
|
}
|
|||
|
|
if (!sharedContentParked) insertActiveSlotFallback(slotResolutionState, moveType);
|
|||
|
|
}
|
|||
|
|
notifyUpdated();
|
|||
|
|
};
|
|||
|
|
frag.insert = (parentNode, anchor, parentSuspense) => place(parentNode, anchor, parentSuspense);
|
|||
|
|
frag.move = (parentNode, anchor, moveType, _parentComponent, parentSuspense) => place(parentNode, anchor, parentSuspense, moveType);
|
|||
|
|
frag.remove = (parentNode) => {
|
|||
|
|
const storage = sharedContentStorage;
|
|||
|
|
if (parentNode && !storage) currentParentNode = parentNode;
|
|||
|
|
scope.stop();
|
|||
|
|
disposed = true;
|
|||
|
|
const leavingElement = pendingOutIn && pendingOutIn.leavingElement;
|
|||
|
|
pendingOutIn = void 0;
|
|||
|
|
const leave = leavingElement && leavingElement[leaveCbKey];
|
|||
|
|
if (leave) leave(true);
|
|||
|
|
if (rendered) removeRenderedContent(rendered, storage || parentNode);
|
|||
|
|
disposeSlotResolution(slotResolutionState, storage || parentNode);
|
|||
|
|
if (storage) {
|
|||
|
|
const anchor = frag.anchor;
|
|||
|
|
if (anchor && anchor.parentNode === storage) frag.anchor = void 0;
|
|||
|
|
sharedContentStorage = void 0;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
frag.hydrate = () => {
|
|||
|
|
if (!isHydrating$1) return;
|
|||
|
|
const open = currentHydrationNode;
|
|||
|
|
if (open && isRangeEnd(open)) {
|
|||
|
|
runWithoutHydration(() => place(open.parentNode, open, void 0));
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (open && isComment(open, "(")) {
|
|||
|
|
const close = frag.anchor = claimAnchor(locateEndAnchor(open));
|
|||
|
|
hydrateSlotFallbackRange({
|
|||
|
|
first: open.nextSibling,
|
|||
|
|
close,
|
|||
|
|
boundary
|
|||
|
|
}, () => place(close.parentNode, close, void 0));
|
|||
|
|
if (slotResolutionState.activeFallback) setVNode(null);
|
|||
|
|
advanceHydrationNode(close);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
const hydrationParent = currentHydrationNode && currentHydrationNode.parentNode;
|
|||
|
|
scope.run(render);
|
|||
|
|
if (!currentParentNode) {
|
|||
|
|
currentAnchor = currentSlotEndAnchor || currentHydrationNode;
|
|||
|
|
currentParentNode = currentAnchor.parentNode;
|
|||
|
|
}
|
|||
|
|
slotNamespace = getContainerType(hydrationParent || currentParentNode);
|
|||
|
|
if (content.valid && localFallback && !inheritFallback && !frag.anchor) {
|
|||
|
|
const outletAnchor = claimUntrackedAnchor(/* @__PURE__ */ createTextNode());
|
|||
|
|
insertUntrackedAnchor(currentParentNode, currentAnchor, outletAnchor);
|
|||
|
|
frag.anchor = currentAnchor = outletAnchor;
|
|||
|
|
}
|
|||
|
|
isMounted = true;
|
|||
|
|
};
|
|||
|
|
return frag;
|
|||
|
|
function cleanupInvalidContent() {
|
|||
|
|
const pending = pendingInOutVNode;
|
|||
|
|
if (pending) {
|
|||
|
|
pendingInOutVNode = void 0;
|
|||
|
|
const transition = slotResolutionState.$transition;
|
|||
|
|
const fallback = slotResolutionState.activeFallback;
|
|||
|
|
if (transition) prepareTransitionLeave(pending, fallback && isValidSlot(fallback) ? transition : void 0, transition.props, transition.state, transition.instance, NOOP);
|
|||
|
|
internals.um(pending, parentComponent, resolveUnmountSuspense(suspense), true);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (currentParentNode) removeAttachedNodes(content.nodes, currentParentNode);
|
|||
|
|
}
|
|||
|
|
function parkSharedContent() {
|
|||
|
|
if (!currentParentNode || sharedContentStorage) return;
|
|||
|
|
invalidateExposedSlotContent(slotResolutionState);
|
|||
|
|
const storage = document.createDocumentFragment();
|
|||
|
|
let anchor = frag.anchor;
|
|||
|
|
if (!anchor || anchor.parentNode !== currentParentNode) anchor = /* @__PURE__ */ createTextNode();
|
|||
|
|
storage.appendChild(anchor);
|
|||
|
|
insert(frag.nodes, storage, anchor, suspense);
|
|||
|
|
sharedContentStorage = storage;
|
|||
|
|
currentParentNode = storage;
|
|||
|
|
currentAnchor = anchor;
|
|||
|
|
}
|
|||
|
|
function notifyUpdated() {
|
|||
|
|
syncInteropRoot(parentComponent);
|
|||
|
|
if (isMounted && frag.u) frag.u.forEach((hook) => hook(frag.nodes));
|
|||
|
|
}
|
|||
|
|
function notifyBeforeUpdate() {
|
|||
|
|
if (isMounted && frag.bu) frag.bu.forEach((hook) => hook());
|
|||
|
|
}
|
|||
|
|
function recheckAfterContentUpdate(forceResolutionRecheck = false) {
|
|||
|
|
isContentUpdateRecheck = true;
|
|||
|
|
try {
|
|||
|
|
recheckSlotResolution(slotResolutionState, forceResolutionRecheck);
|
|||
|
|
} finally {
|
|||
|
|
isContentUpdateRecheck = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function finishContentUpdate(forceResolutionRecheck = false) {
|
|||
|
|
recheckAfterContentUpdate(forceResolutionRecheck);
|
|||
|
|
notifyUpdated();
|
|||
|
|
}
|
|||
|
|
function patchSlotVNode(previous, next, slotScopeIds, valid) {
|
|||
|
|
setVNode(next);
|
|||
|
|
const refreshSlotVNode = () => {
|
|||
|
|
const prevValid = content.valid;
|
|||
|
|
const prevOutput = frag.nodes;
|
|||
|
|
setRendered(next);
|
|||
|
|
recheckAfterContentUpdate();
|
|||
|
|
if (content.valid !== prevValid || !isSameResolvedOutput(prevOutput, frag.nodes)) notifyUpdated();
|
|||
|
|
};
|
|||
|
|
trackSlotVNodeUpdatesWithRefresh(next, refreshSlotVNode, notifyBeforeUpdate);
|
|||
|
|
const prev = currentInstance;
|
|||
|
|
simpleSetCurrentInstance(null);
|
|||
|
|
internals.p(previous, next, currentParentNode, currentAnchor, parentComponent, suspense, slotNamespace, concatInteropScopeIds(frag.slotScopeIds, slotScopeIds));
|
|||
|
|
simpleSetCurrentInstance(prev);
|
|||
|
|
setRendered(next, valid);
|
|||
|
|
finishContentUpdate();
|
|||
|
|
}
|
|||
|
|
function removeRenderedContent(renderedContent, parentNode) {
|
|||
|
|
const contentDetached = !!slotResolutionState.activeFallback;
|
|||
|
|
if (isVNode(renderedContent)) internals.um(renderedContent, parentComponent, resolveUnmountSuspense(suspense), !contentDetached && !!parentNode);
|
|||
|
|
else remove(renderedContent, contentDetached ? void 0 : parentNode);
|
|||
|
|
}
|
|||
|
|
function resumeOutIn() {
|
|||
|
|
queuePostFlushCb(() => {
|
|||
|
|
const pending = pendingOutIn;
|
|||
|
|
pendingOutIn = void 0;
|
|||
|
|
if (!pending || disposed || !currentParentNode) return;
|
|||
|
|
const pendingContent = pending.content;
|
|||
|
|
if (isVNode(pendingContent)) {
|
|||
|
|
const nextVNode = prepareInteropSlotTransition(frag, pendingContent, forwarded, void 0, NOOP) || pendingContent;
|
|||
|
|
patchSlotVNode(pending.placeholder, nextVNode, pendingContent.slotScopeIds, pending.contentValid);
|
|||
|
|
} else {
|
|||
|
|
setVNode(null);
|
|||
|
|
if (pending.placeholder) removeRenderedContent(pending.placeholder, currentParentNode);
|
|||
|
|
if (pendingContent) insert(pendingContent, currentParentNode, currentAnchor, suspense);
|
|||
|
|
setRendered(pendingContent || null, pending.contentValid);
|
|||
|
|
finishContentUpdate();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
function render() {
|
|||
|
|
const prev = currentInstance;
|
|||
|
|
simpleSetCurrentInstance(frag.renderInstance);
|
|||
|
|
try {
|
|||
|
|
once ? renderContent() : renderEffect(renderContent);
|
|||
|
|
} finally {
|
|||
|
|
simpleSetCurrentInstance(prev);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function renderContent() {
|
|||
|
|
notifyBeforeUpdate();
|
|||
|
|
withRenderContext(frag.ctx, () => withSlotBoundary(contentBoundary, () => {
|
|||
|
|
const { content: slotContent, valid: slotContentValid } = resolveSlotContent();
|
|||
|
|
if (isHydrating$1) {
|
|||
|
|
hydrateContent(slotContent, slotContentValid);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (pendingOutIn) {
|
|||
|
|
pendingOutIn.content = slotContent;
|
|||
|
|
pendingOutIn.contentValid = slotContentValid;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (isVNode(slotContent)) {
|
|||
|
|
applyVNodeContent(slotContent, slotContentValid);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (slotContent) {
|
|||
|
|
applyBlockContent(slotContent, slotContentValid);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
applyEmptyContent();
|
|||
|
|
}));
|
|||
|
|
}
|
|||
|
|
function resolveSlotContent() {
|
|||
|
|
let slotContent;
|
|||
|
|
let slotContentValid = false;
|
|||
|
|
if (slotsRef.value) {
|
|||
|
|
const renderContent = () => renderSlot(slotsRef.value, isFunction(name) ? name() : name, props);
|
|||
|
|
slotContent = once ? withOnce(renderContent) : renderContent();
|
|||
|
|
if (isVNode(slotContent)) slotContentValid = slotContent.type !== Fragment || hasValidVNodeContent(slotContent);
|
|||
|
|
else if (slotContent) slotContentValid = isValidSlot(slotContent);
|
|||
|
|
}
|
|||
|
|
return {
|
|||
|
|
content: slotContent,
|
|||
|
|
valid: slotContentValid
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
function applyVNodeContent(slotContent, slotContentValid) {
|
|||
|
|
const prevRendered = rendered;
|
|||
|
|
const transition = slotResolutionState.$transition;
|
|||
|
|
const mode = transition && transition.props.mode;
|
|||
|
|
let delayedLeaveSource;
|
|||
|
|
if (slotResolutionState.activeFallback && !slotContentValid) {
|
|||
|
|
applyEmptyContent();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (slotResolutionState.activeFallback && slotContentValid && transition) {
|
|||
|
|
if (mode === "out-in") {
|
|||
|
|
const fallback = slotResolutionState.activeFallback;
|
|||
|
|
const leavingBlock = fallback && findTransitionBlock(fallback);
|
|||
|
|
pendingOutIn = {
|
|||
|
|
content: slotContent,
|
|||
|
|
placeholder: null,
|
|||
|
|
contentValid: true,
|
|||
|
|
leavingElement: leavingBlock && getTransitionElement(leavingBlock)
|
|||
|
|
};
|
|||
|
|
if (leaveSlotFallback(slotResolutionState, transition, resumeOutIn)) return;
|
|||
|
|
pendingOutIn = void 0;
|
|||
|
|
} else if (mode === "in-out") {
|
|||
|
|
const enterHooks = extend$1({}, transition);
|
|||
|
|
delete enterHooks.delayedLeave;
|
|||
|
|
leaveSlotFallback(slotResolutionState, enterHooks, NOOP);
|
|||
|
|
delayedLeaveSource = enterHooks;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
const prevIsVNode = isVNode(prevRendered);
|
|||
|
|
const prevVNode = prevIsVNode && (!slotResolutionState.activeFallback || content.valid) ? prevRendered : null;
|
|||
|
|
if (prevVNode && !slotContentValid && transition && hasSlotFallback(boundary)) {
|
|||
|
|
if (mode === "out-in") {
|
|||
|
|
const placeholder = prepareInteropSlotTransition(frag, slotContent, forwarded, void 0, NOOP) || createCommentVNode();
|
|||
|
|
if (prepareTransitionLeave(prevVNode, void 0, transition.props, transition.state, transition.instance, resumeOutIn)) {
|
|||
|
|
suspendForOutIn(prevVNode, placeholder, slotContent, false);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
} else if (mode === "in-out") {
|
|||
|
|
pendingInOutVNode = prevVNode;
|
|||
|
|
setVNode(null);
|
|||
|
|
setRendered(null);
|
|||
|
|
finishContentUpdate();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
const transitionChild = prepareInteropSlotTransition(frag, slotContent, forwarded, prevVNode || void 0, resumeOutIn, delayedLeaveSource);
|
|||
|
|
const nextVNode = transitionChild || slotContent;
|
|||
|
|
if (prevVNode && transitionChild && transition && transition.state.isLeaving) {
|
|||
|
|
suspendForOutIn(prevVNode, nextVNode, slotContent, slotContentValid);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (prevRendered && !prevIsVNode) removeRenderedContent(prevRendered, currentParentNode);
|
|||
|
|
patchSlotVNode(prevVNode, nextVNode, slotContent.slotScopeIds, slotContentValid);
|
|||
|
|
}
|
|||
|
|
function applyBlockContent(slotContent, slotContentValid) {
|
|||
|
|
setVNode(null);
|
|||
|
|
const prevRendered = rendered;
|
|||
|
|
if (prevRendered) removeRenderedContent(prevRendered, currentParentNode);
|
|||
|
|
insert(slotContent, currentParentNode, currentAnchor, suspense);
|
|||
|
|
setRendered(slotContent, slotContentValid);
|
|||
|
|
finishContentUpdate();
|
|||
|
|
}
|
|||
|
|
function applyEmptyContent() {
|
|||
|
|
if (rendered) removeRenderedContent(rendered, currentParentNode);
|
|||
|
|
setVNode(null);
|
|||
|
|
setRendered(null);
|
|||
|
|
finishContentUpdate();
|
|||
|
|
}
|
|||
|
|
function setVNode(vnode) {
|
|||
|
|
frag.vnode = vnode;
|
|||
|
|
frag.$key = vnode ? getVNodeKey(vnode) : void 0;
|
|||
|
|
}
|
|||
|
|
/** Commit rendered output, deriving the content nodes and validity. */
|
|||
|
|
function setRendered(renderedContent, knownValid) {
|
|||
|
|
rendered = renderedContent;
|
|||
|
|
if (isVNode(renderedContent)) {
|
|||
|
|
content.nodes = resolveVNodeNodes(renderedContent);
|
|||
|
|
content.valid = knownValid === void 0 ? hasValidVNodeContent(renderedContent) : knownValid;
|
|||
|
|
} else if (renderedContent) {
|
|||
|
|
content.nodes = renderedContent;
|
|||
|
|
content.valid = knownValid === void 0 ? isValidSlot(renderedContent) : knownValid;
|
|||
|
|
} else {
|
|||
|
|
content.nodes = EMPTY_BLOCK;
|
|||
|
|
content.valid = false;
|
|||
|
|
}
|
|||
|
|
content.resolved = true;
|
|||
|
|
}
|
|||
|
|
function suspendForOutIn(prevVNode, placeholder, slotContent, contentValid) {
|
|||
|
|
pendingOutIn = {
|
|||
|
|
content: slotContent,
|
|||
|
|
placeholder,
|
|||
|
|
contentValid,
|
|||
|
|
leavingElement: getInteropTransitionElement(prevVNode)
|
|||
|
|
};
|
|||
|
|
setVNode(placeholder);
|
|||
|
|
rendered = placeholder;
|
|||
|
|
internals.p(prevVNode, placeholder, currentParentNode, currentAnchor, parentComponent, suspense, slotNamespace, null);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* One-shot hydration claimer: adopts the SSR-rendered slot content instead
|
|||
|
|
* of mounting. Runs only on the first render pass under an active hydration
|
|||
|
|
* cursor; later passes take the CSR paths above.
|
|||
|
|
*/
|
|||
|
|
function hydrateContent(slotContent, slotContentValid) {
|
|||
|
|
if (!isHydrating$1) return;
|
|||
|
|
const hydratedContent = slotContent && (slotContentValid || !hasSlotFallback(boundary)) ? slotContent : void 0;
|
|||
|
|
if (isVNode(hydratedContent)) {
|
|||
|
|
const transitionChild = prepareInteropSlotTransition(frag, hydratedContent, forwarded, void 0, NOOP);
|
|||
|
|
const hydrationVNode = transitionChild || hydratedContent;
|
|||
|
|
setVNode(hydrationVNode);
|
|||
|
|
const refreshSlotVNode = () => {
|
|||
|
|
frag.nodes = resolveVNodeNodes(hydrationVNode);
|
|||
|
|
notifyUpdated();
|
|||
|
|
};
|
|||
|
|
trackSlotVNodeUpdatesWithRefresh(hydrationVNode, refreshSlotVNode, notifyBeforeUpdate);
|
|||
|
|
const hydrationParent = /* @__PURE__ */ parentNode(currentHydrationNode);
|
|||
|
|
const close = transitionChild && locateFragmentEnd(currentHydrationNode);
|
|||
|
|
if (close) setCurrentHydrationNode(currentHydrationNode.nextSibling);
|
|||
|
|
hydrateVNode(hydrationVNode, parentComponent, concatInteropScopeIds(frag.slotScopeIds, hydrationVNode === hydratedContent ? null : hydratedContent.slotScopeIds), suspense);
|
|||
|
|
if (close) {
|
|||
|
|
frag.anchor = claimAnchor(close);
|
|||
|
|
advanceHydrationNode(close);
|
|||
|
|
}
|
|||
|
|
currentParentNode = hydrationParent;
|
|||
|
|
currentAnchor = internals.n(hydrationVNode);
|
|||
|
|
setRendered(hydrationVNode, slotContentValid);
|
|||
|
|
} else if (hydratedContent) {
|
|||
|
|
setVNode(null);
|
|||
|
|
setRendered(hydratedContent, slotContentValid);
|
|||
|
|
} else {
|
|||
|
|
setVNode(null);
|
|||
|
|
setRendered(null);
|
|||
|
|
}
|
|||
|
|
finishContentUpdate(true);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function needsHostParentForRemove(block) {
|
|||
|
|
if (isVaporComponent(block)) return isKeepAlive(block) || needsHostParentForRemove(block.block);
|
|||
|
|
if (isArray(block)) return block.some(needsHostParentForRemove);
|
|||
|
|
if (isFragment(block)) return needsHostParentForRemove(block.nodes);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
const vaporInteropPlugin = (app) => {
|
|||
|
|
enableSuspense();
|
|||
|
|
setInteropEnabled();
|
|||
|
|
setPublishInteropScopeIds(publishVaporScopeIds);
|
|||
|
|
app._context.vapor = vaporInteropImpl;
|
|||
|
|
const internals = ensureRenderer().internals;
|
|||
|
|
app._context.vdom = {
|
|||
|
|
mount: createVDOMComponent.bind(null, internals),
|
|||
|
|
slot: renderVDOMSlot.bind(null, internals),
|
|||
|
|
mountVNode: mountDynamicVNode.bind(null, internals)
|
|||
|
|
};
|
|||
|
|
const mount = app.mount;
|
|||
|
|
app.mount = ((...args) => {
|
|||
|
|
optimizePropertyLookup();
|
|||
|
|
return mount(...args);
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
function hydrateVNode(vnode, parentComponent, slotScopeIds = null, parentSuspense = null) {
|
|||
|
|
const node = currentHydrationNode;
|
|||
|
|
if (!vdomHydrateNode) vdomHydrateNode = ensureHydrationRenderer().hydrateNode;
|
|||
|
|
const prev = currentInstance;
|
|||
|
|
simpleSetCurrentInstance(null);
|
|||
|
|
const nextNode = vdomHydrateNode(node, vnode, parentComponent, parentSuspense, slotScopeIds, false);
|
|||
|
|
simpleSetCurrentInstance(prev);
|
|||
|
|
if (nextNode) setCurrentHydrationNode(nextNode);
|
|||
|
|
else advanceHydrationNode(/* @__PURE__ */ parentNode(node));
|
|||
|
|
}
|
|||
|
|
function createFallback(state, depth, parentComponent) {
|
|||
|
|
const internals = ensureRenderer().internals;
|
|||
|
|
return () => {
|
|||
|
|
const frag = createVNodeChildrenFragment(internals, () => {
|
|||
|
|
const outlet = state.outletsRef.value[depth];
|
|||
|
|
const children = outlet && invokeSlotFallback(outlet.fallback, outlet.owner);
|
|||
|
|
return children == null ? EMPTY_VNODES : normalizeInteropSlotValue(children);
|
|||
|
|
}, parentComponent);
|
|||
|
|
if (isHydrating$1 && frag.hydrate) frag.hydrate();
|
|||
|
|
return frag;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
function mountSlotWithoutHydration(vnode, open, close, parentComponent, parentSuspense, slotScopeIds, fallbackRange) {
|
|||
|
|
const container = /* @__PURE__ */ parentNode(close);
|
|||
|
|
const mount = () => {
|
|||
|
|
const block = vnode.vb = renderVaporSlot(vnode, parentComponent, parentSuspense, slotScopeIds, fallbackRange);
|
|||
|
|
let anchor = close;
|
|||
|
|
if (!open) {
|
|||
|
|
anchor = isFragment(block) && block.anchor || /* @__PURE__ */ createTextNode();
|
|||
|
|
insert(anchor, container, close);
|
|||
|
|
}
|
|||
|
|
vnode.el = open || anchor;
|
|||
|
|
vnode.anchor = anchor;
|
|||
|
|
insert(block, container, anchor, parentSuspense);
|
|||
|
|
};
|
|||
|
|
if (fallbackRange) hydrateSlotFallbackRange(fallbackRange, mount);
|
|||
|
|
else runWithoutHydration(mount);
|
|||
|
|
}
|
|||
|
|
function hydrateOutletFallback(children, node, close, depth, parentComponent, parentSuspense, slotScopeIds) {
|
|||
|
|
const container = /* @__PURE__ */ parentNode(node);
|
|||
|
|
const internals = ensureRenderer().internals;
|
|||
|
|
let next = node;
|
|||
|
|
for (let i = 0; i < children.length; i++) {
|
|||
|
|
const child = children[i];
|
|||
|
|
if (child.vs) {
|
|||
|
|
const outlets = child.vs.outlets;
|
|||
|
|
mountSlotWithoutHydration(child, null, close, parentComponent, parentSuspense, slotScopeIds, {
|
|||
|
|
depth: outlets && outlets[0].innerIds == null ? depth + 1 : depth,
|
|||
|
|
first: node,
|
|||
|
|
close
|
|||
|
|
});
|
|||
|
|
next = close;
|
|||
|
|
} else if (child.type === Fragment && hasVaporSlot(child)) {
|
|||
|
|
insert(child.el = /* @__PURE__ */ createTextNode(), container, next);
|
|||
|
|
next = hydrateOutletFallback(child.children, node, close, child.vo ? depth + 1 : depth, parentComponent, parentSuspense, child.slotScopeIds ? concatInteropScopeIds(slotScopeIds, child.slotScopeIds) : slotScopeIds);
|
|||
|
|
insert(child.anchor = /* @__PURE__ */ createTextNode(), container, next);
|
|||
|
|
} else runWithoutHydration(() => internals.p(null, child, container, next, parentComponent, parentSuspense, getContainerType(container), slotScopeIds));
|
|||
|
|
}
|
|||
|
|
return next;
|
|||
|
|
}
|
|||
|
|
function hasVaporSlot(fragment) {
|
|||
|
|
return fragment.children.some((child) => child.vs || child.type === Fragment && hasVaporSlot(child));
|
|||
|
|
}
|
|||
|
|
function attachSlotOutlet(content, fallback, owner) {
|
|||
|
|
let slot = findLoneSlot(content, 0) ? loneSlot : null;
|
|||
|
|
if (slot) {
|
|||
|
|
if (slot.cacheIndex != null) slot = loneSlotIn[loneSlotAt] = cloneVNode(slot);
|
|||
|
|
const vs = slot.vs;
|
|||
|
|
const outlet = {
|
|||
|
|
fallback,
|
|||
|
|
owner,
|
|||
|
|
innerIds: loneSlotInnerIds
|
|||
|
|
};
|
|||
|
|
vs.outlets = vs.outlets ? vs.outlets.concat(outlet) : [outlet];
|
|||
|
|
}
|
|||
|
|
loneSlot = loneSlotIn = null;
|
|||
|
|
return !!slot;
|
|||
|
|
}
|
|||
|
|
let loneSlot = null;
|
|||
|
|
let loneSlotIn = null;
|
|||
|
|
let loneSlotAt = 0;
|
|||
|
|
let loneSlotInnerIds = 0;
|
|||
|
|
function findLoneSlot(vnodes, pathIds) {
|
|||
|
|
for (let i = 0; i < vnodes.length; i++) {
|
|||
|
|
const child = vnodes[i];
|
|||
|
|
if (!isVNode(child)) return false;
|
|||
|
|
if (child.vs) {
|
|||
|
|
if (loneSlot) return false;
|
|||
|
|
loneSlot = child;
|
|||
|
|
loneSlotIn = vnodes;
|
|||
|
|
loneSlotAt = i;
|
|||
|
|
loneSlotInnerIds = pathIds;
|
|||
|
|
} else if (child.type === Fragment) {
|
|||
|
|
if (child.patchFlag > 0 && child.patchFlag & 384 || !findLoneSlot(child.children, pathIds + (child.slotScopeIds ? child.slotScopeIds.length : 0))) return false;
|
|||
|
|
} else if (child.type !== Comment$1) return false;
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
function resolveInteropVaporSlotState(vnode) {
|
|||
|
|
const slot = vnode.vs;
|
|||
|
|
let state = slot.state;
|
|||
|
|
if (!state) {
|
|||
|
|
const outlets = slot.outlets || EMPTY_ARR;
|
|||
|
|
state = {
|
|||
|
|
outlets,
|
|||
|
|
outletsRef: shallowRef(outlets)
|
|||
|
|
};
|
|||
|
|
slot.state = state;
|
|||
|
|
}
|
|||
|
|
return state;
|
|||
|
|
}
|
|||
|
|
function syncInteropVaporSlotState(n1, n2) {
|
|||
|
|
const prevState = n1.vs.state;
|
|||
|
|
if (!prevState) return;
|
|||
|
|
n2.vs.state = prevState;
|
|||
|
|
prevState.outletsRef.value = prevState.outlets = n2.vs.outlets || EMPTY_ARR;
|
|||
|
|
}
|
|||
|
|
function trackInteropFallbackChanges(scope, state, onChange) {
|
|||
|
|
if (!scope) return;
|
|||
|
|
let trackedDepth = state.outlets.length;
|
|||
|
|
scope.run(() => {
|
|||
|
|
renderEffect(() => {
|
|||
|
|
const nextDepth = state.outletsRef.value.length;
|
|||
|
|
if (nextDepth !== trackedDepth) {
|
|||
|
|
trackedDepth = nextDepth;
|
|||
|
|
onChange();
|
|||
|
|
}
|
|||
|
|
}, true);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
function renderVaporSlot(vnode, parentComponent, parentSuspense, contextSlotScopeIds, fallbackRange) {
|
|||
|
|
const prev = currentInstance;
|
|||
|
|
const prevCtx = currentRenderContext;
|
|||
|
|
simpleSetCurrentInstance(parentComponent);
|
|||
|
|
if (isSuspenseEnabled && parentSuspense) setRenderContext(deriveSuspense(prevCtx, parentSuspense));
|
|||
|
|
try {
|
|||
|
|
if (!vnode.vs || !vnode.vs.slot) return EMPTY_BLOCK;
|
|||
|
|
const slotState = resolveInteropVaporSlotState(vnode);
|
|||
|
|
const frag = createInteropFragment(EMPTY_BLOCK, null, 128);
|
|||
|
|
const inherited = getInheritedScopeIds(vnode, parentComponent, false);
|
|||
|
|
frag.ctx = deriveSlotScopeIds(frag.ctx, getInteropVaporSlotScopeIds(contextSlotScopeIds, vnode.slotScopeIds, inherited));
|
|||
|
|
const content = new InteropContentState();
|
|||
|
|
frag.isBlockValid = (componentAsValid) => content.resolved ? isValidBlock(frag.nodes, componentAsValid) : true;
|
|||
|
|
const slotBoundary = frag.slotBoundary;
|
|||
|
|
let isResolvingContent = false;
|
|||
|
|
let currentParentNode = null;
|
|||
|
|
let currentAnchor = null;
|
|||
|
|
let disposed = false;
|
|||
|
|
let slotResolutionState;
|
|||
|
|
let ownedSlotFragment;
|
|||
|
|
let ownedSlotFragmentDirtyQueued = false;
|
|||
|
|
let ownedSlotFragmentDirtyForce = false;
|
|||
|
|
const onContentInvalid = [() => {
|
|||
|
|
if (currentParentNode) removeAttachedNodes(content.nodes, currentParentNode);
|
|||
|
|
}];
|
|||
|
|
const markInteropSlotResolutionDirty = (force) => {
|
|||
|
|
const target = ownedSlotFragment;
|
|||
|
|
if (!target) {
|
|||
|
|
markSlotResolutionDirty(slotResolutionState, force);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
ownedSlotFragmentDirtyForce = ownedSlotFragmentDirtyForce || !!force;
|
|||
|
|
if (ownedSlotFragmentDirtyQueued) return;
|
|||
|
|
ownedSlotFragmentDirtyQueued = true;
|
|||
|
|
queuePostFlushCb(() => {
|
|||
|
|
ownedSlotFragmentDirtyQueued = false;
|
|||
|
|
const force = ownedSlotFragmentDirtyForce;
|
|||
|
|
ownedSlotFragmentDirtyForce = false;
|
|||
|
|
markSlotResolutionDirty(target, force);
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
const outletBoundaries = [];
|
|||
|
|
const createOutletBoundary = (depth, onContentInvalid) => {
|
|||
|
|
let fallback;
|
|||
|
|
return createSlotBoundary(frag, () => getOutletBoundary(depth + 1), () => slotState.outlets[depth] ? fallback || (fallback = createFallback(slotState, depth, parentComponent)) : void 0, markInteropSlotResolutionDirty, onContentInvalid, () => {
|
|||
|
|
const outlet = slotState.outlets[depth];
|
|||
|
|
return outlet && outlet.innerIds != null ? getEnclosingOutletScopeIds(contextSlotScopeIds, outlet.innerIds, inherited) : frag.slotScopeIds;
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
const getOutletBoundary = (depth) => depth < slotState.outlets.length ? outletBoundaries[depth] || (outletBoundaries[depth] = createOutletBoundary(depth)) : slotBoundary;
|
|||
|
|
const rootBoundary = outletBoundaries[0] = createOutletBoundary(0, onContentInvalid);
|
|||
|
|
slotResolutionState = createSlotResolutionState(rootBoundary, {
|
|||
|
|
getContent: () => content.nodes,
|
|||
|
|
getParentNode: () => currentParentNode,
|
|||
|
|
getAnchor: () => currentAnchor,
|
|||
|
|
isBusy: () => isResolvingContent,
|
|||
|
|
isDisposed: () => disposed,
|
|||
|
|
isContentValid: () => isValidSlot(content.nodes),
|
|||
|
|
syncNodes: () => {
|
|||
|
|
frag.nodes = resolveExposedSlotNodes(slotResolutionState);
|
|||
|
|
content.resolved = true;
|
|||
|
|
},
|
|||
|
|
notifyExposedValidityChange: () => {
|
|||
|
|
if (slotBoundary) slotBoundary.markDirty();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
const takePendingRecheck = () => {
|
|||
|
|
const force = slotResolutionState.pendingRecheckForce;
|
|||
|
|
slotResolutionState.pendingRecheck = false;
|
|||
|
|
slotResolutionState.pendingRecheckForce = false;
|
|||
|
|
return force;
|
|||
|
|
};
|
|||
|
|
const dispose = (parentNode) => {
|
|||
|
|
if (disposed) return;
|
|||
|
|
if (parentNode) currentParentNode = parentNode;
|
|||
|
|
disposed = true;
|
|||
|
|
disposeSlotResolution(slotResolutionState, parentNode);
|
|||
|
|
currentParentNode = null;
|
|||
|
|
currentAnchor = null;
|
|||
|
|
};
|
|||
|
|
try {
|
|||
|
|
const hasInteropFallback = slotState.outlets.length > 0;
|
|||
|
|
slotResolutionState.pendingRecheck = false;
|
|||
|
|
slotResolutionState.pendingRecheckForce = false;
|
|||
|
|
const finalizeResolvedContent = (resolvedContent) => {
|
|||
|
|
if (hasInteropFallback && isSlotResolver(resolvedContent)) return resolvedContent;
|
|||
|
|
content.nodes = resolvedContent || EMPTY_BLOCK;
|
|||
|
|
recheckSlotResolution(slotResolutionState, takePendingRecheck());
|
|||
|
|
return resolvedContent;
|
|||
|
|
};
|
|||
|
|
let resolvedContent;
|
|||
|
|
const renderContent = () => resolvedContent = finalizeResolvedContent(withRenderContext(frag.ctx, () => withSlotBoundary(rootBoundary, () => invokeVaporSlot(vnode))));
|
|||
|
|
isResolvingContent = true;
|
|||
|
|
try {
|
|||
|
|
if (fallbackRange) (fallbackRange.boundary = getOutletBoundary(fallbackRange.depth)).adoptFallback = fallbackRange.adopt;
|
|||
|
|
if (isHydrating$1) withHydratingSlotBoundary(renderContent);
|
|||
|
|
else renderContent();
|
|||
|
|
} finally {
|
|||
|
|
isResolvingContent = false;
|
|||
|
|
}
|
|||
|
|
if (hasInteropFallback && isSlotResolver(resolvedContent)) {
|
|||
|
|
ownedSlotFragment = resolvedContent;
|
|||
|
|
trackInteropFallbackChanges(vnode.vs.scope, slotState, () => markInteropSlotResolutionDirty());
|
|||
|
|
dispose();
|
|||
|
|
return resolvedContent;
|
|||
|
|
}
|
|||
|
|
slotResolutionState.pendingRecheck = false;
|
|||
|
|
slotResolutionState.pendingRecheckForce = false;
|
|||
|
|
frag.insert = (parentNode, anchor, parentSuspense) => {
|
|||
|
|
currentParentNode = parentNode;
|
|||
|
|
currentAnchor = anchor;
|
|||
|
|
if (slotResolutionState.activeFallback) insertActiveSlotFallback(slotResolutionState);
|
|||
|
|
else insert(frag.nodes, parentNode, anchor, parentSuspense);
|
|||
|
|
};
|
|||
|
|
frag.move = (parentNode, anchor, moveType, parentComponent, parentSuspense) => {
|
|||
|
|
currentParentNode = parentNode;
|
|||
|
|
currentAnchor = anchor;
|
|||
|
|
if (slotResolutionState.activeFallback) insertActiveSlotFallback(slotResolutionState, moveType);
|
|||
|
|
else move(frag.nodes, parentNode, anchor, moveType, parentComponent, parentSuspense);
|
|||
|
|
};
|
|||
|
|
frag.remove = (parentNode) => {
|
|||
|
|
if (!slotResolutionState.activeFallback) remove(frag.nodes, parentNode);
|
|||
|
|
dispose(parentNode);
|
|||
|
|
};
|
|||
|
|
trackInteropFallbackChanges(vnode.vs.scope, slotState, () => {
|
|||
|
|
recheckSlotResolution(slotResolutionState, true);
|
|||
|
|
});
|
|||
|
|
if (isHydrating$1 && currentHydrationNode) {
|
|||
|
|
currentAnchor = currentHydrationNode;
|
|||
|
|
currentParentNode = currentAnchor.parentNode;
|
|||
|
|
}
|
|||
|
|
return frag;
|
|||
|
|
} catch (e) {
|
|||
|
|
dispose(currentParentNode || void 0);
|
|||
|
|
stopVaporSlotScope(vnode);
|
|||
|
|
throw e;
|
|||
|
|
}
|
|||
|
|
} finally {
|
|||
|
|
setRenderContext(prevCtx);
|
|||
|
|
simpleSetCurrentInstance(prev);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function stopVaporSlotScope(vnode) {
|
|||
|
|
if (vnode.vs && vnode.vs.scope) {
|
|||
|
|
vnode.vs.scope.stop();
|
|||
|
|
vnode.vs.scope = void 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Slot functions can create renderEffects while evaluating their block.
|
|||
|
|
* Those effects live in this dedicated scope so slot re-mount/unmount can
|
|||
|
|
* dispose them immediately instead of waiting for the parent component.
|
|||
|
|
*/
|
|||
|
|
function invokeVaporSlot(vnode) {
|
|||
|
|
const propsRef = vnode.vs.ref = shallowRef(vnode.props);
|
|||
|
|
const scope = effectScope();
|
|||
|
|
vnode.vs.scope = scope;
|
|||
|
|
try {
|
|||
|
|
const run = () => vnode.vs.slot(new Proxy(propsRef, vaporSlotPropsProxyHandler));
|
|||
|
|
return inOnce ? withOnce(() => scope.run(run), false) : scope.run(run);
|
|||
|
|
} catch (e) {
|
|||
|
|
vnode.vs.scope = void 0;
|
|||
|
|
scope.stop();
|
|||
|
|
throw e;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function resolveInteropRootEl(instance) {
|
|||
|
|
return getRootElement(instance, { onDynamicFragment: (frag) => registerInteropRootSync(instance, frag) });
|
|||
|
|
}
|
|||
|
|
function syncVNodeEl(vnode, instance) {
|
|||
|
|
vnode.el = resolveInteropRootEl(instance) || vnode.anchor;
|
|||
|
|
}
|
|||
|
|
function syncInteropRoot(instance) {
|
|||
|
|
const state = vnodeHookStateMap.get(instance);
|
|||
|
|
if (!state) return;
|
|||
|
|
syncVNodeEl(state.vnode, instance);
|
|||
|
|
}
|
|||
|
|
function invokeInteropDirsHook(instance, el, vnode, name, prevVNode = null) {
|
|||
|
|
if (!vnode.dirs) return;
|
|||
|
|
invokeDirectiveHook(vnode.el === el ? vnode : extend$1({}, vnode, { el }), prevVNode, instance.parent, name);
|
|||
|
|
}
|
|||
|
|
function queueInteropDirsJob(instance, job, suspense = instance.suspense) {
|
|||
|
|
queuePostRenderEffect(job, void 0, suspense);
|
|||
|
|
}
|
|||
|
|
function warnNonElementRootDirs() {
|
|||
|
|
warn("Runtime directive used on component with non-element root node. The directives will not function as intended.");
|
|||
|
|
}
|
|||
|
|
function getInteropDirsOwner(state, comp, vnode) {
|
|||
|
|
const owners = state.dirsOwners || (state.dirsOwners = /* @__PURE__ */ new WeakMap());
|
|||
|
|
let owner = owners.get(comp);
|
|||
|
|
if (owner) owner.vnode = vnode;
|
|||
|
|
else owners.set(comp, owner = {
|
|||
|
|
comp,
|
|||
|
|
vnode,
|
|||
|
|
el: null,
|
|||
|
|
carried: vnode,
|
|||
|
|
updating: null,
|
|||
|
|
patching: null,
|
|||
|
|
pending: null
|
|||
|
|
});
|
|||
|
|
return owner;
|
|||
|
|
}
|
|||
|
|
function resolveInteropDirsRoot(instance, state, block, inherit) {
|
|||
|
|
let owner = inherit;
|
|||
|
|
const el = getRootElement(block, {
|
|||
|
|
excludeSlotOutlets: true,
|
|||
|
|
onDynamicFragment: (frag) => registerInteropDirsFragment(instance, state, frag, owner),
|
|||
|
|
onComponent: (comp) => {
|
|||
|
|
registerInteropDirsComponent(instance, state, comp);
|
|||
|
|
owner = getInteropDirsOwner(state, comp, inherit.vnode);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
return [owner, el];
|
|||
|
|
}
|
|||
|
|
function isPendingInteropSetup(comp) {
|
|||
|
|
return isSuspenseEnabled && !!comp.asyncDep && !comp.asyncResolved;
|
|||
|
|
}
|
|||
|
|
function registerAfterInteropSetup(comp, pending, register) {
|
|||
|
|
if (pending) (comp.bm || (comp.bm = [])).push(register);
|
|||
|
|
else register();
|
|||
|
|
}
|
|||
|
|
function isPendingInteropDirsRoot(comp) {
|
|||
|
|
if (isPendingInteropSetup(comp)) return true;
|
|||
|
|
const block = comp.block;
|
|||
|
|
return isAsyncComponentEnabled && isAsyncWrapper(comp) && isFragment(block) && block.nodes === EMPTY_BLOCK;
|
|||
|
|
}
|
|||
|
|
function innerInteropDirsOwner(state, comp, visit) {
|
|||
|
|
const owners = state.dirsOwners;
|
|||
|
|
let owner;
|
|||
|
|
if (!owners) return;
|
|||
|
|
getRootElement(comp, {
|
|||
|
|
excludeSlotOutlets: true,
|
|||
|
|
onComponent: (comp) => {
|
|||
|
|
const next = owners.get(comp);
|
|||
|
|
if (next) {
|
|||
|
|
owner = next;
|
|||
|
|
if (visit) visit(next);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
return owner;
|
|||
|
|
}
|
|||
|
|
function settleInteropDirsReceived(instance, state) {
|
|||
|
|
const received = state.dirsReceived;
|
|||
|
|
if (!received) return;
|
|||
|
|
state.dirsReceived = null;
|
|||
|
|
const active = /* @__PURE__ */ new Set();
|
|||
|
|
innerInteropDirsOwner(state, instance, (owner) => active.add(owner));
|
|||
|
|
received.forEach(([owner, vnode]) => {
|
|||
|
|
if (!active.has(owner)) owner.vnode = vnode;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
function mountInteropDirsRoot(instance, owner, el) {
|
|||
|
|
const vnode = owner.carried = owner.vnode;
|
|||
|
|
owner.el = el;
|
|||
|
|
invokeInteropDirsHook(instance, el, vnode, "created");
|
|||
|
|
invokeInteropDirsHook(instance, el, vnode, "beforeMount");
|
|||
|
|
queueInteropDirsJob(instance, () => invokeInteropDirsHook(instance, el, vnode, "mounted"));
|
|||
|
|
}
|
|||
|
|
function unmountInteropDirs(instance, state, comp) {
|
|||
|
|
const owners = state.dirsOwners;
|
|||
|
|
const owner = owners && owners.get(comp);
|
|||
|
|
if (!owner) return;
|
|||
|
|
owners.delete(comp);
|
|||
|
|
if (owner.el) unmountInteropDirsRoot(instance, owner, resolveUnmountSuspense(instance.suspense));
|
|||
|
|
}
|
|||
|
|
function unmountInteropDirsRoot(instance, owner, suspense) {
|
|||
|
|
const el = owner.el;
|
|||
|
|
const vnode = owner.carried;
|
|||
|
|
owner.el = null;
|
|||
|
|
owner.updating = owner.pending = null;
|
|||
|
|
invokeInteropDirsHook(instance, el, vnode, "beforeUnmount");
|
|||
|
|
queueInteropDirsJob(instance, () => invokeInteropDirsHook(instance, el, vnode, "unmounted"), suspense);
|
|||
|
|
}
|
|||
|
|
function updateInteropDirs(instance, state, vnode, prevVNode) {
|
|||
|
|
if (!state.dirsOwners) return;
|
|||
|
|
settleInteropDirsReceived(instance, state);
|
|||
|
|
const owner = innerInteropDirsOwner(state, instance, (owner) => {
|
|||
|
|
if (owner.comp !== instance) (state.dirsReceived || (state.dirsReceived = [])).push([owner, owner.vnode]);
|
|||
|
|
owner.vnode = vnode;
|
|||
|
|
});
|
|||
|
|
const el = owner && owner.el;
|
|||
|
|
if (el) invokeInteropDirsHook(instance, el, vnode, "beforeUpdate", prevVNode);
|
|||
|
|
queueInteropDirsJob(instance, () => {
|
|||
|
|
settleInteropDirsReceived(instance, state);
|
|||
|
|
if (!el || owner.el !== el || innerInteropDirsOwner(state, instance) !== owner) return;
|
|||
|
|
owner.carried = vnode;
|
|||
|
|
invokeInteropDirsHook(instance, el, vnode, "updated", prevVNode);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
function isInteropDirsUpdating(state, owner) {
|
|||
|
|
return !!owner.updating && innerInteropDirsOwner(state, owner.updating) === owner;
|
|||
|
|
}
|
|||
|
|
function beforeInteropDirsSelfUpdate(instance, state, source) {
|
|||
|
|
const owners = state.dirsOwners;
|
|||
|
|
const self = owners && owners.get(source);
|
|||
|
|
if (!self) return;
|
|||
|
|
if (state.pendingVNodeUpdate && (source === instance || isOnInteropRootChain(instance, source))) return;
|
|||
|
|
const owner = self.el ? self : innerInteropDirsOwner(state, source);
|
|||
|
|
if (!owner || !owner.el || isInteropDirsUpdating(state, owner)) return;
|
|||
|
|
owner.updating = source;
|
|||
|
|
self.patching = owner;
|
|||
|
|
invokeInteropDirsHook(instance, owner.el, owner.vnode, "beforeUpdate", owner.pending || owner.carried);
|
|||
|
|
}
|
|||
|
|
function afterInteropDirsSelfUpdate(instance, state, source) {
|
|||
|
|
const owners = state.dirsOwners;
|
|||
|
|
const self = owners && owners.get(source);
|
|||
|
|
const owner = self && self.patching;
|
|||
|
|
if (!owner) return;
|
|||
|
|
self.patching = null;
|
|||
|
|
if (owner.updating !== source) return;
|
|||
|
|
owner.updating = null;
|
|||
|
|
if (owner.el && innerInteropDirsOwner(state, source) === owner) {
|
|||
|
|
const prevVNode = owner.pending || owner.carried;
|
|||
|
|
owner.pending = null;
|
|||
|
|
owner.carried = owner.vnode;
|
|||
|
|
invokeInteropDirsHook(instance, owner.el, owner.vnode, "updated", prevVNode);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function invokeInteropVNodeHook(instance, hook, vnode, prevVNode = null) {
|
|||
|
|
if (hook) invokeVNodeHook(hook, instance.parent, vnode, prevVNode);
|
|||
|
|
}
|
|||
|
|
function queueInteropVNodeHook(instance, hook, vnode, suspense) {
|
|||
|
|
if (hook) queuePostRenderEffect(() => invokeVNodeHook(hook, instance.parent, vnode), void 0, suspense);
|
|||
|
|
}
|
|||
|
|
function invokeInteropVNodeBeforeUpdate(instance, vnode, prevVNode) {
|
|||
|
|
invokeInteropVNodeHook(instance, vnode.props && vnode.props.onVnodeBeforeUpdate, vnode, prevVNode);
|
|||
|
|
if (vnode.ibu) vnode.ibu();
|
|||
|
|
}
|
|||
|
|
function invokeInteropVNodeUpdated(instance, vnode, prevVNode) {
|
|||
|
|
invokeInteropVNodeHook(instance, vnode.props && vnode.props.onVnodeUpdated, vnode, prevVNode);
|
|||
|
|
if (vnode.iu) vnode.iu();
|
|||
|
|
}
|
|||
|
|
function updateInteropVNode(instance, state, vnode, prevVNode) {
|
|||
|
|
state.pendingVNodeUpdate = vnode;
|
|||
|
|
const rawProps = instance.rawProps = interopRawProps(vnode);
|
|||
|
|
const prevSub = setActiveSub();
|
|||
|
|
startBatch();
|
|||
|
|
try {
|
|||
|
|
deliverInputs(instance, rawProps);
|
|||
|
|
instance.rawSlotsRef.value = normalizeInteropSlots(vnode.children);
|
|||
|
|
} finally {
|
|||
|
|
try {
|
|||
|
|
endBatch();
|
|||
|
|
} finally {
|
|||
|
|
setActiveSub(prevSub);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
invokeInteropVNodeBeforeUpdate(instance, vnode, prevVNode);
|
|||
|
|
updateInteropDirs(instance, state, vnode, prevVNode);
|
|||
|
|
queuePostFlushCb(() => {
|
|||
|
|
syncVNodeEl(vnode, instance);
|
|||
|
|
if (state.pendingVNodeUpdate === vnode && !instance.isUpdating) state.pendingVNodeUpdate = null;
|
|||
|
|
});
|
|||
|
|
if (vnode.props && vnode.props.onVnodeUpdated || vnode.iu) queuePostRenderEffect(() => invokeInteropVNodeUpdated(instance, vnode, prevVNode), void 0, instance.suspense);
|
|||
|
|
}
|
|||
|
|
const vnodeHookStateMap = /* @__PURE__ */ new WeakMap();
|
|||
|
|
function ensureVNodeHookState(instance, vnode) {
|
|||
|
|
instance.interopVNode = vnode;
|
|||
|
|
let state = vnodeHookStateMap.get(instance);
|
|||
|
|
if (!state) {
|
|||
|
|
state = {
|
|||
|
|
vnode,
|
|||
|
|
pendingVNodeUpdate: null,
|
|||
|
|
dirsOwners: null,
|
|||
|
|
dirsReceived: null
|
|||
|
|
};
|
|||
|
|
vnodeHookStateMap.set(instance, state);
|
|||
|
|
(instance.bu || (instance.bu = [])).push(() => {
|
|||
|
|
if (state.pendingVNodeUpdate) return;
|
|||
|
|
invokeInteropVNodeBeforeUpdate(instance, state.vnode, state.vnode);
|
|||
|
|
beforeInteropDirsSelfUpdate(instance, state, instance);
|
|||
|
|
});
|
|||
|
|
(instance.u || (instance.u = [])).unshift(() => {
|
|||
|
|
syncInteropRoot(instance);
|
|||
|
|
afterInteropDirsSelfUpdate(instance, state, instance);
|
|||
|
|
});
|
|||
|
|
instance.u.push(() => {
|
|||
|
|
if (state.pendingVNodeUpdate) {
|
|||
|
|
state.pendingVNodeUpdate = null;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
invokeInteropVNodeUpdated(instance, state.vnode, state.vnode);
|
|||
|
|
});
|
|||
|
|
} else state.vnode = vnode;
|
|||
|
|
return state;
|
|||
|
|
}
|
|||
|
|
function createVNodeChildrenFragment(internals, render, parentComponent) {
|
|||
|
|
let suspense = currentRenderContext.suspense || parentComponent && parentComponent.suspense;
|
|||
|
|
const frag = createInteropFragment();
|
|||
|
|
const content = new InteropContentState();
|
|||
|
|
frag.isBlockValid = () => content.resolved ? content.valid : true;
|
|||
|
|
let currentVNode = null;
|
|||
|
|
let currentChildren = EMPTY_VNODES;
|
|||
|
|
let currentParentNode = null;
|
|||
|
|
let childrenNamespace;
|
|||
|
|
let currentAnchor = null;
|
|||
|
|
let isMounted = false;
|
|||
|
|
let isRenderEffectStarted = false;
|
|||
|
|
const scope = effectScope();
|
|||
|
|
const cleanupInvalidContent = () => {
|
|||
|
|
if (currentParentNode) removeAttachedNodes(frag.nodes, currentParentNode);
|
|||
|
|
};
|
|||
|
|
if (frag.slotBoundary) registerContentInvalid(frag.slotBoundary, cleanupInvalidContent, frag);
|
|||
|
|
const syncResolvedNodes = (children = currentChildren) => {
|
|||
|
|
const prevValid = content.resolved ? content.valid : true;
|
|||
|
|
content.valid = !!ensureValidVNode(children);
|
|||
|
|
if (children.length === 0) frag.nodes = EMPTY_BLOCK;
|
|||
|
|
else if (children.length === 1) frag.nodes = resolveVNodeNodes(children[0]);
|
|||
|
|
else frag.nodes = children.map(resolveVNodeNodes);
|
|||
|
|
content.resolved = true;
|
|||
|
|
return prevValid !== content.valid;
|
|||
|
|
};
|
|||
|
|
const syncResolvedNodesAndCleanup = (children = currentChildren) => {
|
|||
|
|
const validityChanged = syncResolvedNodes(children);
|
|||
|
|
if (!content.valid && frag.slotBoundary) {
|
|||
|
|
cleanupInvalidContent();
|
|||
|
|
currentVNode = null;
|
|||
|
|
currentChildren = EMPTY_VNODES;
|
|||
|
|
}
|
|||
|
|
return validityChanged;
|
|||
|
|
};
|
|||
|
|
const notifyUpdated = (validityChanged = false) => {
|
|||
|
|
if (validityChanged && frag.slotBoundary) frag.slotBoundary.markDirty();
|
|||
|
|
if (isMounted && frag.u) frag.u.forEach((hook) => hook(frag.nodes));
|
|||
|
|
};
|
|||
|
|
const notifyBeforeUpdate = () => {
|
|||
|
|
if (isMounted && frag.bu) frag.bu.forEach((hook) => hook());
|
|||
|
|
};
|
|||
|
|
const renderContent = () => {
|
|||
|
|
const prev = currentInstance;
|
|||
|
|
simpleSetCurrentInstance(parentComponent);
|
|||
|
|
try {
|
|||
|
|
renderEffect(() => {
|
|||
|
|
withRenderContext(frag.ctx, () => {
|
|||
|
|
const nextChildren = render();
|
|||
|
|
notifyBeforeUpdate();
|
|||
|
|
if (isHydrating$1) {
|
|||
|
|
nextChildren.forEach((vnode) => hydrateVNode(vnode, parentComponent, frag.slotScopeIds, suspense));
|
|||
|
|
currentChildren = nextChildren;
|
|||
|
|
currentVNode = createVNode(Fragment, null, nextChildren);
|
|||
|
|
currentParentNode = currentHydrationNode.parentNode;
|
|||
|
|
childrenNamespace = getContainerType(currentParentNode);
|
|||
|
|
currentAnchor = currentHydrationNode;
|
|||
|
|
} else if (!isMounted) {
|
|||
|
|
currentChildren = nextChildren;
|
|||
|
|
currentVNode = createVNode(Fragment, null, nextChildren);
|
|||
|
|
const wasResolved = content.resolved;
|
|||
|
|
const validityChanged = syncResolvedNodes(nextChildren);
|
|||
|
|
if (wasResolved) notifyUpdated(validityChanged);
|
|||
|
|
return;
|
|||
|
|
} else if (!currentVNode) {
|
|||
|
|
currentChildren = nextChildren;
|
|||
|
|
currentVNode = createVNode(Fragment, null, nextChildren);
|
|||
|
|
trackSlotVNodeUpdatesWithRefresh(currentVNode, () => {
|
|||
|
|
notifyUpdated(syncResolvedNodesAndCleanup(nextChildren));
|
|||
|
|
}, notifyBeforeUpdate);
|
|||
|
|
if (nextChildren.length) {
|
|||
|
|
const prevInstance = currentInstance;
|
|||
|
|
simpleSetCurrentInstance(null);
|
|||
|
|
internals.mc(nextChildren, currentParentNode, currentAnchor, parentComponent, suspense, childrenNamespace, frag.slotScopeIds, false);
|
|||
|
|
simpleSetCurrentInstance(prevInstance);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
const nextVNode = createVNode(Fragment, null, nextChildren);
|
|||
|
|
trackSlotVNodeUpdatesWithRefresh(nextVNode, () => {
|
|||
|
|
notifyUpdated(syncResolvedNodesAndCleanup(nextChildren));
|
|||
|
|
}, notifyBeforeUpdate);
|
|||
|
|
const prevInstance = currentInstance;
|
|||
|
|
simpleSetCurrentInstance(null);
|
|||
|
|
internals.pc(currentVNode, nextVNode, currentParentNode, currentAnchor, parentComponent, suspense, childrenNamespace, frag.slotScopeIds, false);
|
|||
|
|
simpleSetCurrentInstance(prevInstance);
|
|||
|
|
currentChildren = nextChildren;
|
|||
|
|
currentVNode = nextVNode;
|
|||
|
|
}
|
|||
|
|
const validityChanged = syncResolvedNodesAndCleanup();
|
|||
|
|
if (isHydrating$1) {
|
|||
|
|
if (isMounted && frag.u) frag.u.forEach((hook) => hook(frag.nodes));
|
|||
|
|
} else notifyUpdated(validityChanged);
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
} finally {
|
|||
|
|
simpleSetCurrentInstance(prev);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
const startRenderEffect = () => {
|
|||
|
|
if (isRenderEffectStarted) return;
|
|||
|
|
isRenderEffectStarted = true;
|
|||
|
|
scope.run(renderContent);
|
|||
|
|
};
|
|||
|
|
if (!isHydrating$1) startRenderEffect();
|
|||
|
|
const place = (parentNode, anchor, parentSuspense, moveType = 2) => {
|
|||
|
|
if (isHydrating$1) return;
|
|||
|
|
if (parentSuspense !== void 0) suspense = parentSuspense;
|
|||
|
|
currentParentNode = parentNode;
|
|||
|
|
currentAnchor = anchor;
|
|||
|
|
if (!isMounted) {
|
|||
|
|
childrenNamespace = getContainerType(parentNode);
|
|||
|
|
startRenderEffect();
|
|||
|
|
if (currentVNode) trackSlotVNodeUpdatesWithRefresh(currentVNode, () => {
|
|||
|
|
notifyUpdated(syncResolvedNodesAndCleanup(currentChildren));
|
|||
|
|
}, notifyBeforeUpdate);
|
|||
|
|
if (currentChildren.length) {
|
|||
|
|
const prevInstance = currentInstance;
|
|||
|
|
simpleSetCurrentInstance(null);
|
|||
|
|
internals.mc(currentChildren, currentParentNode, currentAnchor, parentComponent, suspense, childrenNamespace, frag.slotScopeIds, false);
|
|||
|
|
simpleSetCurrentInstance(prevInstance);
|
|||
|
|
}
|
|||
|
|
syncResolvedNodes();
|
|||
|
|
isMounted = true;
|
|||
|
|
} else if (!isHydratingSlotFallback) currentChildren.forEach((vnode) => {
|
|||
|
|
internals.m(vnode, parentNode, anchor, moveType, parentComponent, suspense);
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
frag.insert = (parentNode, anchor, parentSuspense) => place(parentNode, anchor, parentSuspense);
|
|||
|
|
frag.move = (parentNode, anchor, moveType, _parentComponent, parentSuspense) => place(parentNode, anchor, parentSuspense, moveType);
|
|||
|
|
frag.remove = (parentNode) => {
|
|||
|
|
scope.stop();
|
|||
|
|
const parentSuspense = resolveUnmountSuspense(suspense);
|
|||
|
|
currentChildren.forEach((vnode) => {
|
|||
|
|
internals.um(vnode, parentComponent, parentSuspense, !!parentNode);
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
frag.hydrate = () => {
|
|||
|
|
if (!isHydrating$1) return;
|
|||
|
|
startRenderEffect();
|
|||
|
|
isMounted = true;
|
|||
|
|
};
|
|||
|
|
return frag;
|
|||
|
|
}
|
|||
|
|
function isSameResolvedOutput(prev, next) {
|
|||
|
|
return prev === next || isArray(prev) && isArray(next) && prev.length === next.length && prev.every((node, index) => node === next[index]);
|
|||
|
|
}
|
|||
|
|
function normalizeInteropSlots(rawSlots) {
|
|||
|
|
if (rawSlots == null) return EMPTY_OBJ;
|
|||
|
|
if (!isObject(rawSlots) || isArray(rawSlots) || isVNode(rawSlots)) return normalizeInteropDefaultSlot(rawSlots);
|
|||
|
|
const normalized = createInternalObject();
|
|||
|
|
for (const key in rawSlots) {
|
|||
|
|
if (isInternalSlotKey(key)) continue;
|
|||
|
|
const slot = rawSlots[key];
|
|||
|
|
if (isFunction(slot)) normalized[key] = slot[rawVaporSlotKey] || slot._n ? slot : normalizeInteropSlot(slot, rawSlots._ctx);
|
|||
|
|
else if (slot != null) normalized[key] = () => normalizeInteropSlotValue(slot);
|
|||
|
|
}
|
|||
|
|
[
|
|||
|
|
"_",
|
|||
|
|
"_ctx",
|
|||
|
|
"$stable"
|
|||
|
|
].forEach((key) => {
|
|||
|
|
const descriptor = Object.getOwnPropertyDescriptor(rawSlots, key);
|
|||
|
|
if (descriptor) Object.defineProperty(normalized, key, descriptor);
|
|||
|
|
});
|
|||
|
|
return normalized;
|
|||
|
|
}
|
|||
|
|
const interopSlotCache = /* @__PURE__ */ new WeakMap();
|
|||
|
|
function normalizeInteropSlot(rawSlot, ctx) {
|
|||
|
|
let cache = interopSlotCache.get(rawSlot);
|
|||
|
|
if (!cache) interopSlotCache.set(rawSlot, cache = {});
|
|||
|
|
if (ctx) {
|
|||
|
|
let ctxCache = cache.ctx;
|
|||
|
|
if (!ctxCache) cache.ctx = ctxCache = /* @__PURE__ */ new WeakMap();
|
|||
|
|
const cached = ctxCache.get(ctx);
|
|||
|
|
if (cached) return cached;
|
|||
|
|
const normalized = createNormalizedInteropSlot(rawSlot, ctx);
|
|||
|
|
ctxCache.set(ctx, normalized);
|
|||
|
|
return normalized;
|
|||
|
|
}
|
|||
|
|
if (cache.noCtx) return cache.noCtx;
|
|||
|
|
return cache.noCtx = createNormalizedInteropSlot(rawSlot, ctx);
|
|||
|
|
}
|
|||
|
|
function createNormalizedInteropSlot(rawSlot, ctx) {
|
|||
|
|
const normalized = withCtx((...args) => normalizeInteropSlotValue(rawSlot(...args)), ctx);
|
|||
|
|
normalized._c = false;
|
|||
|
|
return normalized;
|
|||
|
|
}
|
|||
|
|
function normalizeInteropDefaultSlot(value) {
|
|||
|
|
const normalized = createInternalObject();
|
|||
|
|
const normalizedValue = normalizeInteropSlotValue(value);
|
|||
|
|
normalized.default = () => normalizedValue;
|
|||
|
|
return normalized;
|
|||
|
|
}
|
|||
|
|
function normalizeInteropSlotValue(value) {
|
|||
|
|
return isArray(value) ? value.map((child) => normalizeVNode(child)) : [normalizeVNode(value)];
|
|||
|
|
}
|
|||
|
|
const isInternalSlotKey = (key) => key === "_" || key === "_ctx" || key === "$stable" || key === "$";
|
|||
|
|
const interopSlotsSourceHandlers = {
|
|||
|
|
get(target, key) {
|
|||
|
|
const slots = target.value;
|
|||
|
|
return slots && slots[key];
|
|||
|
|
},
|
|||
|
|
has(target, key) {
|
|||
|
|
const slots = target.value;
|
|||
|
|
return !!slots && key in slots;
|
|||
|
|
},
|
|||
|
|
ownKeys(target) {
|
|||
|
|
const slots = target.value;
|
|||
|
|
return slots ? Object.keys(slots).filter((key) => !isInternalSlotKey(key)) : EMPTY_ARR;
|
|||
|
|
},
|
|||
|
|
getOwnPropertyDescriptor(target, key) {
|
|||
|
|
const slots = target.value;
|
|||
|
|
const descriptor = slots && Object.getOwnPropertyDescriptor(slots, key);
|
|||
|
|
if (descriptor && descriptor.enumerable && !isInternalSlotKey(key)) return {
|
|||
|
|
enumerable: true,
|
|||
|
|
configurable: true,
|
|||
|
|
value: descriptor.value
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
function createInteropRawSlots(slotsRef) {
|
|||
|
|
return {
|
|||
|
|
$: [new Proxy(slotsRef, interopSlotsSourceHandlers)],
|
|||
|
|
[interopSlotsKey]: slotsRef
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
const interopRootSyncFragmentMap = /* @__PURE__ */ new WeakMap();
|
|||
|
|
function registerInteropRootSync(instance, frag) {
|
|||
|
|
if (interopRootSyncFragmentMap.get(frag) === instance) return;
|
|||
|
|
interopRootSyncFragmentMap.set(frag, instance);
|
|||
|
|
(frag.u || (frag.u = [])).push(() => syncInteropRoot(instance));
|
|||
|
|
}
|
|||
|
|
const interopDirsProducers = /* @__PURE__ */ new WeakSet();
|
|||
|
|
function registerInteropDirsFragment(instance, state, frag, inherit) {
|
|||
|
|
registerInteropRootSync(instance, frag);
|
|||
|
|
if (interopDirsProducers.has(frag)) return;
|
|||
|
|
interopDirsProducers.add(frag);
|
|||
|
|
let reactivated = null;
|
|||
|
|
(frag.bu || (frag.bu = [])).push(() => {
|
|||
|
|
if (inherit.el && inherit.el === getRootElement(frag.nodes)) unmountInteropDirsRoot(instance, inherit);
|
|||
|
|
});
|
|||
|
|
(frag.bm || (frag.bm = [])).push((nodes) => {
|
|||
|
|
if (!inherit.vnode.dirs || !isOnInteropRootChain(inherit.comp, frag)) return;
|
|||
|
|
const [owner, el] = resolveInteropDirsRoot(instance, state, nodes, inherit);
|
|||
|
|
if (!el) return;
|
|||
|
|
if (owner.el === el) {
|
|||
|
|
if (!owner.pending) owner.pending = owner.carried;
|
|||
|
|
reactivated = owner;
|
|||
|
|
} else mountInteropDirsRoot(instance, owner, el);
|
|||
|
|
});
|
|||
|
|
(frag.u || (frag.u = [])).push(() => {
|
|||
|
|
settleInteropDirsReceived(instance, state);
|
|||
|
|
const owner = reactivated;
|
|||
|
|
reactivated = null;
|
|||
|
|
if (!owner || !owner.el || !owner.pending || isInteropDirsUpdating(state, owner)) return;
|
|||
|
|
owner.updating = owner.comp;
|
|||
|
|
owner.patching = owner;
|
|||
|
|
invokeInteropDirsHook(instance, owner.el, owner.vnode, "beforeUpdate", owner.pending);
|
|||
|
|
queueInteropDirsJob(instance, () => afterInteropDirsSelfUpdate(instance, state, owner.comp));
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
function registerInteropDirsComponent(instance, state, comp) {
|
|||
|
|
if (comp === instance || interopDirsProducers.has(comp)) return;
|
|||
|
|
interopDirsProducers.add(comp);
|
|||
|
|
const pending = isPendingInteropSetup(comp);
|
|||
|
|
registerAfterInteropSetup(comp, pending, () => {
|
|||
|
|
(comp.bu || (comp.bu = [])).push(() => beforeInteropDirsSelfUpdate(instance, state, comp));
|
|||
|
|
(comp.u || (comp.u = [])).unshift(() => afterInteropDirsSelfUpdate(instance, state, comp));
|
|||
|
|
(comp.bum || (comp.bum = [])).push(() => unmountInteropDirs(instance, state, comp));
|
|||
|
|
if (pending) (comp.bm || (comp.bm = [])).push(() => {
|
|||
|
|
const owners = state.dirsOwners;
|
|||
|
|
const owner = owners && owners.get(comp);
|
|||
|
|
if (!owner || owner.el || !owner.vnode.dirs) return;
|
|||
|
|
const [inner, el] = resolveInteropDirsRoot(instance, state, comp.block, owner);
|
|||
|
|
if (el) mountInteropDirsRoot(instance, inner, el);
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
function isOnInteropRootChain(from, producer) {
|
|||
|
|
let found = false;
|
|||
|
|
getRootElement(from, {
|
|||
|
|
excludeSlotOutlets: true,
|
|||
|
|
onDynamicFragment: (frag) => frag === producer && (found = true),
|
|||
|
|
onComponent: (comp) => comp === producer && (found = true)
|
|||
|
|
});
|
|||
|
|
return found;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Stores the vnode-derived root-only ids on the instance. Metadata only:
|
|||
|
|
* mountComponent and dynamic branch renders apply them pre-insert to roots
|
|||
|
|
* that mount afterwards; kept roots keep their mount-time ids (VDOM parity).
|
|||
|
|
*/
|
|||
|
|
function setInteropComponentScopeIds(instance, vnode) {
|
|||
|
|
instance.scopeId = vnode.scopeId;
|
|||
|
|
const inherited = getInheritedScopeIds(vnode, instance.parent);
|
|||
|
|
instance.slotScopeIds = concatInteropScopeIds(vnode.slotScopeIds, inherited.length ? inherited : null);
|
|||
|
|
}
|
|||
|
|
function concatInteropScopeIds(base, own) {
|
|||
|
|
return base ? own && own.length && own !== base ? base.concat(own) : base : own || null;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Publishes root-only ids onto the interop vnode backing a vapor component's
|
|||
|
|
* effective root, for core to apply at its own pre-insertion mount. A nested
|
|||
|
|
* component crossed during the descent re-collects canonically — its climb
|
|||
|
|
* carries every ancestor's contribution — superseding the caller's subset.
|
|||
|
|
*/
|
|||
|
|
function publishVaporScopeIds(block, scopeIds) {
|
|||
|
|
let currentScopeIds = scopeIds;
|
|||
|
|
getRootElement(block, {
|
|||
|
|
onComponent: (instance) => {
|
|||
|
|
currentScopeIds = collectRootScopeIds(instance) || [];
|
|||
|
|
},
|
|||
|
|
onInteropFragment: (frag) => {
|
|||
|
|
if (frag.vnode) {
|
|||
|
|
setVNodeVaporScopeIds(frag.vnode, currentScopeIds);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
excludeSlotOutlets: true
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
function setVNodeVaporScopeIds(vnode, scopeIds) {
|
|||
|
|
vnode.vaporScopeIds = scopeIds;
|
|||
|
|
if (vnode.ssContent) setVNodeVaporScopeIds(vnode.ssContent, scopeIds);
|
|||
|
|
if (vnode.ssFallback) setVNodeVaporScopeIds(vnode.ssFallback, scopeIds);
|
|||
|
|
}
|
|||
|
|
function getInteropVaporSlotScopeIds(contextSlotScopeIds, own, inherited) {
|
|||
|
|
return concatInteropScopeIds(concatInteropScopeIds(contextSlotScopeIds, own), inherited.length ? inherited : null);
|
|||
|
|
}
|
|||
|
|
function getEnclosingOutletScopeIds(context, innerIds, inherited) {
|
|||
|
|
const kept = context && innerIds ? context.slice(0, -innerIds) : context;
|
|||
|
|
return getInteropVaporSlotScopeIds(kept && kept.length ? kept : null, null, inherited);
|
|||
|
|
}
|
|||
|
|
function interopHasVDOMContent() {
|
|||
|
|
return !!this.vnode;
|
|||
|
|
}
|
|||
|
|
function interopSetKey(key) {
|
|||
|
|
if (this.vnode) this.vnode.key = key;
|
|||
|
|
}
|
|||
|
|
function interopGetTransitionType() {
|
|||
|
|
return this.vnode ? getInteropTransitionType(this.vnode) : void 0;
|
|||
|
|
}
|
|||
|
|
function interopGetTransitionElement() {
|
|||
|
|
return this.vnode ? getInteropTransitionElement(this.vnode) : void 0;
|
|||
|
|
}
|
|||
|
|
function createInteropFragment(nodes = EMPTY_BLOCK, vnode = null, extraFlags = 0) {
|
|||
|
|
const frag = new RenderContextFragment(nodes, 64 | extraFlags);
|
|||
|
|
frag.vnode = vnode;
|
|||
|
|
frag.hasVDOMContent = interopHasVDOMContent;
|
|||
|
|
frag.setKey = interopSetKey;
|
|||
|
|
frag.getTransitionType = interopGetTransitionType;
|
|||
|
|
frag.getTransitionElement = interopGetTransitionElement;
|
|||
|
|
return frag;
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/components/Teleport.ts
|
|||
|
|
const VaporTeleportImpl = {
|
|||
|
|
name: "VaporTeleport",
|
|||
|
|
__isTeleport: true,
|
|||
|
|
__vapor: true,
|
|||
|
|
process(props, slots, adoptAnchor) {
|
|||
|
|
return new TeleportFragment(props, slots, adoptAnchor);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
var TeleportFragment = class extends RenderContextFragment {
|
|||
|
|
constructor(props, slots, adoptAnchor) {
|
|||
|
|
super([], 32);
|
|||
|
|
this.childrenInitialized = false;
|
|||
|
|
this.childrenScope = getCurrentScope();
|
|||
|
|
this.mountState = { location: 0 };
|
|||
|
|
this.dispose = () => {
|
|||
|
|
const scope = this.scope;
|
|||
|
|
if (scope) {
|
|||
|
|
this.scope = void 0;
|
|||
|
|
scope.stop();
|
|||
|
|
}
|
|||
|
|
const mountState = this.mountState;
|
|||
|
|
if (this.nodes && mountState.location === 1) {
|
|||
|
|
remove(this.nodes, mountState.container);
|
|||
|
|
this.nodes = [];
|
|||
|
|
}
|
|||
|
|
this.disposeTarget();
|
|||
|
|
this.mountState = { location: 0 };
|
|||
|
|
};
|
|||
|
|
this.hydrate = () => {
|
|||
|
|
if (!isHydrating$1) return;
|
|||
|
|
const target = this.target = resolveTeleportTarget(this.resolvedProps, querySelector);
|
|||
|
|
const disabled = isTeleportDisabled(this.resolvedProps);
|
|||
|
|
this.placeholder = currentHydrationNode;
|
|||
|
|
if (target) {
|
|||
|
|
const targetNode = target._lpa || target.firstChild;
|
|||
|
|
if (disabled) this.hydrateDisabledTeleport(target, targetNode);
|
|||
|
|
else {
|
|||
|
|
this.anchor = claimAnchor(locateTeleportEndAnchor(currentHydrationNode.nextSibling));
|
|||
|
|
this.hydrateTargetAnchors(target, targetNode);
|
|||
|
|
this.mountState = {
|
|||
|
|
location: 2,
|
|||
|
|
container: target,
|
|||
|
|
anchor: this.targetAnchor || null
|
|||
|
|
};
|
|||
|
|
if (targetNode) setCurrentHydrationNode(targetNode.nextSibling);
|
|||
|
|
if (!this.targetAnchor) this.mountChildren(target);
|
|||
|
|
else this.initChildren();
|
|||
|
|
}
|
|||
|
|
} else if (disabled) this.hydrateDisabledTeleport(null, null);
|
|||
|
|
else this.anchor = claimAnchor(locateTeleportEndAnchor(currentHydrationNode.nextSibling));
|
|||
|
|
advanceHydrationNode(this.anchor);
|
|||
|
|
};
|
|||
|
|
this.rawSlots = slots;
|
|||
|
|
this.anchor = isHydrating$1 ? void 0 : resolveFragmentAnchor(adoptAnchor, "teleport end");
|
|||
|
|
const propsProxy = new Proxy(props, rawPropsProxyHandlers);
|
|||
|
|
renderEffect(() => {
|
|||
|
|
const prevTo = this.resolvedProps && this.resolvedProps.to;
|
|||
|
|
const wasDisabled = this.isDisabled;
|
|||
|
|
this.resolvedProps = extend$1({}, propsProxy);
|
|||
|
|
this.isDisabled = isTeleportDisabled(this.resolvedProps);
|
|||
|
|
if (wasDisabled !== this.isDisabled || !this.isDisabled && prevTo !== this.resolvedProps.to) this.handlePropsUpdate();
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
get parent() {
|
|||
|
|
return this.anchor ? /* @__PURE__ */ parentNode(this.anchor) : null;
|
|||
|
|
}
|
|||
|
|
get scopeOwner() {
|
|||
|
|
return this.ctx.slotOwner || this.renderInstance;
|
|||
|
|
}
|
|||
|
|
initChildren() {
|
|||
|
|
const instance = this.renderInstance;
|
|||
|
|
const prevInstance = setCurrentInstance(instance, this.childrenScope);
|
|||
|
|
const prevUpdating = instance ? instance.isUpdating : false;
|
|||
|
|
if (instance) instance.isUpdating = true;
|
|||
|
|
try {
|
|||
|
|
this.childrenInitialized = true;
|
|||
|
|
renderEffect(() => withRenderContext(this.ctx, () => {
|
|||
|
|
const prevScope = this.scope;
|
|||
|
|
if (prevScope) prevScope.stop();
|
|||
|
|
const scope = this.scope = new EffectScope$1();
|
|||
|
|
this.handleChildrenUpdate(scope.run(() => this.rawSlots && this.rawSlots.default ? this.rawSlots.default() : []) || []);
|
|||
|
|
}));
|
|||
|
|
const owner = this.scopeOwner;
|
|||
|
|
if (owner && owner.applyCssVars) registerCssVarOutlet(owner, this);
|
|||
|
|
this.bindChildren(this.nodes);
|
|||
|
|
} finally {
|
|||
|
|
if (instance) instance.isUpdating = prevUpdating;
|
|||
|
|
restoreCurrentInstance(prevInstance);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
ensureChildrenInitialized() {
|
|||
|
|
if (!this.childrenInitialized) this.initChildren();
|
|||
|
|
}
|
|||
|
|
bindChildren(block) {
|
|||
|
|
const owner = this.scopeOwner;
|
|||
|
|
if (owner && owner.applyCssVars) owner.applyCssVars(block);
|
|||
|
|
}
|
|||
|
|
handleChildrenUpdate(children) {
|
|||
|
|
const mountState = this.mountState;
|
|||
|
|
if (isHydrating$1 || !this.parent || mountState.location === 0) {
|
|||
|
|
this.nodes = children;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
remove(this.nodes, mountState.container);
|
|||
|
|
this.nodes = children;
|
|||
|
|
this.bindChildren(children);
|
|||
|
|
insert(children, mountState.container, mountState.anchor);
|
|||
|
|
}
|
|||
|
|
mount(parent, anchor, location) {
|
|||
|
|
if (isTransitionEnabled && this.$transition && this.mountState.location === 0) applyTransitionHooks(this.nodes, this.$transition, this);
|
|||
|
|
if (this.mountState.location !== 0) move(this.nodes, parent, anchor, 2);
|
|||
|
|
else insert(this.nodes, parent, anchor);
|
|||
|
|
this.mountState = {
|
|||
|
|
location,
|
|||
|
|
container: parent,
|
|||
|
|
anchor
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
prepareTargetAnchors(target) {
|
|||
|
|
if (!this.targetAnchor || /* @__PURE__ */ parentNode(this.targetAnchor) !== target) {
|
|||
|
|
if (this.targetStart) remove(this.targetStart, /* @__PURE__ */ parentNode(this.targetStart));
|
|||
|
|
if (this.targetAnchor) remove(this.targetAnchor, /* @__PURE__ */ parentNode(this.targetAnchor));
|
|||
|
|
insert(this.targetStart = /* @__PURE__ */ createTextNode(""), target);
|
|||
|
|
insert(this.targetAnchor = /* @__PURE__ */ createTextNode(""), target);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
prepareTarget() {
|
|||
|
|
const target = this.target = resolveTeleportTarget(this.resolvedProps, querySelector);
|
|||
|
|
if (target) this.prepareTargetAnchors(target);
|
|||
|
|
return target;
|
|||
|
|
}
|
|||
|
|
queueTargetUpdate() {
|
|||
|
|
if (!this.mountToTargetJob || this.mountToTargetJob.flags & 4) this.mountToTargetJob = () => {
|
|||
|
|
this.mountToTargetJob = void 0;
|
|||
|
|
if (!this.anchor) return;
|
|||
|
|
if (this.isDisabled) {
|
|||
|
|
if (!this.targetAnchor) this.prepareTarget();
|
|||
|
|
} else this.mountToTarget();
|
|||
|
|
};
|
|||
|
|
queuePostRenderEffect(this.mountToTargetJob, void 0, this.parentSuspense !== void 0 ? this.parentSuspense : isSuspenseEnabled && this.ctx.suspense || null);
|
|||
|
|
}
|
|||
|
|
mountToTarget() {
|
|||
|
|
const target = this.prepareTarget();
|
|||
|
|
if (target) {
|
|||
|
|
this.ensureChildrenInitialized();
|
|||
|
|
this.mount(target, this.targetAnchor, 2);
|
|||
|
|
this.cancelMountToTarget();
|
|||
|
|
} else if (!!(process.env.NODE_ENV !== "production")) warn(`Invalid Teleport target on ${this.targetAnchor ? "update" : "mount"}:`, target, `(${typeof target})`);
|
|||
|
|
}
|
|||
|
|
handlePropsUpdate() {
|
|||
|
|
if (!this.parent || isHydrating$1) return;
|
|||
|
|
if (this.isDisabled) {
|
|||
|
|
this.ensureChildrenInitialized();
|
|||
|
|
this.mount(this.parent, this.anchor, 1);
|
|||
|
|
if (!this.targetAnchor) {
|
|||
|
|
if (isTeleportDeferred(this.resolvedProps) || !this.parent.isConnected) this.queueTargetUpdate();
|
|||
|
|
else this.prepareTarget();
|
|||
|
|
}
|
|||
|
|
} else if (isTeleportDeferred(this.resolvedProps) || !this.parent.isConnected) this.queueTargetUpdate();
|
|||
|
|
else this.mountToTarget();
|
|||
|
|
}
|
|||
|
|
insert(container, anchor, parentSuspense) {
|
|||
|
|
if (isHydrating$1) return;
|
|||
|
|
if (parentSuspense !== void 0) this.parentSuspense = parentSuspense;
|
|||
|
|
const wasMountedInTarget = this.mountState.location === 2;
|
|||
|
|
if (!this.placeholder) this.placeholder = !!(process.env.NODE_ENV !== "production") ? /* @__PURE__ */ createComment("teleport start") : /* @__PURE__ */ createTextNode();
|
|||
|
|
insert(this.placeholder, container, anchor);
|
|||
|
|
insert(this.anchor, container, anchor);
|
|||
|
|
if (!wasMountedInTarget) this.handlePropsUpdate();
|
|||
|
|
}
|
|||
|
|
move(container, anchor, _moveType, _parentComponent, parentSuspense) {
|
|||
|
|
this.insert(container, anchor, parentSuspense);
|
|||
|
|
}
|
|||
|
|
cancelMountToTarget() {
|
|||
|
|
if (this.mountToTargetJob) {
|
|||
|
|
this.mountToTargetJob.flags |= 4;
|
|||
|
|
this.mountToTargetJob = void 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
disposeTarget() {
|
|||
|
|
this.cancelMountToTarget();
|
|||
|
|
const mountState = this.mountState;
|
|||
|
|
if (this.nodes && mountState.location === 2) {
|
|||
|
|
const targetParent = this.targetStart && /* @__PURE__ */ parentNode(this.targetStart) || this.targetAnchor && /* @__PURE__ */ parentNode(this.targetAnchor) || void 0;
|
|||
|
|
remove(this.nodes, targetParent);
|
|||
|
|
this.nodes = [];
|
|||
|
|
this.mountState = { location: 0 };
|
|||
|
|
}
|
|||
|
|
if (this.targetStart) {
|
|||
|
|
remove(this.targetStart, /* @__PURE__ */ parentNode(this.targetStart));
|
|||
|
|
this.targetStart = void 0;
|
|||
|
|
}
|
|||
|
|
if (this.targetAnchor) {
|
|||
|
|
remove(this.targetAnchor, /* @__PURE__ */ parentNode(this.targetAnchor));
|
|||
|
|
this.targetAnchor = void 0;
|
|||
|
|
}
|
|||
|
|
this.target = void 0;
|
|||
|
|
}
|
|||
|
|
scheduleTargetDispose() {
|
|||
|
|
this.cancelMountToTarget();
|
|||
|
|
queuePostFlushCb(() => this.disposeTarget());
|
|||
|
|
}
|
|||
|
|
remove() {
|
|||
|
|
this.dispose();
|
|||
|
|
if (this.anchor) {
|
|||
|
|
remove(this.anchor, /* @__PURE__ */ parentNode(this.anchor));
|
|||
|
|
this.anchor = void 0;
|
|||
|
|
}
|
|||
|
|
if (this.placeholder) {
|
|||
|
|
remove(this.placeholder, /* @__PURE__ */ parentNode(this.placeholder));
|
|||
|
|
this.placeholder = void 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
hydrateTargetAnchors(target, targetNode) {
|
|||
|
|
if (!isHydrating$1) return;
|
|||
|
|
let targetAnchor = targetNode;
|
|||
|
|
while (targetAnchor) {
|
|||
|
|
if (targetAnchor.nodeType === 8) {
|
|||
|
|
if (targetAnchor.data === "teleport start anchor") this.targetStart = targetAnchor;
|
|||
|
|
else if (targetAnchor.data === "teleport anchor") {
|
|||
|
|
this.targetAnchor = claimAnchor(targetAnchor);
|
|||
|
|
target._lpa = this.targetAnchor.nextSibling;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
targetAnchor = targetAnchor.nextSibling;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
hydrateDisabledTeleport(target, targetNode) {
|
|||
|
|
if (!isHydrating$1) return;
|
|||
|
|
let nextNode = this.placeholder.nextSibling;
|
|||
|
|
setCurrentHydrationNode(nextNode);
|
|||
|
|
this.anchor = claimAnchor(locateTeleportEndAnchor(nextNode));
|
|||
|
|
this.mountState = {
|
|||
|
|
location: 1,
|
|||
|
|
container: /* @__PURE__ */ parentNode(this.anchor),
|
|||
|
|
anchor: this.anchor
|
|||
|
|
};
|
|||
|
|
if (target) this.hydrateTargetAnchors(target, targetNode);
|
|||
|
|
else {
|
|||
|
|
this.targetStart = targetNode;
|
|||
|
|
this.targetAnchor = targetNode && targetNode.nextSibling;
|
|||
|
|
}
|
|||
|
|
this.initChildren();
|
|||
|
|
}
|
|||
|
|
mountChildren(target) {
|
|||
|
|
if (!isHydrating$1) return;
|
|||
|
|
target.appendChild(this.targetStart = /* @__PURE__ */ createTextNode(""));
|
|||
|
|
target.appendChild(this.targetAnchor = claimAnchor(/* @__PURE__ */ createTextNode("")));
|
|||
|
|
this.mountState = {
|
|||
|
|
location: 2,
|
|||
|
|
container: target,
|
|||
|
|
anchor: this.targetAnchor
|
|||
|
|
};
|
|||
|
|
if (!isMismatchAllowed(target, 1)) {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) warn(`Hydration children mismatch on`, target, `\nServer rendered element contains fewer child nodes than client nodes.`);
|
|||
|
|
logMismatchError();
|
|||
|
|
}
|
|||
|
|
runWithoutHydration(this.initChildren.bind(this));
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
const VaporTeleport = /*@__PURE__*/ enableTeleport(VaporTeleportImpl);
|
|||
|
|
function locateTeleportEndAnchor(node = currentHydrationNode) {
|
|||
|
|
let depth = 0;
|
|||
|
|
while (node) {
|
|||
|
|
if (isComment(node, "teleport start")) depth++;
|
|||
|
|
else if (isComment(node, "teleport end")) {
|
|||
|
|
if (depth === 0) return node;
|
|||
|
|
else depth--;
|
|||
|
|
}
|
|||
|
|
node = node.nextSibling;
|
|||
|
|
}
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/apiDefineCustomElement.ts
|
|||
|
|
const vaporCustomElementHydrates = /* @__PURE__ */ new WeakMap();
|
|||
|
|
/*@__NO_SIDE_EFFECTS__*/
|
|||
|
|
function defineVaporCustomElement(options, extraOptions, _createApp, _hydrate) {
|
|||
|
|
let Comp = /* @__PURE__ */ defineVaporComponent(options, extraOptions);
|
|||
|
|
if (isPlainObject(Comp)) Comp = extend$1({}, Comp, extraOptions);
|
|||
|
|
class VaporCustomElement extends VaporElement {
|
|||
|
|
constructor(initialProps) {
|
|||
|
|
super(Comp, initialProps, _createApp);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
VaporCustomElement.def = Comp;
|
|||
|
|
if (_hydrate) vaporCustomElementHydrates.set(VaporCustomElement, _hydrate);
|
|||
|
|
return VaporCustomElement;
|
|||
|
|
}
|
|||
|
|
const defineVaporSSRCustomElement = ((options, extraOptions) => {
|
|||
|
|
return /* @__PURE__ */ defineVaporCustomElement(options, extraOptions, createVaporSSRApp, withHydration);
|
|||
|
|
});
|
|||
|
|
var VaporElement = class extends VueElementBase {
|
|||
|
|
constructor(def, props = {}, createAppFn = createVaporApp) {
|
|||
|
|
super(def, shallowReactive$1(props), createAppFn);
|
|||
|
|
}
|
|||
|
|
_needsHydration() {
|
|||
|
|
const hydrate = vaporCustomElementHydrates.get(this.constructor);
|
|||
|
|
if (this.shadowRoot && hydrate) return true;
|
|||
|
|
else if (!!(process.env.NODE_ENV !== "production") && this.shadowRoot) warn("Custom element has pre-rendered declarative shadow root but is not defined as hydratable. Use `defineVaporSSRCustomElement`.");
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
_mount(def) {
|
|||
|
|
if ((!!(process.env.NODE_ENV !== "production") || __VUE_PROD_DEVTOOLS__) && !def.name) def.name = "VaporElement";
|
|||
|
|
this._app = this._createApp(this._def);
|
|||
|
|
this._inheritParentContext();
|
|||
|
|
if (this._def.configureApp) this._def.configureApp(this._app);
|
|||
|
|
const hydrate = vaporCustomElementHydrates.get(this.constructor);
|
|||
|
|
if (this.shadowRoot && hydrate) hydrate(this._root, this._createComponent.bind(this));
|
|||
|
|
else this._createComponent();
|
|||
|
|
this._app.mount(this._root);
|
|||
|
|
}
|
|||
|
|
_update() {}
|
|||
|
|
_unmount() {
|
|||
|
|
if (this._app) this._app.unmount();
|
|||
|
|
if (this._instance && this._instance.ce) this._instance.ce = void 0;
|
|||
|
|
this._app = this._instance = null;
|
|||
|
|
}
|
|||
|
|
_createComponent() {
|
|||
|
|
const ce = (instance) => {
|
|||
|
|
this._app._ceComponent = this._instance = instance;
|
|||
|
|
this._processInstance();
|
|||
|
|
};
|
|||
|
|
createComponent(this._def, { $: [() => this._props] }, this.shadowRoot ? void 0 : this._createSlots(), void 0, void 0, this._app._context, true, ce);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Only called when shadowRoot is false. The light DOM children parsed on
|
|||
|
|
* connect become static slots, so `<slot/>` outlets render them in place
|
|||
|
|
* through the normal slot pipeline instead of a native outlet that has to
|
|||
|
|
* be replaced after mount.
|
|||
|
|
*/
|
|||
|
|
_createSlots() {
|
|||
|
|
const parsed = this._slots;
|
|||
|
|
if (!parsed) return;
|
|||
|
|
const scopeId = this._def.__scopeId;
|
|||
|
|
let slots;
|
|||
|
|
for (const name in parsed) {
|
|||
|
|
const nodes = parsed[name];
|
|||
|
|
if (scopeId) {
|
|||
|
|
const id = scopeId + "-s";
|
|||
|
|
for (const n of nodes) if (n.nodeType === 1) {
|
|||
|
|
n.setAttribute(id, "");
|
|||
|
|
const walker = document.createTreeWalker(n, 1);
|
|||
|
|
let child;
|
|||
|
|
while (child = walker.nextNode()) child.setAttribute(id, "");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
(slots || (slots = {}))[name] = () => nodes;
|
|||
|
|
}
|
|||
|
|
return slots;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/dom/template.ts
|
|||
|
|
function cloneTemplate(n) {
|
|||
|
|
const scopeIds = currentRenderContext.slotScopeIds;
|
|||
|
|
return scopeIds ? cloneStampedTemplate(n, scopeIds) : n.cloneNode(true);
|
|||
|
|
}
|
|||
|
|
/*@__NO_SIDE_EFFECTS__*/
|
|||
|
|
function template(html, flags = 0, ns) {
|
|||
|
|
const root = !!(flags & 1);
|
|||
|
|
const isStatic = !!(flags & 2);
|
|||
|
|
let node;
|
|||
|
|
let adoptTarget;
|
|||
|
|
let rootMeta;
|
|||
|
|
const createRootMeta = () => {
|
|||
|
|
let cls;
|
|||
|
|
let sty;
|
|||
|
|
let resolved = false;
|
|||
|
|
const resolve = () => {
|
|||
|
|
resolved = true;
|
|||
|
|
if (html.includes(" class=") || html.includes(" style=")) {
|
|||
|
|
const el = node || (node = parseTemplate(html, ns));
|
|||
|
|
if (el.classList.length) cls = Array.from(el.classList);
|
|||
|
|
const style = el.getAttribute("style");
|
|||
|
|
if (style) sty = parseStringStyle(style);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
return {
|
|||
|
|
get cls() {
|
|||
|
|
resolved || resolve();
|
|||
|
|
return cls;
|
|||
|
|
},
|
|||
|
|
get sty() {
|
|||
|
|
resolved || resolve();
|
|||
|
|
return sty;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
};
|
|||
|
|
return () => {
|
|||
|
|
let hydrationCursor = null;
|
|||
|
|
if (insertionParent) {
|
|||
|
|
if (isHydrating$1) hydrationCursor = enterHydrationCursor(void 0, (adoptTarget || (adoptTarget = parseAdoptTarget(html))).blank);
|
|||
|
|
else resetInsertionState();
|
|||
|
|
}
|
|||
|
|
if (isHydrating$1) {
|
|||
|
|
let adopted = null;
|
|||
|
|
if (isStatic && !isComment(currentHydrationNode, "")) {
|
|||
|
|
adopted = resolveHydrationTarget(currentHydrationNode);
|
|||
|
|
if (html !== "") {
|
|||
|
|
if (html[0] !== "<") {
|
|||
|
|
if (!hydrateTextNode(adopted, html) && (!!(process.env.NODE_ENV !== "production") || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__)) validateHydrationTarget(adopted, html);
|
|||
|
|
} else if (!!(process.env.NODE_ENV !== "production") || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) validateHydrationTarget(adopted, html);
|
|||
|
|
}
|
|||
|
|
if (!node && !html) node = adopted.cloneNode(true);
|
|||
|
|
advanceHydrationNode(adopted);
|
|||
|
|
} else adopted = adoptTemplate(currentHydrationNode, html, false, ns, adoptTarget || (adoptTarget = parseAdoptTarget(html)));
|
|||
|
|
if (root) adopted.$root = rootMeta || (rootMeta = createRootMeta());
|
|||
|
|
exitHydrationCursor(hydrationCursor);
|
|||
|
|
return adopted;
|
|||
|
|
}
|
|||
|
|
if (!node && html[0] !== "<") return /* @__PURE__ */ createTextNode(html);
|
|||
|
|
const ret = cloneTemplate(node || (node = parseTemplate(html, ns)));
|
|||
|
|
if (root) ret.$root = rootMeta || (rootMeta = createRootMeta());
|
|||
|
|
return ret;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/apiCreateIf.ts
|
|||
|
|
function createIf(condition, b1, b2, flags = 1) {
|
|||
|
|
const _insertionParent = insertionParent;
|
|||
|
|
const _insertionAnchor = insertionAnchor;
|
|||
|
|
if (!isHydrating$1) resetInsertionState();
|
|||
|
|
let hydrationCursor = null;
|
|||
|
|
let branchShape;
|
|||
|
|
let anchor;
|
|||
|
|
let frag;
|
|||
|
|
if (flags & 16) {
|
|||
|
|
const ok = condition();
|
|||
|
|
let claim;
|
|||
|
|
if (isHydrating$1) {
|
|||
|
|
branchShape = decodeIfShape(flags, ok);
|
|||
|
|
claim = branchShape === 2 ? createFragmentClaim() : void 0;
|
|||
|
|
hydrationCursor = enterHydrationCursor(claim);
|
|||
|
|
}
|
|||
|
|
frag = ok ? b1() : b2 ? b2() : [claimUntrackedAnchor(!!(process.env.NODE_ENV !== "production") ? /* @__PURE__ */ createComment("if") : /* @__PURE__ */ createTextNode())];
|
|||
|
|
if (isHydrating$1 && claim && claim.start) advanceHydrationNode(locateEndAnchor(claim.start));
|
|||
|
|
} else {
|
|||
|
|
const index = flags >> 8;
|
|||
|
|
const keyed = index > 0;
|
|||
|
|
const keyBase = keyed ? (index - 1) * 2 : 0;
|
|||
|
|
const trackSlotBoundary = !!(flags & 128);
|
|||
|
|
const dynamicFragment = new DynamicFragment(256, !!(process.env.NODE_ENV !== "production") ? "if" : void 0, keyed, trackSlotBoundary, trackSlotBoundary ? () => {
|
|||
|
|
const anchor = dynamicFragment.anchor;
|
|||
|
|
const parent = anchor.parentNode;
|
|||
|
|
if (parent) removeNode(anchor, parent);
|
|||
|
|
} : void 0, _insertionAnchor);
|
|||
|
|
anchor = dynamicFragment.anchor;
|
|||
|
|
frag = dynamicFragment;
|
|||
|
|
renderEffect(() => {
|
|||
|
|
const ok = condition();
|
|||
|
|
if (isHydrating$1) {
|
|||
|
|
branchShape = decodeIfShape(flags, ok);
|
|||
|
|
dynamicFragment.hydrationClaim = branchShape === 2 ? createFragmentClaim() : void 0;
|
|||
|
|
hydrationCursor = enterHydrationCursor(dynamicFragment.hydrationClaim);
|
|||
|
|
}
|
|||
|
|
dynamicFragment.update(ok ? b1 : b2, keyed ? keyBase + (ok ? 0 : 1) : void 0, isNoScopeBranch(flags, ok));
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
if (isHydrating$1 && branchShape === 0 && hydrationCursor) {
|
|||
|
|
const start = hydrationCursor.start;
|
|||
|
|
if (start && currentHydrationNode === start && isComment(start, "")) advanceHydrationNode(start);
|
|||
|
|
}
|
|||
|
|
finishBlockCreation(frag, anchor, hydrationCursor, _insertionParent, _insertionAnchor);
|
|||
|
|
return frag;
|
|||
|
|
}
|
|||
|
|
function decodeIfShape(shape, ok) {
|
|||
|
|
return shape >> (ok ? 0 : 2) & 3;
|
|||
|
|
}
|
|||
|
|
function isNoScopeBranch(flags, ok) {
|
|||
|
|
return !!(flags & (ok ? 32 : 64));
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/apiCreateFragment.ts
|
|||
|
|
/**
|
|||
|
|
* Create a dynamic fragment keyed by a reactive value for Vapor transitions.
|
|||
|
|
* The fragment is re-rendered when the key changes to trigger enter/leave
|
|||
|
|
* animations.
|
|||
|
|
*
|
|||
|
|
* Example:
|
|||
|
|
* <VaporTransition>
|
|||
|
|
* <h1 :key="count">{{ count }}</h1>
|
|||
|
|
* </VaporTransition>
|
|||
|
|
*/
|
|||
|
|
function createKeyedFragment(key, render, trackSlotBoundary = false) {
|
|||
|
|
const _insertionParent = insertionParent;
|
|||
|
|
const _insertionAnchor = insertionAnchor;
|
|||
|
|
if (!isHydrating$1) resetInsertionState();
|
|||
|
|
const hydrationCursor = isHydrating$1 ? captureHydrationCursor() : null;
|
|||
|
|
const frag = new DynamicFragment(0, !!(process.env.NODE_ENV !== "production") ? "keyed" : void 0, true, trackSlotBoundary, trackSlotBoundary ? () => {
|
|||
|
|
const parent = frag.anchor.parentNode;
|
|||
|
|
if (parent) removeNode(frag.anchor, parent);
|
|||
|
|
} : void 0, _insertionAnchor);
|
|||
|
|
if (isHydrating$1) locateHydrationNode();
|
|||
|
|
renderEffect(() => frag.update(render, key()));
|
|||
|
|
finishBlockCreation(frag, frag.anchor, hydrationCursor, _insertionParent, _insertionAnchor);
|
|||
|
|
return frag;
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/apiCreateFor.ts
|
|||
|
|
const createFor = (src, renderItem, getKey, flags = 0) => {
|
|||
|
|
const _insertionParent = insertionParent;
|
|||
|
|
const _insertionAnchor = insertionAnchor;
|
|||
|
|
const _insertionIndex = insertionIndex;
|
|||
|
|
let hydrationCursor = null;
|
|||
|
|
let hydrationClaim;
|
|||
|
|
if (isHydrating$1) {
|
|||
|
|
hydrationClaim = createFragmentClaim();
|
|||
|
|
hydrationCursor = enterHydrationCursor(hydrationClaim);
|
|||
|
|
} else resetInsertionState();
|
|||
|
|
let isMounted = false;
|
|||
|
|
let oldBlocks = [];
|
|||
|
|
let newBlocks;
|
|||
|
|
let newKeys;
|
|||
|
|
let parent;
|
|||
|
|
let parentAnchor;
|
|||
|
|
if (!isHydrating$1) {
|
|||
|
|
parentAnchor = resolveFragmentAnchor(_insertionAnchor, "for");
|
|||
|
|
if (parentAnchor === _insertionAnchor) parent = parentAnchor.parentNode;
|
|||
|
|
}
|
|||
|
|
const trackSlotBoundary = !!(flags & 32);
|
|||
|
|
const frag = new ForFragment(oldBlocks, trackSlotBoundary, trackSlotBoundary ? () => {
|
|||
|
|
const parent = parentAnchor.parentNode;
|
|||
|
|
if (parent) removeNode(parentAnchor, parent);
|
|||
|
|
} : void 0);
|
|||
|
|
const instance = currentInstance$1;
|
|||
|
|
const isComponent = !!(flags & 2);
|
|||
|
|
const canUseFastRemove = !!(flags & 1) && !isComponent;
|
|||
|
|
const isSingleNode = !!(flags & 8);
|
|||
|
|
const isFragment = !!(flags & 16);
|
|||
|
|
const wrappedRows = !!(flags & 64);
|
|||
|
|
const ctx = currentRenderContext;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && !instance) warn("createFor() can only be used inside setup()");
|
|||
|
|
onScopeDispose$1(() => {
|
|||
|
|
stopBlockScopes(oldBlocks);
|
|||
|
|
if (newBlocks && newBlocks !== oldBlocks) stopBlockScopes(newBlocks);
|
|||
|
|
oldBlocks = [];
|
|||
|
|
newBlocks = [];
|
|||
|
|
}, true);
|
|||
|
|
const renderList = () => {
|
|||
|
|
const source = normalizeSource(src());
|
|||
|
|
const sourceKeys = source.keys;
|
|||
|
|
const newLength = source.values.length;
|
|||
|
|
const oldLength = oldBlocks.length;
|
|||
|
|
newBlocks = new Array(newLength);
|
|||
|
|
newKeys = void 0;
|
|||
|
|
if (getKey) {
|
|||
|
|
newKeys = new Array(newLength);
|
|||
|
|
for (let i = 0; i < newLength; i++) {
|
|||
|
|
const value = getItemValue(source, i);
|
|||
|
|
newKeys[i] = sourceKeys ? getKey(value, sourceKeys[i], i) : getKey(value, i, void 0);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
const prevSub = setActiveSub();
|
|||
|
|
const wasMounted = isMounted;
|
|||
|
|
if (wasMounted && frag.bu) for (let i = 0; i < frag.bu.length; i++) frag.bu[i]();
|
|||
|
|
if (!wasMounted) {
|
|||
|
|
isMounted = true;
|
|||
|
|
if (isHydrating$1) hydrateList(source, newLength);
|
|||
|
|
else mountAll(source, newLength);
|
|||
|
|
} else {
|
|||
|
|
parent = parentAnchor.parentNode;
|
|||
|
|
if (!oldLength) mountAll(source, newLength);
|
|||
|
|
else if (!newLength) {
|
|||
|
|
if (frag.resetListeners) for (const fn of frag.resetListeners) fn();
|
|||
|
|
const doRemove = !canUseFastRemove;
|
|||
|
|
for (let i = 0; i < oldLength; i++) unmount(oldBlocks[i], doRemove);
|
|||
|
|
if (canUseFastRemove) {
|
|||
|
|
parent.textContent = "";
|
|||
|
|
parent.appendChild(parentAnchor);
|
|||
|
|
}
|
|||
|
|
} else if (!getKey) {
|
|||
|
|
const commonLength = Math.min(newLength, oldLength);
|
|||
|
|
for (let i = 0; i < commonLength; i++) updateAt(newBlocks[i] = oldBlocks[i], source, i);
|
|||
|
|
for (let i = oldLength; i < newLength; i++) mount(source, i, parentAnchor);
|
|||
|
|
for (let i = newLength; i < oldLength; i++) unmount(oldBlocks[i]);
|
|||
|
|
} else {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) {
|
|||
|
|
const keyToIndexMap = /* @__PURE__ */ new Map();
|
|||
|
|
for (let i = 0; i < newLength; i++) {
|
|||
|
|
const key = newKeys[i];
|
|||
|
|
if (key != null) {
|
|||
|
|
if (keyToIndexMap.has(key)) warn(`Duplicate keys found during update:`, JSON.stringify(key), `Make sure keys are unique.`);
|
|||
|
|
keyToIndexMap.set(key, i);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
const commonLength = Math.min(oldLength, newLength);
|
|||
|
|
let endOffset = 0;
|
|||
|
|
while (endOffset < commonLength) {
|
|||
|
|
const index = newLength - endOffset - 1;
|
|||
|
|
const key = newKeys[index];
|
|||
|
|
const existingBlock = oldBlocks[oldLength - endOffset - 1];
|
|||
|
|
if (existingBlock.key !== key) break;
|
|||
|
|
updateAt(existingBlock, source, index);
|
|||
|
|
newBlocks[index] = existingBlock;
|
|||
|
|
endOffset++;
|
|||
|
|
}
|
|||
|
|
const e1 = commonLength - endOffset;
|
|||
|
|
const e2 = oldLength - endOffset;
|
|||
|
|
const e3 = newLength - endOffset;
|
|||
|
|
const queuedIndices = [];
|
|||
|
|
const oldKeyIndexMap = /* @__PURE__ */ new Map();
|
|||
|
|
for (let i = 0; i < e1; i++) {
|
|||
|
|
const currentKey = newKeys[i];
|
|||
|
|
const oldBlock = oldBlocks[i];
|
|||
|
|
if (oldBlock.key === currentKey) updateAt(newBlocks[i] = oldBlock, source, i);
|
|||
|
|
else {
|
|||
|
|
queuedIndices.push(i);
|
|||
|
|
oldKeyIndexMap.set(oldBlock.key, i);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
for (let i = e1; i < e2; i++) oldKeyIndexMap.set(oldBlocks[i].key, i);
|
|||
|
|
for (let i = e1; i < e3; i++) queuedIndices.push(i);
|
|||
|
|
let queuedLength = queuedIndices.length;
|
|||
|
|
let sources = EMPTY_ARR;
|
|||
|
|
let mountCounter = 0;
|
|||
|
|
let pureInsert = false;
|
|||
|
|
if (oldKeyIndexMap.size === 0) {
|
|||
|
|
mountCounter = queuedLength;
|
|||
|
|
pureInsert = true;
|
|||
|
|
} else {
|
|||
|
|
sources = new Array(queuedLength);
|
|||
|
|
for (let q = queuedLength - 1; q >= 0; q--) {
|
|||
|
|
const index = queuedIndices[q];
|
|||
|
|
const key = newKeys[index];
|
|||
|
|
const oldIndex = oldKeyIndexMap.get(key);
|
|||
|
|
if (oldIndex !== void 0) {
|
|||
|
|
oldKeyIndexMap.delete(key);
|
|||
|
|
const reusedBlock = newBlocks[index] = oldBlocks[oldIndex];
|
|||
|
|
updateAt(reusedBlock, source, index);
|
|||
|
|
sources[q] = oldIndex + 1;
|
|||
|
|
} else {
|
|||
|
|
sources[q] = 0;
|
|||
|
|
mountCounter++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
const useFastRemove = mountCounter === newLength;
|
|||
|
|
if (useFastRemove && frag.resetListeners) for (const fn of frag.resetListeners) fn();
|
|||
|
|
if (oldKeyIndexMap.size) for (const leftoverIndex of oldKeyIndexMap.values()) unmount(oldBlocks[leftoverIndex], !(useFastRemove && canUseFastRemove));
|
|||
|
|
if (useFastRemove && canUseFastRemove) {
|
|||
|
|
parent.textContent = "";
|
|||
|
|
parent.appendChild(parentAnchor);
|
|||
|
|
}
|
|||
|
|
let sequence;
|
|||
|
|
const hasReuse = mountCounter !== queuedLength;
|
|||
|
|
if (hasReuse) {
|
|||
|
|
sequence = planMoves(queuedIndices, sources, e2, e3);
|
|||
|
|
queuedLength = queuedIndices.length;
|
|||
|
|
}
|
|||
|
|
const allKept = hasReuse && sequence === void 0;
|
|||
|
|
let sequenceEnd = sequence ? sequence.length - 1 : -1;
|
|||
|
|
let scanFrom = newLength;
|
|||
|
|
let cachedAnchor;
|
|||
|
|
for (let q = queuedLength - 1; q >= 0; q--) {
|
|||
|
|
const index = queuedIndices[q];
|
|||
|
|
let isKept = allKept && sources[q] !== 0;
|
|||
|
|
if (sequenceEnd >= 0 && sequence[sequenceEnd] === q) {
|
|||
|
|
sequenceEnd--;
|
|||
|
|
isKept = sources[q] !== 0;
|
|||
|
|
}
|
|||
|
|
if (isKept) continue;
|
|||
|
|
let anchorNode;
|
|||
|
|
for (let i = index + 1; i < scanFrom; i++) {
|
|||
|
|
const node = getBlockFirstNode(newBlocks[i].nodes);
|
|||
|
|
if (node && node.parentNode === parent) {
|
|||
|
|
anchorNode = node;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (anchorNode === void 0) {
|
|||
|
|
if (cachedAnchor === void 0) cachedAnchor = parentAnchor;
|
|||
|
|
anchorNode = cachedAnchor;
|
|||
|
|
}
|
|||
|
|
scanFrom = index + 1;
|
|||
|
|
cachedAnchor = anchorNode;
|
|||
|
|
if (pureInsert) {
|
|||
|
|
for (let i = 0; i < queuedLength; i++) mount(source, queuedIndices[i], anchorNode);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
const block = newBlocks[index];
|
|||
|
|
if (block !== void 0) move(block.nodes, parent, anchorNode, 2);
|
|||
|
|
else mount(source, index, anchorNode);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
oldBlocks = newBlocks;
|
|||
|
|
frag.nodes = parentAnchor ? [newBlocks, parentAnchor] : [newBlocks];
|
|||
|
|
if (wasMounted && frag.u) for (const fn of frag.u) fn(frag.nodes);
|
|||
|
|
setActiveSub(prevSub);
|
|||
|
|
};
|
|||
|
|
const needKey = renderItem.length > 1;
|
|||
|
|
const needIndex = renderItem.length > 2;
|
|||
|
|
const insertForBlock = isSingleNode ? (block, anchor) => insertNode(block.nodes, parent, anchor) : isFragment ? (block, anchor) => insertFragment(block.nodes, parent, anchor) : (block, anchor) => insert(block.nodes, parent, anchor);
|
|||
|
|
const removeForBlock = isSingleNode ? (block) => removeNode(block.nodes, parent) : isFragment ? (block) => removeFragment(block.nodes, parent) : (block) => remove(block.nodes, parent);
|
|||
|
|
const mount = (source, idx, anchor) => {
|
|||
|
|
const keys = source.keys;
|
|||
|
|
const itemRef = shallowRef$1(getItemValue(source, idx));
|
|||
|
|
const keyRef = needKey ? shallowRef$1(keys ? keys[idx] : idx) : void 0;
|
|||
|
|
const indexRef = needIndex ? shallowRef$1(keys ? idx : void 0) : void 0;
|
|||
|
|
let nodes;
|
|||
|
|
const scope = new EffectScope$1(true);
|
|||
|
|
const prevScope = setCurrentScope(scope);
|
|||
|
|
let ok = false;
|
|||
|
|
try {
|
|||
|
|
nodes = renderItem(itemRef, keyRef, indexRef);
|
|||
|
|
ok = true;
|
|||
|
|
} finally {
|
|||
|
|
setCurrentScope(prevScope);
|
|||
|
|
if (!ok) scope.stop();
|
|||
|
|
}
|
|||
|
|
const block = newBlocks[idx] = new ForBlock(nodes, scope, itemRef, keyRef, indexRef, newKeys ? newKeys[idx] : void 0);
|
|||
|
|
if (isTransitionEnabled && frag.$transition) {
|
|||
|
|
const hooks = frag.$transition;
|
|||
|
|
if (hooks.applyGroup) hooks.applyGroup(block, hooks.props, hooks.state, hooks.instance);
|
|||
|
|
else applyTransitionHooks(block.nodes, hooks);
|
|||
|
|
}
|
|||
|
|
const bm = frag.bm;
|
|||
|
|
if (bm) for (let i = 0; i < bm.length; i++) bm[i](block.nodes);
|
|||
|
|
if (parent) insertForBlock(block, anchor);
|
|||
|
|
return block;
|
|||
|
|
};
|
|||
|
|
const mountAll = (source, newLength) => {
|
|||
|
|
for (let i = 0; i < newLength; i++) mount(source, i, parentAnchor);
|
|||
|
|
};
|
|||
|
|
const updateAt = (block, source, idx) => {
|
|||
|
|
const keys = source.keys;
|
|||
|
|
update(block, getItemValue(source, idx), keys ? keys[idx] : idx, keys ? idx : void 0);
|
|||
|
|
};
|
|||
|
|
function hydrateList(source, newLength) {
|
|||
|
|
const claim = hydrationClaim;
|
|||
|
|
let exitHydrationBoundary;
|
|||
|
|
const reuseBoundaryClose = (close) => {
|
|||
|
|
parentAnchor = claimAnchor(close);
|
|||
|
|
exitHydrationBoundary = enterHydrationBoundary(parentAnchor);
|
|||
|
|
};
|
|||
|
|
try {
|
|||
|
|
for (let i = 0; i < newLength; i++) {
|
|||
|
|
const node = currentHydrationNode;
|
|||
|
|
let nextNode = null;
|
|||
|
|
if (isComment(node, "]")) nextNode = claimAnchor(node);
|
|||
|
|
else if (wrappedRows && isComment(node, "[")) {
|
|||
|
|
nextNode = nextLogicalSibling(node);
|
|||
|
|
setCurrentHydrationNode(node.nextSibling);
|
|||
|
|
}
|
|||
|
|
mount(source, i, parentAnchor);
|
|||
|
|
if (nextNode) setCurrentHydrationNode(nextNode);
|
|||
|
|
}
|
|||
|
|
if (claim.start) {
|
|||
|
|
reuseBoundaryClose(locateClaimedEnd(claim.start));
|
|||
|
|
if (_insertionParent) {
|
|||
|
|
const idx = _insertionAnchor ? _insertionParent.$llc === _insertionAnchor ? _insertionParent.$lli : void 0 : _insertionIndex || 0;
|
|||
|
|
if (idx !== void 0) setLastLocatedLogicalChild(_insertionParent, parentAnchor, idx);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
const close = currentHydrationNode;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && !isComment(close, "]")) throw new Error(`v-for fragment anchor node was not found. this is likely a Vue internal bug.`);
|
|||
|
|
reuseBoundaryClose(close);
|
|||
|
|
}
|
|||
|
|
} finally {
|
|||
|
|
exitHydrationBoundary && exitHydrationBoundary();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
const update = ({ itemRef, keyRef, indexRef }, newItem, newKey, newIndex) => {
|
|||
|
|
if (newItem !== itemRef.value) itemRef.value = newItem;
|
|||
|
|
if (keyRef && newKey !== void 0 && newKey !== keyRef.value) keyRef.value = newKey;
|
|||
|
|
if (indexRef && newIndex !== indexRef.value) indexRef.value = newIndex;
|
|||
|
|
};
|
|||
|
|
const unmount = (block, doRemove = true) => {
|
|||
|
|
if (!isComponent) block.scope.stop();
|
|||
|
|
if (doRemove) removeForBlock(block);
|
|||
|
|
else if (isInteropEnabled) unmountVDOM(block);
|
|||
|
|
if (isComponent) block.scope.stop();
|
|||
|
|
};
|
|||
|
|
if (flags & 4) renderList();
|
|||
|
|
else renderEffect(() => {
|
|||
|
|
if (!isMounted) return renderList();
|
|||
|
|
withRenderContext(ctx, renderList);
|
|||
|
|
});
|
|||
|
|
if (isHydrating$1 && currentHydrationNode === parentAnchor) advanceHydrationNode(parentAnchor);
|
|||
|
|
finishBlockCreation(frag, parentAnchor, hydrationCursor, _insertionParent, _insertionAnchor);
|
|||
|
|
return frag;
|
|||
|
|
};
|
|||
|
|
/**
|
|||
|
|
* Builds a key-indexed selector that activates only the opers registered with
|
|||
|
|
* the key matching the current source value. Compared to letting each item
|
|||
|
|
* subscribe directly, this keeps re-renders on source change O(2) instead of
|
|||
|
|
* O(N) (only previous and new active item re-run).
|
|||
|
|
*
|
|||
|
|
* Selector cleanup follows the current scope. Per-item teardown is auto-wired
|
|||
|
|
* via `onScopeDispose` so callers (typically v-for item scopes) don't need
|
|||
|
|
* explicit deregistration. For bulk-reset hot paths, attach the selector to
|
|||
|
|
* the v-for via `frag.onReset(selector.reset)` to skip the per-item Map ops.
|
|||
|
|
*/
|
|||
|
|
function createSelector(source) {
|
|||
|
|
const operMap = /* @__PURE__ */ new Map();
|
|||
|
|
let activeKey = source();
|
|||
|
|
let activeOpers;
|
|||
|
|
let pendingKey = activeKey;
|
|||
|
|
let pending = false;
|
|||
|
|
let generation = 0;
|
|||
|
|
watch$1(source, (newValue) => {
|
|||
|
|
pendingKey = newValue;
|
|||
|
|
if (pending) return;
|
|||
|
|
pending = true;
|
|||
|
|
if (activeOpers !== void 0) for (const oper of activeOpers) oper();
|
|||
|
|
queuePostFlushCb(() => {
|
|||
|
|
pending = false;
|
|||
|
|
activeKey = pendingKey;
|
|||
|
|
activeOpers = operMap.get(activeKey);
|
|||
|
|
if (activeOpers !== void 0) for (const oper of activeOpers) oper();
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
const register = (key, oper) => {
|
|||
|
|
oper();
|
|||
|
|
let opers = operMap.get(key);
|
|||
|
|
if (opers !== void 0) opers.push(oper);
|
|||
|
|
else {
|
|||
|
|
opers = [oper];
|
|||
|
|
operMap.set(key, opers);
|
|||
|
|
if (key === activeKey) activeOpers = opers;
|
|||
|
|
}
|
|||
|
|
const myGen = generation;
|
|||
|
|
onScopeDispose$1(() => {
|
|||
|
|
if (myGen !== generation) return;
|
|||
|
|
const list = operMap.get(key);
|
|||
|
|
if (list === void 0) return;
|
|||
|
|
if (list.length === 1) {
|
|||
|
|
operMap.delete(key);
|
|||
|
|
if (key === activeKey) activeOpers = void 0;
|
|||
|
|
} else {
|
|||
|
|
const idx = list.indexOf(oper);
|
|||
|
|
if (idx !== -1) list.splice(idx, 1);
|
|||
|
|
}
|
|||
|
|
}, true);
|
|||
|
|
};
|
|||
|
|
register.reset = () => {
|
|||
|
|
operMap.clear();
|
|||
|
|
activeOpers = void 0;
|
|||
|
|
generation++;
|
|||
|
|
};
|
|||
|
|
return register;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Decides which reused blocks may stay where they are: the longest increasing
|
|||
|
|
* subsequence of their old indices is already in relative order, so only the
|
|||
|
|
* blocks outside it need a DOM move. Returns that subsequence as indices into
|
|||
|
|
* `sources`, or `undefined` when no reused block has to move at all.
|
|||
|
|
*
|
|||
|
|
* Two planners, picked by how dense the change is across the range it touches:
|
|||
|
|
*
|
|||
|
|
* - dense (the queued indices cover at least half of the range they span):
|
|||
|
|
* pull the in-place matches in that range into the plan too and run an
|
|||
|
|
* unbounded LIS, which is move-count minimal like vdom's. The range is at
|
|||
|
|
* most `2 * queuedIndices.length` wide here, so this stays O(queued).
|
|||
|
|
* - sparse (a couple of rows moved across an otherwise untouched list, e.g. a
|
|||
|
|
* far swap): keep the in-place matches pinned, which costs nothing but
|
|||
|
|
* bounds each segment's LIS by its stationary neighbours. Not minimal in
|
|||
|
|
* general, but it never walks the untouched majority.
|
|||
|
|
*
|
|||
|
|
* Both arrays are expanded in place on the dense path.
|
|||
|
|
*/
|
|||
|
|
function planMoves(queuedIndices, sources, e2, e3) {
|
|||
|
|
let queuedLength = queuedIndices.length;
|
|||
|
|
const denseLength = e3 - queuedIndices[0];
|
|||
|
|
const isDense = queuedLength * 2 >= denseLength;
|
|||
|
|
let moved = false;
|
|||
|
|
let maxSource = 0;
|
|||
|
|
if (isDense) {
|
|||
|
|
let read = queuedLength - 1;
|
|||
|
|
queuedIndices.length = sources.length = denseLength;
|
|||
|
|
for (let write = denseLength - 1, index = e3 - 1; write >= 0; write--, index--) {
|
|||
|
|
if (read >= 0 && queuedIndices[read] === index) sources[write] = sources[read--];
|
|||
|
|
else sources[write] = index + 1;
|
|||
|
|
queuedIndices[write] = index;
|
|||
|
|
}
|
|||
|
|
queuedLength = denseLength;
|
|||
|
|
for (let q = 0; q < queuedLength; q++) {
|
|||
|
|
const value = sources[q];
|
|||
|
|
if (value !== 0) {
|
|||
|
|
if (value < maxSource) moved = true;
|
|||
|
|
else maxSource = value;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
let seg = 0;
|
|||
|
|
while (seg < queuedLength) {
|
|||
|
|
let segEnd = seg;
|
|||
|
|
while (segEnd + 1 < queuedLength && queuedIndices[segEnd + 1] === queuedIndices[segEnd] + 1) segEnd++;
|
|||
|
|
const lowerBound = queuedIndices[seg] - 1;
|
|||
|
|
const nextIndex = queuedIndices[segEnd] + 1;
|
|||
|
|
const upperBound = nextIndex < e3 ? nextIndex : e2;
|
|||
|
|
for (let q = seg; q <= segEnd; q++) {
|
|||
|
|
const value = sources[q];
|
|||
|
|
const oldIndex = value - 1;
|
|||
|
|
if (oldIndex <= lowerBound || oldIndex >= upperBound) sources[q] = 0;
|
|||
|
|
else if (value < maxSource) moved = true;
|
|||
|
|
else maxSource = value;
|
|||
|
|
}
|
|||
|
|
seg = segEnd + 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return moved ? getSequence(sources) : void 0;
|
|||
|
|
}
|
|||
|
|
function stopBlockScopes(blocks) {
|
|||
|
|
for (let i = 0; i < blocks.length; i++) {
|
|||
|
|
const block = blocks[i];
|
|||
|
|
if (block) {
|
|||
|
|
const scope = block.scope;
|
|||
|
|
if (scope) scope.stop();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function isSameMapKey(a, b) {
|
|||
|
|
return Object.is(a, b) || a === 0 && b === 0;
|
|||
|
|
}
|
|||
|
|
function createForSlots(rawSource, renderSlot, getName, getKey) {
|
|||
|
|
let oldRecords = [];
|
|||
|
|
const needKey = renderSlot.length > 1;
|
|||
|
|
const needIndex = renderSlot.length > 2;
|
|||
|
|
const update = (record, [item, key, index]) => {
|
|||
|
|
if (!Object.is(record.itemRef.value, item)) record.itemRef.value = item;
|
|||
|
|
if (record.keyRef && !Object.is(record.keyRef.value, key)) record.keyRef.value = key;
|
|||
|
|
if (record.indexRef && !Object.is(record.indexRef.value, index)) record.indexRef.value = index;
|
|||
|
|
};
|
|||
|
|
return () => {
|
|||
|
|
const source = normalizeSource(rawSource());
|
|||
|
|
const sourceLength = source.values.length;
|
|||
|
|
const names = new Array(sourceLength);
|
|||
|
|
const identities = getKey ? new Array(sourceLength) : names;
|
|||
|
|
const items = new Array(sourceLength);
|
|||
|
|
let sameResolution = sourceLength === oldRecords.length;
|
|||
|
|
for (let i = 0; i < sourceLength; i++) {
|
|||
|
|
const item = items[i] = getItem(source, i);
|
|||
|
|
const name = names[i] = String(getName(...item));
|
|||
|
|
const identity = identities[i] = getKey ? getKey(...item) : name;
|
|||
|
|
if (sameResolution && (!isSameMapKey(oldRecords[i].rawIdentity, identity) || oldRecords[i].name !== name)) sameResolution = false;
|
|||
|
|
}
|
|||
|
|
if (sameResolution) {
|
|||
|
|
const prevSub = setActiveSub();
|
|||
|
|
for (let i = sourceLength - 1; i >= 0; i--) update(oldRecords[i], items[i]);
|
|||
|
|
setActiveSub(prevSub);
|
|||
|
|
return oldRecords;
|
|||
|
|
}
|
|||
|
|
const oldByIdentity = /* @__PURE__ */ new Map();
|
|||
|
|
for (let i = 0; i < oldRecords.length; i++) oldByIdentity.set(oldRecords[i].rawIdentity, oldRecords[i]);
|
|||
|
|
const records = new Array(sourceLength);
|
|||
|
|
const prevSub = setActiveSub();
|
|||
|
|
for (let i = sourceLength - 1; i >= 0; i--) {
|
|||
|
|
const slotItem = items[i];
|
|||
|
|
const rawIdentity = identities[i];
|
|||
|
|
let record = oldByIdentity.get(rawIdentity);
|
|||
|
|
if (record) {
|
|||
|
|
oldByIdentity.delete(rawIdentity);
|
|||
|
|
update(record, slotItem);
|
|||
|
|
record.name = names[i];
|
|||
|
|
} else {
|
|||
|
|
const [item, key, index] = slotItem;
|
|||
|
|
const itemRef = shallowRef$1(item);
|
|||
|
|
const keyRef = needKey ? shallowRef$1(key) : void 0;
|
|||
|
|
const indexRef = needIndex ? shallowRef$1(index) : void 0;
|
|||
|
|
record = {
|
|||
|
|
rawIdentity,
|
|||
|
|
itemRef,
|
|||
|
|
keyRef,
|
|||
|
|
indexRef,
|
|||
|
|
name: names[i],
|
|||
|
|
fn: renderSlot(itemRef, keyRef, indexRef),
|
|||
|
|
key: itemRef
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
records[i] = record;
|
|||
|
|
}
|
|||
|
|
setActiveSub(prevSub);
|
|||
|
|
oldRecords = records;
|
|||
|
|
return records;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
function normalizeSource(source) {
|
|||
|
|
let values = source;
|
|||
|
|
let needsWrap = false;
|
|||
|
|
let isReadonlySource = false;
|
|||
|
|
let keys;
|
|||
|
|
if (isArray(source)) {
|
|||
|
|
if (isReactive(source)) {
|
|||
|
|
needsWrap = !isShallow(source);
|
|||
|
|
values = shallowReadArray(source);
|
|||
|
|
isReadonlySource = isReadonly(source);
|
|||
|
|
}
|
|||
|
|
} else if (isString(source)) values = source.split("");
|
|||
|
|
else if (typeof source === "number") {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && (!Number.isInteger(source) || source < 0)) {
|
|||
|
|
warn(`The v-for range expects a positive integer value but got ${source}.`);
|
|||
|
|
values = [];
|
|||
|
|
} else {
|
|||
|
|
values = new Array(source);
|
|||
|
|
for (let i = 0; i < source; i++) values[i] = i + 1;
|
|||
|
|
}
|
|||
|
|
} else if (isObject(source)) {
|
|||
|
|
if (source[Symbol.iterator]) values = Array.from(source);
|
|||
|
|
else {
|
|||
|
|
keys = Object.keys(source);
|
|||
|
|
values = new Array(keys.length);
|
|||
|
|
for (let i = 0, l = keys.length; i < l; i++) values[i] = source[keys[i]];
|
|||
|
|
}
|
|||
|
|
} else values = [];
|
|||
|
|
return {
|
|||
|
|
values,
|
|||
|
|
needsWrap,
|
|||
|
|
isReadonlySource,
|
|||
|
|
keys
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
function getItemValue({ values, needsWrap, isReadonlySource }, idx) {
|
|||
|
|
return needsWrap ? isReadonlySource ? toReadonly(toReactive(values[idx])) : toReactive(values[idx]) : values[idx];
|
|||
|
|
}
|
|||
|
|
function getItem(source, idx) {
|
|||
|
|
const value = getItemValue(source, idx);
|
|||
|
|
if (source.keys) return [
|
|||
|
|
value,
|
|||
|
|
source.keys[idx],
|
|||
|
|
idx
|
|||
|
|
];
|
|||
|
|
else return [
|
|||
|
|
value,
|
|||
|
|
idx,
|
|||
|
|
void 0
|
|||
|
|
];
|
|||
|
|
}
|
|||
|
|
function getRestElement(val, keys) {
|
|||
|
|
const res = {};
|
|||
|
|
for (const key of Object.keys(val)) if (!keys.includes(key)) res[key] = val[key];
|
|||
|
|
return res;
|
|||
|
|
}
|
|||
|
|
function getDefaultValue(val, getDefaultVal) {
|
|||
|
|
return val === void 0 ? getDefaultVal() : val;
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/apiTemplateRef.ts
|
|||
|
|
function getTemplateRefUpdateFragment(el) {
|
|||
|
|
if (isDynamicFragment(el)) return el;
|
|||
|
|
if (isAsyncComponentEnabled && isVaporComponent(el) && isAsyncWrapper(el)) return el.block;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Async/dynamic component targets swap their inner block on update, so the ref
|
|||
|
|
* has to be re-applied after the fragment settles. Registration is idempotent
|
|||
|
|
* per (el, owner) pair: `getTemplateRefUpdateFragment` reads the async
|
|||
|
|
* wrapper's mutable `block`, so the resolved fragment is compared by identity
|
|||
|
|
* rather than with a "registered once" flag.
|
|||
|
|
*/
|
|||
|
|
function registerFragmentRefUpdate(el, registeredFrag, reapply) {
|
|||
|
|
const frag = getTemplateRefUpdateFragment(el);
|
|||
|
|
if (frag && registeredFrag !== frag) {
|
|||
|
|
if (isDynamicFragment(el)) {
|
|||
|
|
let nestedFrag;
|
|||
|
|
const onAsyncUpdate = () => {
|
|||
|
|
const inner = frag.nodes;
|
|||
|
|
if (isVaporComponent(inner) && inner.block === nestedFrag && !inner.isDeactivated && !inner.isUnmounted) reapply();
|
|||
|
|
};
|
|||
|
|
const onUpdate = () => {
|
|||
|
|
nestedFrag = syncNestedAsyncRefUpdate(frag, nestedFrag, onAsyncUpdate);
|
|||
|
|
reapply();
|
|||
|
|
};
|
|||
|
|
(frag.u || (frag.u = [])).push(onUpdate);
|
|||
|
|
onScopeDispose$1(() => {
|
|||
|
|
remove$1(frag.u, onUpdate);
|
|||
|
|
if (nestedFrag) {
|
|||
|
|
remove$1(nestedFrag.u, onAsyncUpdate);
|
|||
|
|
nestedFrag = void 0;
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
nestedFrag = syncNestedAsyncRefUpdate(frag, void 0, onAsyncUpdate);
|
|||
|
|
} else (frag.u || (frag.u = [])).push(() => {
|
|||
|
|
if (isVaporComponent(el) && el.isDeactivated) return;
|
|||
|
|
reapply();
|
|||
|
|
});
|
|||
|
|
return frag;
|
|||
|
|
}
|
|||
|
|
return registeredFrag;
|
|||
|
|
}
|
|||
|
|
function syncNestedAsyncRefUpdate(frag, registeredFrag, onUpdate) {
|
|||
|
|
const inner = frag.nodes;
|
|||
|
|
const next = isAsyncComponentEnabled && isVaporComponent(inner) && isAsyncWrapper(inner) && isDynamicFragment(inner.block) ? inner.block : void 0;
|
|||
|
|
if (next !== registeredFrag) {
|
|||
|
|
if (registeredFrag) remove$1(registeredFrag.u, onUpdate);
|
|||
|
|
if (next) (next.u || (next.u = [])).push(onUpdate);
|
|||
|
|
}
|
|||
|
|
return next;
|
|||
|
|
}
|
|||
|
|
function ensureCleanup(el) {
|
|||
|
|
let cleanupRef = refCleanups.get(el);
|
|||
|
|
if (!cleanupRef) {
|
|||
|
|
refCleanups.set(el, cleanupRef = { fn: NOOP });
|
|||
|
|
onScopeDispose$1(() => {
|
|||
|
|
invalidatePendingRef(el);
|
|||
|
|
cleanupRef.fn();
|
|||
|
|
refCleanups.delete(el);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
return cleanupRef;
|
|||
|
|
}
|
|||
|
|
function createTemplateRefSetter() {
|
|||
|
|
const instance = getScopeOwner();
|
|||
|
|
const stateMap = /* @__PURE__ */ new WeakMap();
|
|||
|
|
return (el, ref, refFor, refKey) => {
|
|||
|
|
let state = stateMap.get(el);
|
|||
|
|
if (!state) stateMap.set(el, state = {
|
|||
|
|
ref,
|
|||
|
|
suspense: currentRenderContext.suspense
|
|||
|
|
});
|
|||
|
|
setTemplateRefWithState(instance, el, state, ref, refFor, refKey);
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
function setTemplateRefWithState(instance, el, state, ref, refFor, refKey) {
|
|||
|
|
state.ref = ref;
|
|||
|
|
state.refFor = refFor;
|
|||
|
|
state.refKey = refKey;
|
|||
|
|
state.registeredFrag = registerFragmentRefUpdate(el, state.registeredFrag, () => {
|
|||
|
|
setRef$1(instance, state.suspense, el, state.ref, state.oldRef, state.refFor, state.refKey, state.oldRefKey);
|
|||
|
|
state.oldRef = state.ref;
|
|||
|
|
state.oldRefKey = state.ref != null ? state.refKey : void 0;
|
|||
|
|
});
|
|||
|
|
setRef$1(instance, state.suspense, el, ref, state.oldRef, refFor, refKey, state.oldRefKey);
|
|||
|
|
state.oldRef = ref;
|
|||
|
|
state.oldRefKey = ref != null ? refKey : void 0;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Static refs never change value, so they need no old-ref tracking and no
|
|||
|
|
* per-element state - only the fragment re-apply hook shared with the
|
|||
|
|
* stateful path.
|
|||
|
|
*/
|
|||
|
|
function setStaticTemplateRef(el, ref, refFor, refKey) {
|
|||
|
|
const instance = getScopeOwner();
|
|||
|
|
const suspense = currentRenderContext.suspense;
|
|||
|
|
setRef$1(instance, suspense, el, ref, void 0, refFor, refKey);
|
|||
|
|
registerFragmentRefUpdate(el, void 0, () => {
|
|||
|
|
setRef$1(instance, suspense, el, ref, ref, refFor, refKey);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
function setTemplateRefBinding(el, getter, refFor, refKey) {
|
|||
|
|
const instance = getScopeOwner();
|
|||
|
|
let state;
|
|||
|
|
renderEffect(() => {
|
|||
|
|
const ref = getter();
|
|||
|
|
if (!state) state = {
|
|||
|
|
ref,
|
|||
|
|
suspense: currentRenderContext.suspense
|
|||
|
|
};
|
|||
|
|
setTemplateRefWithState(instance, el, state, ref, refFor, refKey);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Function for handling a template ref
|
|||
|
|
*/
|
|||
|
|
function setRef$1(instance, suspense, el, ref, oldRef, refFor = false, refKey, oldRefKey) {
|
|||
|
|
if (!instance || instance.isUnmounted) return;
|
|||
|
|
const setupState = !!(process.env.NODE_ENV !== "production") ? instance.setupState || {} : null;
|
|||
|
|
const refValue = getRefValue(el);
|
|||
|
|
if (isInteropEnabled) {
|
|||
|
|
const target = isFragment(el) && el.setRef ? el : refValue && isFragment(refValue) && refValue.setRef ? refValue : null;
|
|||
|
|
if (target) {
|
|||
|
|
target.setRef(instance, ref, refFor, refKey);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
const refs = instance.refs === EMPTY_OBJ ? instance.refs = {} : instance.refs;
|
|||
|
|
const canSetSetupRef = !!(process.env.NODE_ENV !== "production") ? createCanSetSetupRefChecker(setupState, refs) : NO;
|
|||
|
|
const canSetRef = (ref, key) => {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && knownTemplateRefs.has(ref)) return false;
|
|||
|
|
if (key && isTemplateRefKey(refs, key)) return false;
|
|||
|
|
return true;
|
|||
|
|
};
|
|||
|
|
if (oldRef != null && oldRef !== ref) {
|
|||
|
|
invalidatePendingRef(el);
|
|||
|
|
if (isString(oldRef)) {
|
|||
|
|
refs[oldRef] = null;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && canSetSetupRef(oldRef)) setupState[oldRef] = null;
|
|||
|
|
} else if (isRef(oldRef)) {
|
|||
|
|
if (canSetRef(oldRef, oldRefKey)) oldRef.value = null;
|
|||
|
|
if (oldRefKey) refs[oldRefKey] = null;
|
|||
|
|
} else if (isFunction(oldRef) && isDynamicFragment(el)) callWithErrorHandling(oldRef, instance, 12, [null, refs]);
|
|||
|
|
} else if (oldRef != null && isDynamicFragment(el)) {
|
|||
|
|
if (isFunction(oldRef)) callWithErrorHandling(oldRef, instance, 12, [null, refs]);
|
|||
|
|
else if (refFor) unsetRef(el);
|
|||
|
|
}
|
|||
|
|
if (ref == null) return;
|
|||
|
|
if (isFunction(ref)) {
|
|||
|
|
const invokeRefSetter = (value) => {
|
|||
|
|
callWithErrorHandling(ref, instance, 12, [value, refs]);
|
|||
|
|
};
|
|||
|
|
invokeRefSetter(refValue);
|
|||
|
|
ensureCleanup(el).fn = () => invokeRefSetter(null);
|
|||
|
|
} else {
|
|||
|
|
const _isString = isString(ref);
|
|||
|
|
const _isRef = isRef(ref);
|
|||
|
|
let existing;
|
|||
|
|
if (_isString || _isRef) {
|
|||
|
|
const doSet = () => {
|
|||
|
|
if (refFor) {
|
|||
|
|
if (refValue == null) return;
|
|||
|
|
existing = _isString ? !!(process.env.NODE_ENV !== "production") && canSetSetupRef(ref) ? setupState[ref] : refs[ref] : canSetRef(ref) || !refKey ? ref.value : refs[refKey];
|
|||
|
|
if (!isArray(existing)) {
|
|||
|
|
existing = [refValue];
|
|||
|
|
if (_isString) {
|
|||
|
|
refs[ref] = existing;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && canSetSetupRef(ref)) {
|
|||
|
|
setupState[ref] = refs[ref];
|
|||
|
|
existing = setupState[ref];
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
if (canSetRef(ref, refKey)) ref.value = existing;
|
|||
|
|
if (refKey) refs[refKey] = existing;
|
|||
|
|
}
|
|||
|
|
} else if (!existing.includes(refValue)) existing.push(refValue);
|
|||
|
|
} else if (_isString) {
|
|||
|
|
refs[ref] = refValue;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && canSetSetupRef(ref)) setupState[ref] = refValue;
|
|||
|
|
} else if (_isRef) {
|
|||
|
|
if (canSetRef(ref, refKey)) ref.value = refValue;
|
|||
|
|
if (refKey) refs[refKey] = refValue;
|
|||
|
|
} else if (!!(process.env.NODE_ENV !== "production")) warn("Invalid template ref type:", ref, `(${typeof ref})`);
|
|||
|
|
};
|
|||
|
|
const cleanup = ensureCleanup(el);
|
|||
|
|
cleanup.fn = () => {
|
|||
|
|
if (refFor) {
|
|||
|
|
if (isArray(existing)) remove$1(existing, refValue);
|
|||
|
|
} else if (_isString) {
|
|||
|
|
refs[ref] = null;
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && canSetSetupRef(ref)) setupState[ref] = null;
|
|||
|
|
} else if (_isRef) {
|
|||
|
|
if (canSetRef(ref, refKey)) ref.value = null;
|
|||
|
|
if (refKey) refs[refKey] = null;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
invalidatePendingRef(el);
|
|||
|
|
if (refValue != null) {
|
|||
|
|
const job = () => {
|
|||
|
|
doSet();
|
|||
|
|
if (cleanup.job === job) cleanup.job = void 0;
|
|||
|
|
};
|
|||
|
|
cleanup.job = job;
|
|||
|
|
queuePostRenderEffect(job, -1, suspense);
|
|||
|
|
} else doSet();
|
|||
|
|
} else if (!!(process.env.NODE_ENV !== "production")) warn("Invalid template ref type:", ref, `(${typeof ref})`);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
const getRefValue = (el) => {
|
|||
|
|
if (isVaporComponent(el)) {
|
|||
|
|
if (isAsyncComponentEnabled && isAsyncWrapper(el)) {
|
|||
|
|
const inner = getAsyncWrapperInner(el);
|
|||
|
|
if (inner === void 0) return null;
|
|||
|
|
return getRefValue(inner);
|
|||
|
|
}
|
|||
|
|
return getExposed(el) || el;
|
|||
|
|
} else if (isTeleportEnabled && isTeleportFragment(el)) return null;
|
|||
|
|
else if (isDynamicFragment(el)) {
|
|||
|
|
if (isArray(el.nodes)) return null;
|
|||
|
|
return getRefValue(el.nodes);
|
|||
|
|
}
|
|||
|
|
return el;
|
|||
|
|
};
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/apiCreateDynamicComponent.ts
|
|||
|
|
function createDynamicComponent(getter, rawProps, rawSlots, flags = 0, key) {
|
|||
|
|
const isSingleRoot = !!(flags & 1);
|
|||
|
|
const once = !!(flags & 2);
|
|||
|
|
const slotRoot = !!(flags & 4);
|
|||
|
|
const ns = flags & 8 ? 1 : flags & 16 ? 2 : void 0;
|
|||
|
|
const _insertionParent = insertionParent;
|
|||
|
|
const _insertionAnchor = insertionAnchor;
|
|||
|
|
if (!isHydrating$1) resetInsertionState();
|
|||
|
|
const normalizedRawSlots = normalizeRawSlots(rawSlots);
|
|||
|
|
const scopeOwner = getScopeOwner();
|
|||
|
|
let latestVNode;
|
|||
|
|
let patchVNode;
|
|||
|
|
const render = (value, resolved, appContext) => {
|
|||
|
|
if (isBlock(value)) return value;
|
|||
|
|
if (isInteropEnabled && appContext.vdom && isVNode(value)) {
|
|||
|
|
const vnodeFrag = appContext.vdom.mountVNode(latestVNode || resolved, currentInstance, isSingleRoot, rawProps, once);
|
|||
|
|
patchVNode = vnodeFrag.patchVNode;
|
|||
|
|
return vnodeFrag;
|
|||
|
|
}
|
|||
|
|
return createComponentWithFallback(resolved, rawProps, normalizedRawSlots, isSingleRoot, once, ns, appContext);
|
|||
|
|
};
|
|||
|
|
if (once) {
|
|||
|
|
const hydrationCursor = isHydrating$1 ? enterHydrationCursor() : null;
|
|||
|
|
const value = getter();
|
|||
|
|
const appContext = getAppContext();
|
|||
|
|
const block = render(value, resolveValue(value, appContext, scopeOwner), appContext);
|
|||
|
|
finishBlockCreation(block, void 0, hydrationCursor, _insertionParent, _insertionAnchor);
|
|||
|
|
return block;
|
|||
|
|
}
|
|||
|
|
const hydrationCursor = isHydrating$1 ? captureHydrationCursor() : null;
|
|||
|
|
const frag = new DynamicFragment(0, !!(process.env.NODE_ENV !== "production") ? "dynamic-component" : void 0, false, slotRoot, slotRoot ? () => {
|
|||
|
|
const nodes = frag.nodes;
|
|||
|
|
if (nodes instanceof Node) {
|
|||
|
|
const parent = nodes.parentNode;
|
|||
|
|
if (parent) removeNode(nodes, parent);
|
|||
|
|
}
|
|||
|
|
const anchorParent = frag.anchor.parentNode;
|
|||
|
|
if (anchorParent) removeNode(frag.anchor, anchorParent);
|
|||
|
|
} : void 0, _insertionAnchor);
|
|||
|
|
if (isHydrating$1) locateHydrationNode();
|
|||
|
|
let lastKey;
|
|||
|
|
let lastBranch;
|
|||
|
|
let branchToken;
|
|||
|
|
renderEffect(() => {
|
|||
|
|
const value = getter();
|
|||
|
|
let userKey = key ? key() : void 0;
|
|||
|
|
const appContext = getAppContext();
|
|||
|
|
let resolved = resolveValue(value, appContext, scopeOwner);
|
|||
|
|
if (resolved === NULL_DYNAMIC_COMPONENT) {
|
|||
|
|
if (isInteropEnabled) latestVNode = patchVNode = void 0;
|
|||
|
|
frag.update(void 0, resolved);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
let branchKey = resolved;
|
|||
|
|
if (isInteropEnabled && isVNode(resolved)) {
|
|||
|
|
if (key) {
|
|||
|
|
if (resolved.key !== (userKey == null ? null : userKey)) resolved = cloneVNode(resolved, { key: userKey });
|
|||
|
|
} else if (resolved.key != null) userKey = resolved.key;
|
|||
|
|
latestVNode = resolved;
|
|||
|
|
branchKey = resolved.type;
|
|||
|
|
}
|
|||
|
|
if (key || isInteropEnabled && userKey !== void 0) {
|
|||
|
|
if (userKey !== lastKey || branchKey !== lastBranch) {
|
|||
|
|
lastKey = userKey;
|
|||
|
|
lastBranch = branchKey;
|
|||
|
|
branchToken = {};
|
|||
|
|
}
|
|||
|
|
branchKey = branchToken;
|
|||
|
|
}
|
|||
|
|
if (branchKey === frag.current && !isHydrating$1) {
|
|||
|
|
if (isInteropEnabled && patchVNode && isVNode(resolved)) patchVNode(resolved);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (isInteropEnabled) latestVNode = patchVNode = void 0;
|
|||
|
|
frag.update(() => render(value, resolved, appContext), branchKey, false, userKey);
|
|||
|
|
});
|
|||
|
|
finishBlockCreation(frag, frag.anchor, hydrationCursor, _insertionParent, _insertionAnchor);
|
|||
|
|
return frag;
|
|||
|
|
}
|
|||
|
|
function getAppContext() {
|
|||
|
|
return currentInstance && currentInstance.appContext || emptyContext;
|
|||
|
|
}
|
|||
|
|
function resolveValue(value, appContext, scopeOwner) {
|
|||
|
|
if (isBlock(value) || isInteropEnabled && appContext.vdom && isVNode(value)) return value;
|
|||
|
|
const resolved = withScopeOwner(scopeOwner, () => resolveDynamicComponent(value));
|
|||
|
|
const type = typeof resolved;
|
|||
|
|
if (!resolved || type !== "string" && type !== "object" && type !== "function" && type !== "symbol") {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) warn(`Invalid dynamic component type: ${String(resolved)} (${type})`);
|
|||
|
|
return NULL_DYNAMIC_COMPONENT;
|
|||
|
|
}
|
|||
|
|
return resolved;
|
|||
|
|
}
|
|||
|
|
function withScopeOwner(owner, fn) {
|
|||
|
|
const prev = setCurrentRenderingInstance(owner);
|
|||
|
|
try {
|
|||
|
|
return fn();
|
|||
|
|
} finally {
|
|||
|
|
setCurrentRenderingInstance(prev);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/directives/vShow.ts
|
|||
|
|
/**
|
|||
|
|
* v-show is root-inherited state: it lands on the effective root element of
|
|||
|
|
* `target`, and any producer on the root chain (dynamic fragment branch,
|
|||
|
|
* interop subtree, pending async setup) can replace that root later. `apply`
|
|||
|
|
* resolves the root through the shared chain walker and registers itself on
|
|||
|
|
* every producer it passes, so a replacement root re-enters `apply` and
|
|||
|
|
* registers the producers inside it in turn.
|
|||
|
|
*/
|
|||
|
|
function applyVShow(target, source) {
|
|||
|
|
let value;
|
|||
|
|
let transition;
|
|||
|
|
let unresolved = false;
|
|||
|
|
let slotRoot = false;
|
|||
|
|
const visitor = {
|
|||
|
|
onComponent(instance) {
|
|||
|
|
if (isSuspenseEnabled && instance.asyncDep && !instance.asyncResolved) {
|
|||
|
|
if (!instance.$vshow) (instance.bm || (instance.bm = [])).push(() => apply(instance.block));
|
|||
|
|
unresolved = true;
|
|||
|
|
mark(instance);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
mark(instance);
|
|||
|
|
},
|
|||
|
|
onDynamicFragment(frag) {
|
|||
|
|
if (isSlotOutletFragment(frag)) return slotRoot = true;
|
|||
|
|
mark(frag);
|
|||
|
|
register(frag.bm || (frag.bm = []), apply);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
if (isInteropEnabled) visitor.onInteropFragment = (frag) => {
|
|||
|
|
if (isSlotOutletFragment(frag)) return slotRoot = true;
|
|||
|
|
mark(frag);
|
|||
|
|
if (isTransitionEnabled && frag.$transition) transition = frag.$transition;
|
|||
|
|
register(frag.u || (frag.u = []), apply);
|
|||
|
|
if (!isValidBlock(frag.nodes)) unresolved = true;
|
|||
|
|
};
|
|||
|
|
const apply = (nodes) => {
|
|||
|
|
transition = void 0;
|
|||
|
|
unresolved = slotRoot = false;
|
|||
|
|
const root = getRootElement(nodes, visitor);
|
|||
|
|
if (root) setDisplay(root, value, transition);
|
|||
|
|
else if (!!(process.env.NODE_ENV !== "production") && (slotRoot || !unresolved && isValidBlock(nodes))) warn("v-show used on component with non-single-element root node and will be ignored.");
|
|||
|
|
};
|
|||
|
|
renderEffect(() => {
|
|||
|
|
value = source();
|
|||
|
|
apply(target);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
function mark(block) {
|
|||
|
|
block.$vshow = true;
|
|||
|
|
}
|
|||
|
|
function register(hooks, hook) {
|
|||
|
|
if (!hooks.includes(hook)) hooks.push(hook);
|
|||
|
|
}
|
|||
|
|
function setDisplay(el, value, transition) {
|
|||
|
|
const hidden = !value;
|
|||
|
|
if (!(vShowOriginalDisplay in el)) {
|
|||
|
|
mark(el);
|
|||
|
|
el[vShowOriginalDisplay] = el.style.display === "none" ? "" : el.style.display;
|
|||
|
|
el[vShowHidden] = hidden;
|
|||
|
|
writeDisplay(el, value);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (el[vShowHidden] === hidden) return;
|
|||
|
|
el[vShowHidden] = hidden;
|
|||
|
|
const $transition = isTransitionEnabled ? el.$transition || transition : void 0;
|
|||
|
|
if ($transition) {
|
|||
|
|
const prevSub = setActiveSub();
|
|||
|
|
try {
|
|||
|
|
if (value) {
|
|||
|
|
$transition.beforeEnter(el);
|
|||
|
|
el.style.display = el[vShowOriginalDisplay];
|
|||
|
|
$transition.enter(el);
|
|||
|
|
} else if (el.isConnected) $transition.leave(el, () => {
|
|||
|
|
el.style.display = "none";
|
|||
|
|
});
|
|||
|
|
else el.style.display = "none";
|
|||
|
|
} finally {
|
|||
|
|
setActiveSub(prevSub);
|
|||
|
|
}
|
|||
|
|
} else writeDisplay(el, value);
|
|||
|
|
}
|
|||
|
|
function writeDisplay(el, value) {
|
|||
|
|
if ((!!(process.env.NODE_ENV !== "production") || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && isHydrating$1) {
|
|||
|
|
const hidden = el.style.display === "none";
|
|||
|
|
if (!value === hidden) return;
|
|||
|
|
const expected = value ? el[vShowOriginalDisplay] : "none";
|
|||
|
|
if (warnPropMismatch(el, "style", 3, `display: ${el.style.display}`, expected ? `display: ${expected}` : false)) logMismatchError();
|
|||
|
|
}
|
|||
|
|
el.style.display = value ? el[vShowOriginalDisplay] : "none";
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/directives/vModel.ts
|
|||
|
|
function ensureMounted(cb) {
|
|||
|
|
if (currentInstance.isMounted) cb();
|
|||
|
|
else onMounted(inOnce ? () => withOnce(cb) : cb);
|
|||
|
|
}
|
|||
|
|
const applyTextModel = (el, get, set, { trim, number, lazy } = {}) => {
|
|||
|
|
vModelTextInit(el, trim, number, lazy, set);
|
|||
|
|
ensureMounted(() => {
|
|||
|
|
let value;
|
|||
|
|
renderEffect(() => {
|
|||
|
|
vModelTextUpdate(el, value, value = get(), trim, number, lazy);
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
const applyCheckboxModel = (el, get, set) => {
|
|||
|
|
vModelCheckboxInit(el, set);
|
|||
|
|
ensureMounted(() => {
|
|||
|
|
let value;
|
|||
|
|
renderEffect(() => {
|
|||
|
|
vModelCheckboxUpdate(el, value, traverse(value = get()));
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
const applyRadioModel = (el, get, set) => {
|
|||
|
|
el.addEventListener("change", () => set(vModelGetValue(el)));
|
|||
|
|
ensureMounted(() => {
|
|||
|
|
let value;
|
|||
|
|
renderEffect(() => {
|
|||
|
|
if (value !== (value = get())) el.checked = looseEqual(value, vModelGetValue(el));
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
const applySelectModel = (el, get, set, modifiers) => {
|
|||
|
|
vModelSelectInit(el, get(), modifiers && modifiers.number, set);
|
|||
|
|
if (inOnce) {
|
|||
|
|
ensureMounted(() => vModelSetSelected(el, get()));
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
const instance = currentInstance;
|
|||
|
|
const update = () => vModelSetSelected(el, get());
|
|||
|
|
(instance.u || (instance.u = [])).unshift(update);
|
|||
|
|
onScopeDispose$1(() => remove$1(instance.u, update));
|
|||
|
|
ensureMounted(() => {
|
|||
|
|
update();
|
|||
|
|
renderEffect(() => traverse(get()));
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
const applyDynamicModel = (el, get, set, modifiers) => {
|
|||
|
|
let apply = applyTextModel;
|
|||
|
|
if (el.tagName === "SELECT") apply = applySelectModel;
|
|||
|
|
else if (el.tagName === "TEXTAREA") apply = applyTextModel;
|
|||
|
|
else if (el.type === "checkbox") apply = applyCheckboxModel;
|
|||
|
|
else if (el.type === "radio") apply = applyRadioModel;
|
|||
|
|
apply(el, get, set, modifiers);
|
|||
|
|
};
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/directives/custom.ts
|
|||
|
|
function withVaporDirectives(node, dirs) {
|
|||
|
|
if (node instanceof Element) {
|
|||
|
|
applyDirectivesToElement(node, dirs, currentInstance);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
const instance = currentInstance;
|
|||
|
|
const once = inOnce;
|
|||
|
|
let currentElement = null;
|
|||
|
|
let directiveScope;
|
|||
|
|
let disposed = false;
|
|||
|
|
let pending = false;
|
|||
|
|
let pendingSetups;
|
|||
|
|
const visitor = {
|
|||
|
|
onDynamicFragment: track,
|
|||
|
|
onComponent(block) {
|
|||
|
|
if (isSuspenseEnabled && block.asyncDep && !block.asyncResolved) {
|
|||
|
|
pending = true;
|
|||
|
|
if (!(pendingSetups || (pendingSetups = /* @__PURE__ */ new WeakSet())).has(block)) {
|
|||
|
|
pendingSetups.add(block);
|
|||
|
|
onBeforeMount(applyDirectives, block);
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
if (isAsyncComponentEnabled && isAsyncWrapper(block)) {
|
|||
|
|
const inner = block.block;
|
|||
|
|
if (isFragment(inner) && inner.nodes === EMPTY_BLOCK) pending = true;
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
excludeSlotOutlets: true
|
|||
|
|
};
|
|||
|
|
if (isInteropEnabled) visitor.onInteropFragment = (frag) => {
|
|||
|
|
if (frag.nodes === EMPTY_BLOCK) pending = true;
|
|||
|
|
track(frag);
|
|||
|
|
};
|
|||
|
|
function stopDirectiveScope() {
|
|||
|
|
if (directiveScope) {
|
|||
|
|
directiveScope.stop();
|
|||
|
|
directiveScope = void 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function track(frag) {
|
|||
|
|
const u = frag.u || (frag.u = []);
|
|||
|
|
if (u.includes(applyDirectives)) return;
|
|||
|
|
u.push(applyDirectives);
|
|||
|
|
if (isDynamicFragment(frag)) (frag.bu || (frag.bu = [])).push(() => {
|
|||
|
|
if (currentElement && getRootElement(frag.nodes) === currentElement) {
|
|||
|
|
currentElement = null;
|
|||
|
|
stopDirectiveScope();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
function applyDirectives() {
|
|||
|
|
if (disposed) return;
|
|||
|
|
pending = false;
|
|||
|
|
const element = getRootElement(node, visitor);
|
|||
|
|
if (!element && pending) {
|
|||
|
|
if (currentElement !== null) {
|
|||
|
|
currentElement = null;
|
|||
|
|
stopDirectiveScope();
|
|||
|
|
}
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (element === currentElement) return;
|
|||
|
|
currentElement = element;
|
|||
|
|
stopDirectiveScope();
|
|||
|
|
if (!element) {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) warn("Runtime directive used on component with non-element root node. The directives will not function as intended.");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
directiveScope = new EffectScope$1(true);
|
|||
|
|
const prev = setCurrentInstance(instance, directiveScope);
|
|||
|
|
try {
|
|||
|
|
if (once) withOnce(() => applyDirectivesToElement(element, dirs, instance));
|
|||
|
|
else applyDirectivesToElement(element, dirs, instance);
|
|||
|
|
} finally {
|
|||
|
|
restoreCurrentInstance(prev);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
onScopeDispose(() => {
|
|||
|
|
disposed = true;
|
|||
|
|
stopDirectiveScope();
|
|||
|
|
}, true);
|
|||
|
|
applyDirectives();
|
|||
|
|
}
|
|||
|
|
function applyDirectivesToElement(element, dirs, instance) {
|
|||
|
|
const hookCounts = !!(process.env.NODE_ENV !== "production") && instance ? countLifecycleHooks(instance) : null;
|
|||
|
|
for (const [dir, value, argument, modifiers] of dirs) if (dir) {
|
|||
|
|
if (!isFunction(dir)) {
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production")) warn(`Received a VDOM object directive` + (isObject(dir) ? ` (hooks: ${Object.keys(dir).join(", ")})` : ``) + " in a Vapor template. Vapor directives must be a function: (el, value, arg, modifiers) => cleanup.");
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
const ret = callWithErrorHandling(dir, instance, 8, [
|
|||
|
|
element,
|
|||
|
|
value,
|
|||
|
|
argument,
|
|||
|
|
modifiers
|
|||
|
|
]);
|
|||
|
|
if (ret) onScopeDispose(() => callWithErrorHandling(ret, instance, 8));
|
|||
|
|
}
|
|||
|
|
if (!!(process.env.NODE_ENV !== "production") && hookCounts) warnLifecycleHooks(instance, hookCounts);
|
|||
|
|
}
|
|||
|
|
const lifecycleHookNames = !!(process.env.NODE_ENV !== "production") ? {
|
|||
|
|
bm: "onBeforeMount",
|
|||
|
|
m: "onMounted",
|
|||
|
|
bu: "onBeforeUpdate",
|
|||
|
|
u: "onUpdated",
|
|||
|
|
bum: "onBeforeUnmount",
|
|||
|
|
um: "onUnmounted",
|
|||
|
|
da: "onDeactivated",
|
|||
|
|
a: "onActivated"
|
|||
|
|
} : {};
|
|||
|
|
function countLifecycleHooks(instance) {
|
|||
|
|
const counts = [];
|
|||
|
|
for (const key in lifecycleHookNames) {
|
|||
|
|
const hooks = instance[key];
|
|||
|
|
counts.push(hooks ? hooks.length : 0);
|
|||
|
|
}
|
|||
|
|
return counts;
|
|||
|
|
}
|
|||
|
|
function warnLifecycleHooks(instance, before) {
|
|||
|
|
let i = 0;
|
|||
|
|
for (const key in lifecycleHookNames) {
|
|||
|
|
const hooks = instance[key];
|
|||
|
|
if (hooks && hooks.length > before[i]) warn(`${lifecycleHookNames[key]}() was called inside a custom directive. Lifecycle hooks are not supported in Vapor directives: they attach to the component, not the element. Use watchPostEffect() for work that needs the element in the DOM, and return a cleanup function for teardown.`);
|
|||
|
|
i++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region packages/runtime-vapor/src/components/TransitionGroup.ts
|
|||
|
|
const positionMap = /* @__PURE__ */ new WeakMap();
|
|||
|
|
const newPositionMap = /* @__PURE__ */ new WeakMap();
|
|||
|
|
const trackedTransitionGroupOwners = /* @__PURE__ */ new WeakSet();
|
|||
|
|
const decorate = (t) => {
|
|||
|
|
delete t.props.mode;
|
|||
|
|
return t;
|
|||
|
|
};
|
|||
|
|
const VaporTransitionGroup = /*@__PURE__*/ decorate(/* @__PURE__ */ defineVaporComponent({
|
|||
|
|
name: "VaporTransitionGroup",
|
|||
|
|
props: /*@__PURE__*/ extend$1({}, TransitionPropsValidators, {
|
|||
|
|
tag: String,
|
|||
|
|
moveClass: String
|
|||
|
|
}),
|
|||
|
|
setup(props, { slots, expose }) {
|
|||
|
|
expose();
|
|||
|
|
if (!isTransitionEnabled) registerTransitionHooks(applyTransitionHooksImpl, () => false, () => false, () => false);
|
|||
|
|
const instance = currentInstance;
|
|||
|
|
const state = useTransitionState();
|
|||
|
|
let cssTransitionProps;
|
|||
|
|
const propsProxy = new Proxy({}, { get(_, key) {
|
|||
|
|
return cssTransitionProps[key];
|
|||
|
|
} });
|
|||
|
|
let prevChildren = [];
|
|||
|
|
let isUpdatePending = false;
|
|||
|
|
let isUpdatedPending = false;
|
|||
|
|
let slottedBlock = [];
|
|||
|
|
const beforeUpdate = () => {
|
|||
|
|
if (isUpdatePending) return;
|
|||
|
|
isUpdatePending = true;
|
|||
|
|
prevChildren = [];
|
|||
|
|
const children = resolveTransitionBlocks(slottedBlock, void 0, void 0, true);
|
|||
|
|
for (let i = 0; i < children.length; i++) {
|
|||
|
|
const child = children[i];
|
|||
|
|
const el = isValidTransitionBlock(child) && child.$transition ? getTransitionElement(child) : void 0;
|
|||
|
|
if (el && !el[vShowHidden]) {
|
|||
|
|
prevChildren.push(child);
|
|||
|
|
positionMap.set(child, el.getBoundingClientRect());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
const flushUpdated = () => {
|
|||
|
|
isUpdatedPending = false;
|
|||
|
|
if (!isUpdatePending) return;
|
|||
|
|
isUpdatePending = false;
|
|||
|
|
if (!prevChildren.length) return;
|
|||
|
|
const moveClass = props.moveClass || `${props.name || "v"}-move`;
|
|||
|
|
const firstChild = getFirstConnectedChild(prevChildren);
|
|||
|
|
if (!!!(firstChild && hasCSSTransform(firstChild, firstChild.parentNode, moveClass))) {
|
|||
|
|
prevChildren = [];
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
prevChildren.forEach((child) => {
|
|||
|
|
const el = getTransitionElement(child);
|
|||
|
|
if (el) callPendingCbs(el);
|
|||
|
|
});
|
|||
|
|
prevChildren.forEach(recordPosition);
|
|||
|
|
const movedChildren = prevChildren.filter(applyTranslation);
|
|||
|
|
forceReflow(firstChild);
|
|||
|
|
movedChildren.forEach((c) => handleMovedChildren(getTransitionElement(c), moveClass));
|
|||
|
|
prevChildren = [];
|
|||
|
|
};
|
|||
|
|
const updated = () => {
|
|||
|
|
if (!isUpdatePending || isUpdatedPending) return;
|
|||
|
|
isUpdatedPending = true;
|
|||
|
|
queuePostRenderEffect(flushUpdated, void 0, instance.suspense);
|
|||
|
|
};
|
|||
|
|
onBeforeUpdate(beforeUpdate);
|
|||
|
|
onUpdated(updated);
|
|||
|
|
const updateHooks = {
|
|||
|
|
beforeUpdate,
|
|||
|
|
updated
|
|||
|
|
};
|
|||
|
|
const tag = props.tag;
|
|||
|
|
let close = null;
|
|||
|
|
if (isHydrating$1) {
|
|||
|
|
const claim = tag ? void 0 : createFragmentClaim();
|
|||
|
|
locateHydrationNode(claim);
|
|||
|
|
if (claim && claim.start) close = claimAnchor(locateEndAnchor(claim.start));
|
|||
|
|
}
|
|||
|
|
let isMounted = false;
|
|||
|
|
renderEffect(() => {
|
|||
|
|
cssTransitionProps = resolveTransitionProps(props);
|
|||
|
|
if (isMounted) applyGroupTransitionHooks(slottedBlock, propsProxy, state, instance, updateHooks);
|
|||
|
|
}, true);
|
|||
|
|
const createContainer = () => tag ? isHydrating$1 ? adoptTemplate(currentHydrationNode, `<${tag}/>`) : /* @__PURE__ */ createElement(tag) : void 0;
|
|||
|
|
const renderChildren = (slot, container, run = (render) => render()) => {
|
|||
|
|
let nextNode = null;
|
|||
|
|
if (isHydrating$1 && container) {
|
|||
|
|
nextNode = nextLogicalSibling(container);
|
|||
|
|
setCurrentHydrationNode(container.firstChild || container);
|
|||
|
|
}
|
|||
|
|
try {
|
|||
|
|
run(() => {
|
|||
|
|
const block = slot && slot() || [];
|
|||
|
|
applyGroupTransitionHooks(block, propsProxy, state, instance, updateHooks);
|
|||
|
|
slottedBlock = block;
|
|||
|
|
if (container) {
|
|||
|
|
if (!isHydrating$1) insert(block, container);
|
|||
|
|
registerNestedVDOMCleanup(block);
|
|||
|
|
return container;
|
|||
|
|
}
|
|||
|
|
return block;
|
|||
|
|
});
|
|||
|
|
if (isHydrating$1 && container && currentHydrationNode && currentHydrationNode.parentNode === container) cleanupHydrationTail(currentHydrationNode, container);
|
|||
|
|
if (isHydrating$1 && close) {
|
|||
|
|
trimHydrationBoundary(close);
|
|||
|
|
if (currentHydrationNode === close) advanceHydrationNode(close);
|
|||
|
|
close = null;
|
|||
|
|
}
|
|||
|
|
} finally {
|
|||
|
|
if (isHydrating$1 && container) setCurrentHydrationNode(nextNode);
|
|||
|
|
}
|
|||
|
|
isMounted = true;
|
|||
|
|
};
|
|||
|
|
if (!instance.rawSlots.$) {
|
|||
|
|
const container = createContainer();
|
|||
|
|
renderChildren(slots.default, container);
|
|||
|
|
return container || slottedBlock;
|
|||
|
|
}
|
|||
|
|
const frag = new DynamicFragment(0, !!(process.env.NODE_ENV !== "production") ? "transition-group" : void 0);
|
|||
|
|
let currentSlot;
|
|||
|
|
renderEffect(() => {
|
|||
|
|
const slot = slots.default;
|
|||
|
|
if (isMounted && slot === currentSlot) return;
|
|||
|
|
renderChildren(slot, createContainer(), (render) => frag.update(render));
|
|||
|
|
currentSlot = slot;
|
|||
|
|
});
|
|||
|
|
return frag;
|
|||
|
|
}
|
|||
|
|
}));
|
|||
|
|
function resolveTransitionBlocks(block, onFragment, onUpdateOwner, collectOnly = false) {
|
|||
|
|
const children = [];
|
|||
|
|
if (collectOnly) {
|
|||
|
|
collectTransitionBlocks(block, children, onFragment, onUpdateOwner);
|
|||
|
|
return children;
|
|||
|
|
}
|
|||
|
|
const keys = /* @__PURE__ */ new Map();
|
|||
|
|
collectTransitionBlocks(block, children, onFragment, onUpdateOwner, keys, ROOT_KEY_CONTEXT);
|
|||
|
|
for (let i = 0; i < children.length; i++) setTransitionKey(children[i], keys.get(children[i]));
|
|||
|
|
return children;
|
|||
|
|
}
|
|||
|
|
function collectTransitionBlocks(block, children, onFragment, onUpdateOwner, keys, ctx) {
|
|||
|
|
if (block instanceof Node) {
|
|||
|
|
if (block instanceof Element) {
|
|||
|
|
children.push(block);
|
|||
|
|
if (keys) keys.set(block, block.$key);
|
|||
|
|
}
|
|||
|
|
} else if (isVaporComponent(block)) {
|
|||
|
|
const isRootSlot = block.block && isVaporSlotOutlet(block.block);
|
|||
|
|
if (onUpdateOwner && !isRootSlot) onUpdateOwner(block);
|
|||
|
|
const start = children.length;
|
|||
|
|
collectTransitionBlocks(block.block, children, onFragment, isRootSlot ? onUpdateOwner : void 0, keys, ctx && (isRootSlot ? withDefaultKey(ctx, block.$key) : enterComponentKeyContext(ctx, block)));
|
|||
|
|
if (keys) {
|
|||
|
|
if (!isRootSlot) {
|
|||
|
|
const t = transitionTypeOf(block);
|
|||
|
|
for (let i = start; i < children.length; i++) setTransitionType(children[i], t);
|
|||
|
|
}
|
|||
|
|
resolveOwnerKey(children, start, block.$key, keys, !isRootSlot);
|
|||
|
|
}
|
|||
|
|
} else if (isArray(block)) for (let i = 0; i < block.length; i++) collectTransitionBlocks(block[i], children, onFragment, onUpdateOwner, keys, ctx);
|
|||
|
|
else if (isFragment(block)) {
|
|||
|
|
const isItem = isForBlock(block);
|
|||
|
|
if (!isItem) {
|
|||
|
|
if (onFragment) onFragment(block);
|
|||
|
|
if (onUpdateOwner) onUpdateOwner(block);
|
|||
|
|
}
|
|||
|
|
if (isInteropEnabled && block.hasVDOMContent && block.hasVDOMContent()) {
|
|||
|
|
children.push(block);
|
|||
|
|
if (keys) keys.set(block, block.$key);
|
|||
|
|
} else {
|
|||
|
|
const key = isItem ? block.key : getFragmentKey(block);
|
|||
|
|
const start = children.length;
|
|||
|
|
collectTransitionBlocks(block.nodes, children, onFragment, onUpdateOwner, keys, ctx && enterFragmentKeyContext(block, ctx, key));
|
|||
|
|
if (!keys) return;
|
|||
|
|
if (!isItem) resolveOwnerKey(children, start, key, keys, false);
|
|||
|
|
else if (key != null) {
|
|||
|
|
if (children.length - start === 1) keys.set(children[start], key);
|
|||
|
|
else for (let i = start; i < children.length; i++) keys.set(children[i], `${key}:${i - start}`);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function resolveOwnerKey(children, start, key, keys, final) {
|
|||
|
|
if (children.length - start === 1) {
|
|||
|
|
const child = children[start];
|
|||
|
|
if (final || keys.get(child) == null) keys.set(child, key);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (key == null) return;
|
|||
|
|
for (let i = start; i < children.length; i++) {
|
|||
|
|
const child = children[i];
|
|||
|
|
const inner = keys.get(child);
|
|||
|
|
keys.set(child, String(key) + String(inner != null ? inner : i - start));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function applyGroupTransitionHooks(block, props, state, instance, updateHooks) {
|
|||
|
|
const fragments = [];
|
|||
|
|
const children = resolveTransitionBlocks(block, (frag) => fragments.push(frag), (owner) => trackTransitionGroupUpdate(owner, instance, updateHooks));
|
|||
|
|
for (let i = 0; i < children.length; i++) {
|
|||
|
|
const child = children[i];
|
|||
|
|
if (isValidTransitionBlock(child)) {
|
|||
|
|
if (getTransitionKey(child) != null) child.$transition = resolveTransitionHooks(child, props, state, instance);
|
|||
|
|
else if (!!(process.env.NODE_ENV !== "production")) warn(`<transition-group> children must be keyed`);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
fragments.forEach((frag) => {
|
|||
|
|
const hooks = resolveTransitionHooks(frag, props, state, instance);
|
|||
|
|
hooks.applyGroup = (block, props, state, instance) => applyGroupTransitionHooks(block, props, state, instance, updateHooks);
|
|||
|
|
frag.$transition = hooks;
|
|||
|
|
});
|
|||
|
|
return children;
|
|||
|
|
}
|
|||
|
|
function trackTransitionGroupUpdate(owner, instance, updateHooks) {
|
|||
|
|
if (trackedTransitionGroupOwners.has(owner)) return;
|
|||
|
|
if (isFragment(owner)) {
|
|||
|
|
trackedTransitionGroupOwners.add(owner);
|
|||
|
|
(owner.bu || (owner.bu = [])).push(updateHooks.beforeUpdate);
|
|||
|
|
(owner.u || (owner.u = [])).push(updateHooks.updated);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (!owner.hasDynamicProps) return;
|
|||
|
|
trackedTransitionGroupOwners.add(owner);
|
|||
|
|
const prevGroup = setCurrentInstance(instance, owner.scope);
|
|||
|
|
try {
|
|||
|
|
renderEffect(() => {
|
|||
|
|
trackRawValues(owner);
|
|||
|
|
});
|
|||
|
|
} finally {
|
|||
|
|
restoreCurrentInstance(prevGroup);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function recordPosition(c) {
|
|||
|
|
const el = getTransitionElement(c);
|
|||
|
|
if (el) newPositionMap.set(c, el.getBoundingClientRect());
|
|||
|
|
}
|
|||
|
|
function applyTranslation(c) {
|
|||
|
|
const el = getTransitionElement(c);
|
|||
|
|
if (el && baseApplyTranslation(positionMap.get(c), newPositionMap.get(c), el)) return c;
|
|||
|
|
}
|
|||
|
|
function getFirstConnectedChild(children) {
|
|||
|
|
for (let i = 0; i < children.length; i++) {
|
|||
|
|
const child = children[i];
|
|||
|
|
const el = getTransitionElement(child);
|
|||
|
|
if (el && el.isConnected) return el;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
export { DynamicFragment, VaporElement, VaporFragment, VaporKeepAlive, VaporTeleport, VaporTransition, VaporTransitionGroup, applyCheckboxModel, applyDynamicModel, applyRadioModel, applySelectModel, applyTextModel, applyVShow, child, createAssetComponent, createComponent, createComponentWithFallback, createDynamicComponent, createFor, createForSlots, createIf, createInvoker, createKeyedFragment, createPlainElement, createSelector, createSlot, createTemplateRefSetter, createTextNode, createVaporApp, createVaporSSRApp, defineVaporAsyncComponent, defineVaporComponent, defineVaporCustomElement, defineVaporSSRCustomElement, delegate, delegateEvents, extend, getDefaultValue, getRestElement, insert, isFragment, isVaporComponent, next, nthChild, on, onBinding, remove, renderEffect, setAttr, setBlockKey, setClass, setClassName, setDOMProp, setDynamicEvents, setDynamicProps, setElementText, setHtml, setInsertionState, setListener, setProp, setStaticTemplateRef, setStyle, setTemplateRefBinding, setText, setValue, template, txt, useVaporCssVars, vaporInteropPlugin, withOnce, withVaporDirectives, withVaporKeys, withVaporModifiers };
|