( fn: Function, ctx: ComponentInternalInstance | null = currentRenderingInstance, isNonScopedSlot?: boolean, // __COMPAT__ only )
| 68 | * @private compiler helper |
| 69 | */ |
| 70 | export function withCtx( |
| 71 | fn: Function, |
| 72 | ctx: ComponentInternalInstance | null = currentRenderingInstance, |
| 73 | isNonScopedSlot?: boolean, // __COMPAT__ only |
| 74 | ): Function { |
| 75 | if (!ctx) return fn |
| 76 | |
| 77 | // already normalized |
| 78 | if ((fn as ContextualRenderFn)._n) { |
| 79 | return fn |
| 80 | } |
| 81 | |
| 82 | const renderFnWithContext: ContextualRenderFn = (...args: any[]) => { |
| 83 | // If a user calls a compiled slot inside a template expression (#1745), it |
| 84 | // can mess up block tracking, so by default we disable block tracking and |
| 85 | // force bail out when invoking a compiled slot (indicated by the ._d flag). |
| 86 | // This isn't necessary if rendering a compiled `<slot>`, so we flip the |
| 87 | // ._d flag off when invoking the wrapped fn inside `renderSlot`. |
| 88 | if (renderFnWithContext._d) { |
| 89 | setBlockTracking(-1) |
| 90 | } |
| 91 | const prevInstance = setCurrentRenderingInstance(ctx) |
| 92 | let res |
| 93 | try { |
| 94 | res = fn(...args) |
| 95 | } finally { |
| 96 | setCurrentRenderingInstance(prevInstance) |
| 97 | if (renderFnWithContext._d) { |
| 98 | setBlockTracking(1) |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) { |
| 103 | devtoolsComponentUpdated(ctx) |
| 104 | } |
| 105 | |
| 106 | return res |
| 107 | } |
| 108 | |
| 109 | // mark normalized to avoid duplicated wrapping |
| 110 | renderFnWithContext._n = true |
| 111 | // mark this as compiled by default |
| 112 | // this is used in vnode.ts -> normalizeChildren() to set the slot |
| 113 | // rendering flag. |
| 114 | renderFnWithContext._c = true |
| 115 | // disable block tracking by default |
| 116 | renderFnWithContext._d = true |
| 117 | // compat build only flag to distinguish scoped slots from non-scoped ones |
| 118 | if (__COMPAT__ && isNonScopedSlot) { |
| 119 | renderFnWithContext._ns = true |
| 120 | } |
| 121 | return renderFnWithContext |
| 122 | } |
no outgoing calls