How to use validateDirectiveName method in Playwright Internal

Best JavaScript code snippet using playwright-internal

vue.runtime.esm.js

Source:vue.runtime.esm.js Github

copy

Full Screen

...1750 [bar, this.y]1751])1752*/1753const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text');1754function validateDirectiveName(name) {1755 if (isBuiltInDirective(name)) {1756 warn('Do not use built-in directive ids as custom directive id: ' + name);1757 }1758}1759function createAppContext() {1760 return {1761 app: null,1762 config: {1763 isNativeTag: NO,1764 performance: false,1765 globalProperties: {},1766 optionMergeStrategies: {},1767 isCustomElement: NO,1768 errorHandler: undefined,1769 warnHandler: undefined1770 },1771 mixins: [],1772 components: {},1773 directives: {},1774 provides: Object.create(null)1775 };1776}1777let uid$1 = 0;1778// fixed by xxxxxx1779function createAppAPI() {1780 return function createApp(rootComponent, rootProps = null) {1781 if (rootProps != null && !isObject(rootProps)) {1782 (process.env.NODE_ENV !== 'production') && warn(`root props passed to app.mount() must be an object.`);1783 rootProps = null;1784 }1785 const context = createAppContext();1786 const installedPlugins = new Set();1787 // fixed by xxxxxx1788 // let isMounted = false1789 const app = (context.app = {1790 _uid: uid$1++,1791 _component: rootComponent,1792 _props: rootProps,1793 _container: null,1794 _context: context,1795 version,1796 get config() {1797 return context.config;1798 },1799 set config(v) {1800 if ((process.env.NODE_ENV !== 'production')) {1801 warn(`app.config cannot be replaced. Modify individual options instead.`);1802 }1803 },1804 use(plugin, ...options) {1805 if (installedPlugins.has(plugin)) {1806 (process.env.NODE_ENV !== 'production') && warn(`Plugin has already been applied to target app.`);1807 }1808 else if (plugin && isFunction(plugin.install)) {1809 installedPlugins.add(plugin);1810 plugin.install(app, ...options);1811 }1812 else if (isFunction(plugin)) {1813 installedPlugins.add(plugin);1814 plugin(app, ...options);1815 }1816 else if ((process.env.NODE_ENV !== 'production')) {1817 warn(`A plugin must either be a function or an object with an "install" ` +1818 `function.`);1819 }1820 return app;1821 },1822 mixin(mixin) {1823 if (__VUE_OPTIONS_API__) {1824 if (!context.mixins.includes(mixin)) {1825 context.mixins.push(mixin);1826 }1827 else if ((process.env.NODE_ENV !== 'production')) {1828 warn('Mixin has already been applied to target app' +1829 (mixin.name ? `: ${mixin.name}` : ''));1830 }1831 }1832 else if ((process.env.NODE_ENV !== 'production')) {1833 warn('Mixins are only available in builds supporting Options API');1834 }1835 return app;1836 },1837 component(name, component) {1838 if ((process.env.NODE_ENV !== 'production')) {1839 validateComponentName(name, context.config);1840 }1841 if (!component) {1842 return context.components[name];1843 }1844 if ((process.env.NODE_ENV !== 'production') && context.components[name]) {1845 warn(`Component "${name}" has already been registered in target app.`);1846 }1847 context.components[name] = component;1848 return app;1849 },1850 directive(name, directive) {1851 if ((process.env.NODE_ENV !== 'production')) {1852 validateDirectiveName(name);1853 }1854 if (!directive) {1855 return context.directives[name];1856 }1857 if ((process.env.NODE_ENV !== 'production') && context.directives[name]) {1858 warn(`Directive "${name}" has already been registered in target app.`);1859 }1860 context.directives[name] = directive;1861 return app;1862 },1863 // fixed by xxxxxx1864 mount() { },1865 // fixed by xxxxxx1866 unmount() { },1867 provide(key, value) {1868 if ((process.env.NODE_ENV !== 'production') && key in context.provides) {1869 warn(`App already provides property with key "${String(key)}". ` +1870 `It will be overwritten with the new value.`);1871 }1872 // TypeScript doesn't allow symbols as index type1873 // https://github.com/Microsoft/TypeScript/issues/245871874 context.provides[key] = value;1875 return app;1876 }1877 });1878 return app;1879 };1880}1881const queuePostRenderEffect = queuePostFlushCb;1882// Simple effect.1883function watchEffect(effect, options) {1884 return doWatch(effect, null, options);1885}1886// initial value for watchers to trigger on undefined initial values1887const INITIAL_WATCHER_VALUE = {};1888// implementation1889function watch(source, cb, options) {1890 if ((process.env.NODE_ENV !== 'production') && !isFunction(cb)) {1891 warn(`\`watch(fn, options?)\` signature has been moved to a separate API. ` +1892 `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` +1893 `supports \`watch(source, cb, options?) signature.`);1894 }1895 return doWatch(source, cb, options);1896}1897function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EMPTY_OBJ, instance = currentInstance) {1898 if ((process.env.NODE_ENV !== 'production') && !cb) {1899 if (immediate !== undefined) {1900 warn(`watch() "immediate" option is only respected when using the ` +1901 `watch(source, callback, options?) signature.`);1902 }1903 if (deep !== undefined) {1904 warn(`watch() "deep" option is only respected when using the ` +1905 `watch(source, callback, options?) signature.`);1906 }1907 }1908 const warnInvalidSource = (s) => {1909 warn(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` +1910 `a reactive object, or an array of these types.`);1911 };1912 let getter;1913 const isRefSource = isRef(source);1914 if (isRefSource) {1915 getter = () => source.value;1916 }1917 else if (isReactive(source)) {1918 getter = () => source;1919 deep = true;1920 }1921 else if (isArray(source)) {1922 getter = () => source.map(s => {1923 if (isRef(s)) {1924 return s.value;1925 }1926 else if (isReactive(s)) {1927 return traverse(s);1928 }1929 else if (isFunction(s)) {1930 return callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */);1931 }1932 else {1933 (process.env.NODE_ENV !== 'production') && warnInvalidSource(s);1934 }1935 });1936 }1937 else if (isFunction(source)) {1938 if (cb) {1939 // getter with cb1940 getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */);1941 }1942 else {1943 // no cb -> simple effect1944 getter = () => {1945 if (instance && instance.isUnmounted) {1946 return;1947 }1948 if (cleanup) {1949 cleanup();1950 }1951 return callWithErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [onInvalidate]);1952 };1953 }1954 }1955 else {1956 getter = NOOP;1957 (process.env.NODE_ENV !== 'production') && warnInvalidSource(source);1958 }1959 if (cb && deep) {1960 const baseGetter = getter;1961 getter = () => traverse(baseGetter());1962 }1963 let cleanup;1964 const onInvalidate = (fn) => {1965 cleanup = runner.options.onStop = () => {1966 callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */);1967 };1968 };1969 let oldValue = isArray(source) ? [] : INITIAL_WATCHER_VALUE;1970 const job = () => {1971 if (!runner.active) {1972 return;1973 }1974 if (cb) {1975 // watch(source, cb)1976 const newValue = runner();1977 if (deep || isRefSource || hasChanged(newValue, oldValue)) {1978 // cleanup before running cb again1979 if (cleanup) {1980 cleanup();1981 }1982 callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [1983 newValue,1984 // pass undefined as the old value when it's changed for the first time1985 oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue,1986 onInvalidate1987 ]);1988 oldValue = newValue;1989 }1990 }1991 else {1992 // watchEffect1993 runner();1994 }1995 };1996 // important: mark the job as a watcher callback so that scheduler knows it1997 // it is allowed to self-trigger (#1727)1998 job.allowRecurse = !!cb;1999 let scheduler;2000 if (flush === 'sync') {2001 scheduler = job;2002 }2003 else if (flush === 'post') {2004 scheduler = () => queuePostRenderEffect(job, instance && instance.suspense);2005 }2006 else {2007 // default: 'pre'2008 scheduler = () => {2009 if (!instance || instance.isMounted) {2010 queuePreFlushCb(job);2011 }2012 else {2013 // with 'pre' option, the first call must happen before2014 // the component is mounted so it is called synchronously.2015 job();2016 }2017 };2018 }2019 const runner = effect(getter, {2020 lazy: true,2021 onTrack,2022 onTrigger,2023 scheduler2024 });2025 recordInstanceBoundEffect(runner);2026 // initial run2027 if (cb) {2028 if (immediate) {2029 job();2030 }2031 else {2032 oldValue = runner();2033 }2034 }2035 else if (flush === 'post') {2036 queuePostRenderEffect(runner, instance && instance.suspense);2037 }2038 else {2039 runner();2040 }2041 return () => {2042 stop(runner);2043 if (instance) {2044 remove(instance.effects, runner);2045 }2046 };2047}2048// this.$watch2049function instanceWatch(source, cb, options) {2050 const publicThis = this.proxy;2051 const getter = isString(source)2052 ? () => publicThis[source]2053 : source.bind(publicThis);2054 return doWatch(getter, cb.bind(publicThis), options, this);2055}2056function traverse(value, seen = new Set()) {2057 if (!isObject(value) || seen.has(value)) {2058 return value;2059 }2060 seen.add(value);2061 if (isRef(value)) {2062 traverse(value.value, seen);2063 }2064 else if (isArray(value)) {2065 for (let i = 0; i < value.length; i++) {2066 traverse(value[i], seen);2067 }2068 }2069 else if (isMap(value)) {2070 value.forEach((_, key) => {2071 // to register mutation dep for existing keys2072 traverse(value.get(key), seen);2073 });2074 }2075 else if (isSet(value)) {2076 value.forEach(v => {2077 traverse(v, seen);2078 });2079 }2080 else {2081 for (const key in value) {2082 traverse(value[key], seen);2083 }2084 }2085 return value;2086}2087function provide(key, value) {2088 if (!currentInstance) {2089 if ((process.env.NODE_ENV !== 'production')) {2090 warn(`provide() can only be used inside setup().`);2091 }2092 }2093 else {2094 let provides = currentInstance.provides;2095 // by default an instance inherits its parent's provides object2096 // but when it needs to provide values of its own, it creates its2097 // own provides object using parent provides object as prototype.2098 // this way in `inject` we can simply look up injections from direct2099 // parent and let the prototype chain do the work.2100 const parentProvides = currentInstance.parent && currentInstance.parent.provides;2101 if (parentProvides === provides) {2102 provides = currentInstance.provides = Object.create(parentProvides);2103 }2104 // TS doesn't allow symbol as index type2105 provides[key] = value;2106 }2107}2108function inject(key, defaultValue, treatDefaultAsFactory = false) {2109 // fallback to `currentRenderingInstance` so that this can be called in2110 // a functional component2111 const instance = currentInstance || currentRenderingInstance;2112 if (instance) {2113 const provides = instance.provides;2114 if (key in provides) {2115 // TS doesn't allow symbol as index type2116 return provides[key];2117 }2118 else if (arguments.length > 1) {2119 return treatDefaultAsFactory && isFunction(defaultValue)2120 ? defaultValue()2121 : defaultValue;2122 }2123 else if ((process.env.NODE_ENV !== 'production')) {2124 warn(`injection "${String(key)}" not found.`);2125 }2126 }2127 else if ((process.env.NODE_ENV !== 'production')) {2128 warn(`inject() can only be used inside setup() or functional components.`);2129 }2130}2131function createDuplicateChecker() {2132 const cache = Object.create(null);2133 return (type, key) => {2134 if (cache[key]) {2135 warn(`${type} property "${key}" is already defined in ${cache[key]}.`);2136 }2137 else {2138 cache[key] = type;2139 }2140 };2141}2142let isInBeforeCreate = false;2143function applyOptions(instance, options, deferredData = [], deferredWatch = [], asMixin = false) {2144 const { 2145 // composition2146 mixins, extends: extendsOptions, 2147 // state2148 data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions, 2149 // assets2150 components, directives, 2151 // lifecycle2152 beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy, beforeUnmount, destroyed, unmounted, render, renderTracked, renderTriggered, errorCaptured } = options;2153 const publicThis = instance.proxy;2154 const ctx = instance.ctx;2155 const globalMixins = instance.appContext.mixins;2156 if (asMixin && render && instance.render === NOOP) {2157 instance.render = render;2158 }2159 // applyOptions is called non-as-mixin once per instance2160 if (!asMixin) {2161 isInBeforeCreate = true;2162 callSyncHook('beforeCreate', options, publicThis, globalMixins);2163 isInBeforeCreate = false;2164 // global mixins are applied first2165 applyMixins(instance, globalMixins, deferredData, deferredWatch);2166 }2167 // extending a base component...2168 if (extendsOptions) {2169 applyOptions(instance, extendsOptions, deferredData, deferredWatch, true);2170 }2171 // local mixins2172 if (mixins) {2173 applyMixins(instance, mixins, deferredData, deferredWatch);2174 }2175 const checkDuplicateProperties = (process.env.NODE_ENV !== 'production') ? createDuplicateChecker() : null;2176 if ((process.env.NODE_ENV !== 'production')) {2177 const [propsOptions] = instance.propsOptions;2178 if (propsOptions) {2179 for (const key in propsOptions) {2180 checkDuplicateProperties("Props" /* PROPS */, key);2181 }2182 }2183 }2184 // options initialization order (to be consistent with Vue 2):2185 // - props (already done outside of this function)2186 // - inject2187 // - methods2188 // - data (deferred since it relies on `this` access)2189 // - computed2190 // - watch (deferred since it relies on `this` access)2191 // fixed by xxxxxx2192 if (!__VUE_CREATED_DEFERRED__ && injectOptions) {2193 if (isArray(injectOptions)) {2194 for (let i = 0; i < injectOptions.length; i++) {2195 const key = injectOptions[i];2196 ctx[key] = inject(key);2197 if ((process.env.NODE_ENV !== 'production')) {2198 checkDuplicateProperties("Inject" /* INJECT */, key);2199 }2200 }2201 }2202 else {2203 for (const key in injectOptions) {2204 const opt = injectOptions[key];2205 if (isObject(opt)) {2206 ctx[key] = inject(opt.from || key, opt.default, true /* treat default function as factory */);2207 }2208 else {2209 ctx[key] = inject(opt);2210 }2211 if ((process.env.NODE_ENV !== 'production')) {2212 checkDuplicateProperties("Inject" /* INJECT */, key);2213 }2214 }2215 }2216 }2217 if (methods) {2218 for (const key in methods) {2219 const methodHandler = methods[key];2220 if (isFunction(methodHandler)) {2221 ctx[key] = methodHandler.bind(publicThis);2222 if ((process.env.NODE_ENV !== 'production')) {2223 checkDuplicateProperties("Methods" /* METHODS */, key);2224 }2225 }2226 else if ((process.env.NODE_ENV !== 'production')) {2227 warn(`Method "${key}" has type "${typeof methodHandler}" in the component definition. ` +2228 `Did you reference the function correctly?`);2229 }2230 }2231 }2232 if (!asMixin) {2233 if (deferredData.length) {2234 deferredData.forEach(dataFn => resolveData(instance, dataFn, publicThis));2235 }2236 if (dataOptions) {2237 resolveData(instance, dataOptions, publicThis);2238 }2239 if ((process.env.NODE_ENV !== 'production')) {2240 const rawData = toRaw(instance.data);2241 for (const key in rawData) {2242 checkDuplicateProperties("Data" /* DATA */, key);2243 // expose data on ctx during dev2244 if (key[0] !== '$' && key[0] !== '_') {2245 Object.defineProperty(ctx, key, {2246 configurable: true,2247 enumerable: true,2248 get: () => rawData[key],2249 set: NOOP2250 });2251 }2252 }2253 }2254 }2255 else if (dataOptions) {2256 deferredData.push(dataOptions);2257 }2258 if (computedOptions) {2259 for (const key in computedOptions) {2260 const opt = computedOptions[key];2261 const get = isFunction(opt)2262 ? opt.bind(publicThis, publicThis)2263 : isFunction(opt.get)2264 ? opt.get.bind(publicThis, publicThis)2265 : NOOP;2266 if ((process.env.NODE_ENV !== 'production') && get === NOOP) {2267 warn(`Computed property "${key}" has no getter.`);2268 }2269 const set = !isFunction(opt) && isFunction(opt.set)2270 ? opt.set.bind(publicThis)2271 : (process.env.NODE_ENV !== 'production')2272 ? () => {2273 warn(`Write operation failed: computed property "${key}" is readonly.`);2274 }2275 : NOOP;2276 const c = computed$1({2277 get,2278 set2279 });2280 Object.defineProperty(ctx, key, {2281 enumerable: true,2282 configurable: true,2283 get: () => c.value,2284 set: v => (c.value = v)2285 });2286 if ((process.env.NODE_ENV !== 'production')) {2287 checkDuplicateProperties("Computed" /* COMPUTED */, key);2288 }2289 }2290 }2291 if (watchOptions) {2292 deferredWatch.push(watchOptions);2293 }2294 if (!asMixin && deferredWatch.length) {2295 deferredWatch.forEach(watchOptions => {2296 for (const key in watchOptions) {2297 createWatcher(watchOptions[key], ctx, publicThis, key);2298 }2299 });2300 }2301 // fixed by xxxxxx2302 if (!__VUE_CREATED_DEFERRED__ && provideOptions) {2303 const provides = isFunction(provideOptions)2304 ? provideOptions.call(publicThis)2305 : provideOptions;2306 for (const key in provides) {2307 provide(key, provides[key]);2308 }2309 }2310 // asset options.2311 // To reduce memory usage, only components with mixins or extends will have2312 // resolved asset registry attached to instance.2313 if (asMixin) {2314 if (components) {2315 extend(instance.components ||2316 (instance.components = extend({}, instance.type.components)), components);2317 }2318 if (directives) {2319 extend(instance.directives ||2320 (instance.directives = extend({}, instance.type.directives)), directives);2321 }2322 }2323 // fixed by xxxxxx2324 // lifecycle options2325 if (__VUE_CREATED_DEFERRED__) {2326 ctx.$callSyncHook = function (name) {2327 return callSyncHook(name, options, publicThis, globalMixins);2328 };2329 }2330 else if (!asMixin) {2331 callSyncHook('created', options, publicThis, globalMixins);2332 }2333 if (beforeMount) {2334 onBeforeMount(beforeMount.bind(publicThis));2335 }2336 if (mounted) {2337 onMounted(mounted.bind(publicThis));2338 }2339 if (beforeUpdate) {2340 onBeforeUpdate(beforeUpdate.bind(publicThis));2341 }2342 if (updated) {2343 onUpdated(updated.bind(publicThis));2344 }2345 if (activated) {2346 onActivated(activated.bind(publicThis));2347 }2348 if (deactivated) {2349 onDeactivated(deactivated.bind(publicThis));2350 }2351 if (errorCaptured) {2352 onErrorCaptured(errorCaptured.bind(publicThis));2353 }2354 if (renderTracked) {2355 onRenderTracked(renderTracked.bind(publicThis));2356 }2357 if (renderTriggered) {2358 onRenderTriggered(renderTriggered.bind(publicThis));2359 }2360 if ((process.env.NODE_ENV !== 'production') && beforeDestroy) {2361 warn(`\`beforeDestroy\` has been renamed to \`beforeUnmount\`.`);2362 }2363 if (beforeUnmount) {2364 onBeforeUnmount(beforeUnmount.bind(publicThis));2365 }2366 if ((process.env.NODE_ENV !== 'production') && destroyed) {2367 warn(`\`destroyed\` has been renamed to \`unmounted\`.`);2368 }2369 if (unmounted) {2370 onUnmounted(unmounted.bind(publicThis));2371 }2372 // fixed by xxxxxx2373 if (instance.ctx.$onApplyOptions) {2374 instance.ctx.$onApplyOptions(options, instance, publicThis);2375 }2376}2377function callSyncHook(name, options, ctx, globalMixins) {2378 callHookFromMixins(name, globalMixins, ctx);2379 const { extends: base, mixins } = options;2380 if (base) {2381 callHookFromExtends(name, base, ctx);2382 }2383 if (mixins) {2384 callHookFromMixins(name, mixins, ctx);2385 }2386 const selfHook = options[name];2387 if (selfHook) {2388 selfHook.call(ctx);2389 }2390}2391function callHookFromExtends(name, base, ctx) {2392 if (base.extends) {2393 callHookFromExtends(name, base.extends, ctx);2394 }2395 const baseHook = base[name];2396 if (baseHook) {2397 baseHook.call(ctx);2398 }2399}2400function callHookFromMixins(name, mixins, ctx) {2401 for (let i = 0; i < mixins.length; i++) {2402 const chainedMixins = mixins[i].mixins;2403 if (chainedMixins) {2404 callHookFromMixins(name, chainedMixins, ctx);2405 }2406 const fn = mixins[i][name];2407 if (fn) {2408 fn.call(ctx);2409 }2410 }2411}2412function applyMixins(instance, mixins, deferredData, deferredWatch) {2413 for (let i = 0; i < mixins.length; i++) {2414 applyOptions(instance, mixins[i], deferredData, deferredWatch, true);2415 }2416}2417function resolveData(instance, dataFn, publicThis) {2418 if ((process.env.NODE_ENV !== 'production') && !isFunction(dataFn)) {2419 warn(`The data option must be a function. ` +2420 `Plain object usage is no longer supported.`);2421 }2422 const data = dataFn.call(publicThis, publicThis);2423 if ((process.env.NODE_ENV !== 'production') && isPromise(data)) {2424 warn(`data() returned a Promise - note data() cannot be async; If you ` +2425 `intend to perform data fetching before component renders, use ` +2426 `async setup() + <Suspense>.`);2427 }2428 if (!isObject(data)) {2429 (process.env.NODE_ENV !== 'production') && warn(`data() should return an object.`);2430 }2431 else if (instance.data === EMPTY_OBJ) {2432 instance.data = reactive(data);2433 }2434 else {2435 // existing data: this is a mixin or extends.2436 extend(instance.data, data);2437 }2438}2439function createWatcher(raw, ctx, publicThis, key) {2440 const getter = key.includes('.')2441 ? createPathGetter(publicThis, key)2442 : () => publicThis[key];2443 if (isString(raw)) {2444 const handler = ctx[raw];2445 if (isFunction(handler)) {2446 watch(getter, handler);2447 }2448 else if ((process.env.NODE_ENV !== 'production')) {2449 warn(`Invalid watch handler specified by key "${raw}"`, handler);2450 }2451 }2452 else if (isFunction(raw)) {2453 watch(getter, raw.bind(publicThis));2454 }2455 else if (isObject(raw)) {2456 if (isArray(raw)) {2457 raw.forEach(r => createWatcher(r, ctx, publicThis, key));2458 }2459 else {2460 const handler = isFunction(raw.handler)2461 ? raw.handler.bind(publicThis)2462 : ctx[raw.handler];2463 if (isFunction(handler)) {2464 watch(getter, handler, raw);2465 }2466 else if ((process.env.NODE_ENV !== 'production')) {2467 warn(`Invalid watch handler specified by key "${raw.handler}"`, handler);2468 }2469 }2470 }2471 else if ((process.env.NODE_ENV !== 'production')) {2472 warn(`Invalid watch option: "${key}"`, raw);2473 }2474}2475function createPathGetter(ctx, path) {2476 const segments = path.split('.');2477 return () => {2478 let cur = ctx;2479 for (let i = 0; i < segments.length && cur; i++) {2480 cur = cur[segments[i]];2481 }2482 return cur;2483 };2484}2485function resolveMergedOptions(instance) {2486 const raw = instance.type;2487 const { __merged, mixins, extends: extendsOptions } = raw;2488 if (__merged)2489 return __merged;2490 const globalMixins = instance.appContext.mixins;2491 if (!globalMixins.length && !mixins && !extendsOptions)2492 return raw;2493 const options = {};2494 globalMixins.forEach(m => mergeOptions(options, m, instance));2495 mergeOptions(options, raw, instance);2496 return (raw.__merged = options);2497}2498function mergeOptions(to, from, instance) {2499 const strats = instance.appContext.config.optionMergeStrategies;2500 const { mixins, extends: extendsOptions } = from;2501 extendsOptions && mergeOptions(to, extendsOptions, instance);2502 mixins &&2503 mixins.forEach((m) => mergeOptions(to, m, instance));2504 for (const key in from) {2505 if (strats && hasOwn(strats, key)) {2506 to[key] = strats[key](to[key], from[key], instance.proxy, key);2507 }2508 else {2509 to[key] = from[key];2510 }2511 }2512}2513const publicPropertiesMap = extend(Object.create(null), {2514 $: i => i,2515 $el: i => i.vnode.el,2516 $data: i => i.data,2517 $props: i => ((process.env.NODE_ENV !== 'production') ? shallowReadonly(i.props) : i.props),2518 $attrs: i => ((process.env.NODE_ENV !== 'production') ? shallowReadonly(i.attrs) : i.attrs),2519 $slots: i => ((process.env.NODE_ENV !== 'production') ? shallowReadonly(i.slots) : i.slots),2520 $refs: i => ((process.env.NODE_ENV !== 'production') ? shallowReadonly(i.refs) : i.refs),2521 $parent: i => i.parent && i.parent.proxy,2522 $root: i => i.root && i.root.proxy,2523 $emit: i => i.emit,2524 $options: i => (__VUE_OPTIONS_API__ ? resolveMergedOptions(i) : i.type),2525 $forceUpdate: i => () => queueJob(i.update),2526 // $nextTick: () => nextTick, // fixed by xxxxxx2527 $watch: i => (__VUE_OPTIONS_API__ ? instanceWatch.bind(i) : NOOP)2528});2529const PublicInstanceProxyHandlers = {2530 get({ _: instance }, key) {2531 const { ctx, setupState, data, props, accessCache, type, appContext } = instance;2532 // let @vue/reactivity know it should never observe Vue public instances.2533 if (key === "__v_skip" /* SKIP */) {2534 return true;2535 }2536 // data / props / ctx2537 // This getter gets called for every property access on the render context2538 // during render and is a major hotspot. The most expensive part of this2539 // is the multiple hasOwn() calls. It's much faster to do a simple property2540 // access on a plain object, so we use an accessCache object (with null2541 // prototype) to memoize what access type a key corresponds to.2542 let normalizedProps;2543 if (key[0] !== '$') {2544 const n = accessCache[key];2545 if (n !== undefined) {2546 switch (n) {2547 case 0 /* SETUP */:2548 return setupState[key];2549 case 1 /* DATA */:2550 return data[key];2551 case 3 /* CONTEXT */:2552 return ctx[key];2553 case 2 /* PROPS */:2554 return props[key];2555 // default: just fallthrough2556 }2557 }2558 else if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {2559 accessCache[key] = 0 /* SETUP */;2560 return setupState[key];2561 }2562 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {2563 accessCache[key] = 1 /* DATA */;2564 return data[key];2565 }2566 else if (2567 // only cache other properties when instance has declared (thus stable)2568 // props2569 (normalizedProps = instance.propsOptions[0]) &&2570 hasOwn(normalizedProps, key)) {2571 accessCache[key] = 2 /* PROPS */;2572 return props[key];2573 }2574 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {2575 accessCache[key] = 3 /* CONTEXT */;2576 return ctx[key];2577 }2578 else if (!__VUE_OPTIONS_API__ || !isInBeforeCreate) {2579 accessCache[key] = 4 /* OTHER */;2580 }2581 }2582 const publicGetter = publicPropertiesMap[key];2583 let cssModule, globalProperties;2584 // public $xxx properties2585 if (publicGetter) {2586 if (key === '$attrs') {2587 track(instance, "get" /* GET */, key);2588 (process.env.NODE_ENV !== 'production') && markAttrsAccessed();2589 }2590 return publicGetter(instance);2591 }2592 else if (2593 // css module (injected by vue-loader)2594 (cssModule = type.__cssModules) &&2595 (cssModule = cssModule[key])) {2596 return cssModule;2597 }2598 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {2599 // user may set custom properties to `this` that start with `$`2600 accessCache[key] = 3 /* CONTEXT */;2601 return ctx[key];2602 }2603 else if (2604 // global properties2605 ((globalProperties = appContext.config.globalProperties),2606 hasOwn(globalProperties, key))) {2607 return globalProperties[key];2608 }2609 else if ((process.env.NODE_ENV !== 'production') &&2610 currentRenderingInstance &&2611 (!isString(key) ||2612 // #1091 avoid internal isRef/isVNode checks on component instance leading2613 // to infinite warning loop2614 key.indexOf('__v') !== 0)) {2615 if (data !== EMPTY_OBJ &&2616 (key[0] === '$' || key[0] === '_') &&2617 hasOwn(data, key)) {2618 warn(`Property ${JSON.stringify(key)} must be accessed via $data because it starts with a reserved ` +2619 `character ("$" or "_") and is not proxied on the render context.`);2620 }2621 else {2622 warn(`Property ${JSON.stringify(key)} was accessed during render ` +2623 `but is not defined on instance.`);2624 }2625 }2626 },2627 set({ _: instance }, key, value) {2628 const { data, setupState, ctx } = instance;2629 if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {2630 setupState[key] = value;2631 }2632 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {2633 data[key] = value;2634 }2635 else if (key in instance.props) {2636 (process.env.NODE_ENV !== 'production') &&2637 warn(`Attempting to mutate prop "${key}". Props are readonly.`, instance);2638 return false;2639 }2640 if (key[0] === '$' && key.slice(1) in instance) {2641 (process.env.NODE_ENV !== 'production') &&2642 warn(`Attempting to mutate public property "${key}". ` +2643 `Properties starting with $ are reserved and readonly.`, instance);2644 return false;2645 }2646 else {2647 if ((process.env.NODE_ENV !== 'production') && key in instance.appContext.config.globalProperties) {2648 Object.defineProperty(ctx, key, {2649 enumerable: true,2650 configurable: true,2651 value2652 });2653 }2654 else {2655 ctx[key] = value;2656 }2657 }2658 return true;2659 },2660 has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) {2661 let normalizedProps;2662 return (accessCache[key] !== undefined ||2663 (data !== EMPTY_OBJ && hasOwn(data, key)) ||2664 (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) ||2665 ((normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key)) ||2666 hasOwn(ctx, key) ||2667 hasOwn(publicPropertiesMap, key) ||2668 hasOwn(appContext.config.globalProperties, key));2669 }2670};2671if ((process.env.NODE_ENV !== 'production') && !false) {2672 PublicInstanceProxyHandlers.ownKeys = (target) => {2673 warn(`Avoid app logic that relies on enumerating keys on a component instance. ` +2674 `The keys will be empty in production mode to avoid performance overhead.`);2675 return Reflect.ownKeys(target);2676 };2677}2678const RuntimeCompiledPublicInstanceProxyHandlers = extend({}, PublicInstanceProxyHandlers, {2679 get(target, key) {2680 // fast path for unscopables when using `with` block2681 if (key === Symbol.unscopables) {2682 return;2683 }2684 return PublicInstanceProxyHandlers.get(target, key, target);2685 },2686 has(_, key) {2687 const has = key[0] !== '_' && !isGloballyWhitelisted(key);2688 if ((process.env.NODE_ENV !== 'production') && !has && PublicInstanceProxyHandlers.has(_, key)) {2689 warn(`Property ${JSON.stringify(key)} should not start with _ which is a reserved prefix for Vue internals.`);2690 }2691 return has;2692 }2693});2694// In dev mode, the proxy target exposes the same properties as seen on `this`2695// for easier console inspection. In prod mode it will be an empty object so2696// these properties definitions can be skipped.2697function createRenderContext(instance) {2698 const target = {};2699 // expose internal instance for proxy handlers2700 Object.defineProperty(target, `_`, {2701 configurable: true,2702 enumerable: false,2703 get: () => instance2704 });2705 // expose public properties2706 Object.keys(publicPropertiesMap).forEach(key => {2707 Object.defineProperty(target, key, {2708 configurable: true,2709 enumerable: false,2710 get: () => publicPropertiesMap[key](instance),2711 // intercepted by the proxy so no need for implementation,2712 // but needed to prevent set errors2713 set: NOOP2714 });2715 });2716 // expose global properties2717 const { globalProperties } = instance.appContext.config;2718 Object.keys(globalProperties).forEach(key => {2719 Object.defineProperty(target, key, {2720 configurable: true,2721 enumerable: false,2722 get: () => globalProperties[key],2723 set: NOOP2724 });2725 });2726 return target;2727}2728// dev only2729function exposePropsOnRenderContext(instance) {2730 const { ctx, propsOptions: [propsOptions] } = instance;2731 if (propsOptions) {2732 Object.keys(propsOptions).forEach(key => {2733 Object.defineProperty(ctx, key, {2734 enumerable: true,2735 configurable: true,2736 get: () => instance.props[key],2737 set: NOOP2738 });2739 });2740 }2741}2742// dev only2743function exposeSetupStateOnRenderContext(instance) {2744 const { ctx, setupState } = instance;2745 Object.keys(toRaw(setupState)).forEach(key => {2746 if (key[0] === '$' || key[0] === '_') {2747 warn(`setup() return property ${JSON.stringify(key)} should not start with "$" or "_" ` +2748 `which are reserved prefixes for Vue internals.`);2749 return;2750 }2751 Object.defineProperty(ctx, key, {2752 enumerable: true,2753 configurable: true,2754 get: () => setupState[key],2755 set: NOOP2756 });2757 });2758}2759const emptyAppContext = createAppContext();2760let uid$2 = 0;2761function createComponentInstance(vnode, parent, suspense) {2762 const type = vnode.type;2763 // inherit parent app context - or - if root, adopt from root vnode2764 const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;2765 const instance = {2766 uid: uid$2++,2767 vnode,2768 type,2769 parent,2770 appContext,2771 root: null,2772 next: null,2773 subTree: null,2774 update: null,2775 render: null,2776 proxy: null,2777 withProxy: null,2778 effects: null,2779 provides: parent ? parent.provides : Object.create(appContext.provides),2780 accessCache: null,2781 renderCache: [],2782 // local resovled assets2783 components: null,2784 directives: null,2785 // resolved props and emits options2786 propsOptions: normalizePropsOptions(type, appContext),2787 emitsOptions: normalizeEmitsOptions(type, appContext),2788 // emit2789 emit: null,2790 emitted: null,2791 // state2792 ctx: EMPTY_OBJ,2793 data: EMPTY_OBJ,2794 props: EMPTY_OBJ,2795 attrs: EMPTY_OBJ,2796 slots: EMPTY_OBJ,2797 refs: EMPTY_OBJ,2798 setupState: EMPTY_OBJ,2799 setupContext: null,2800 // suspense related2801 suspense,2802 suspenseId: suspense ? suspense.pendingId : 0,2803 asyncDep: null,2804 asyncResolved: false,2805 // lifecycle hooks2806 // not using enums here because it results in computed properties2807 isMounted: false,2808 isUnmounted: false,2809 isDeactivated: false,2810 bc: null,2811 c: null,2812 bm: null,2813 m: null,2814 bu: null,2815 u: null,2816 um: null,2817 bum: null,2818 da: null,2819 a: null,2820 rtg: null,2821 rtc: null,2822 ec: null2823 };2824 if ((process.env.NODE_ENV !== 'production')) {2825 instance.ctx = createRenderContext(instance);2826 }2827 else {2828 instance.ctx = { _: instance };2829 }2830 instance.root = parent ? parent.root : instance;2831 instance.emit = emit.bind(null, instance);2832 if ((process.env.NODE_ENV !== 'production') || false) ;2833 return instance;2834}2835let currentInstance = null;2836const setCurrentInstance = (instance) => {2837 currentInstance = instance;2838};2839const isBuiltInTag = /*#__PURE__*/ makeMap('slot,component');2840function validateComponentName(name, config) {2841 const appIsNativeTag = config.isNativeTag || NO;2842 if (isBuiltInTag(name) || appIsNativeTag(name)) {2843 warn('Do not use built-in or reserved HTML elements as component id: ' + name);2844 }2845}2846let isInSSRComponentSetup = false;2847function setupComponent(instance, isSSR = false) {2848 isInSSRComponentSetup = isSSR;2849 const { props, /* children, */ shapeFlag } = instance.vnode;2850 const isStateful = shapeFlag & 4 /* STATEFUL_COMPONENT */;2851 initProps(instance, props, isStateful, isSSR);2852 // initSlots(instance, children) // fixed by xxxxxx2853 const setupResult = isStateful2854 ? setupStatefulComponent(instance, isSSR)2855 : undefined;2856 isInSSRComponentSetup = false;2857 return setupResult;2858}2859function setupStatefulComponent(instance, isSSR) {2860 const Component = instance.type;2861 if ((process.env.NODE_ENV !== 'production')) {2862 if (Component.name) {2863 validateComponentName(Component.name, instance.appContext.config);2864 }2865 if (Component.components) {2866 const names = Object.keys(Component.components);2867 for (let i = 0; i < names.length; i++) {2868 validateComponentName(names[i], instance.appContext.config);2869 }2870 }2871 if (Component.directives) {2872 const names = Object.keys(Component.directives);2873 for (let i = 0; i < names.length; i++) {2874 validateDirectiveName(names[i]);2875 }2876 }2877 }2878 // 0. create render proxy property access cache2879 instance.accessCache = {};2880 // 1. create public instance / render proxy2881 // also mark it raw so it's never observed2882 instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers);2883 if ((process.env.NODE_ENV !== 'production')) {2884 exposePropsOnRenderContext(instance);2885 }2886 // 2. call setup()2887 const { setup } = Component;2888 if (setup) { ...

Full Screen

Full Screen

runtime-core.esm-bundler.js

Source:runtime-core.esm-bundler.js Github

copy

Full Screen

...1045])1046*/1047const valueCache = new WeakMap();1048const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text');1049function validateDirectiveName(name) {1050 if (isBuiltInDirective(name)) {1051 warn('Do not use built-in directive ids as custom directive id: ' + name);1052 }1053}1054function applyDirective(props, instance, directive, value, arg, modifiers = EMPTY_OBJ) {1055 let valueCacheForDir = valueCache.get(directive);1056 if (!valueCacheForDir) {1057 valueCacheForDir = new WeakMap();1058 valueCache.set(directive, valueCacheForDir);1059 }1060 if (isFunction(directive)) {1061 directive = {1062 mounted: directive,1063 updated: directive1064 };1065 }1066 for (const key in directive) {1067 const hook = directive[key];1068 const hookKey = `onVnode` + key[0].toUpperCase() + key.slice(1);1069 const vnodeHook = (vnode, prevVNode) => {1070 let oldValue;1071 if (prevVNode != null) {1072 oldValue = valueCacheForDir.get(prevVNode);1073 valueCacheForDir.delete(prevVNode);1074 }1075 valueCacheForDir.set(vnode, value);1076 hook(vnode.el, {1077 instance: instance.renderProxy,1078 value,1079 oldValue,1080 arg,1081 modifiers1082 }, vnode, prevVNode);1083 };1084 const existing = props[hookKey];1085 props[hookKey] = existing1086 ? [].concat(existing, vnodeHook)1087 : vnodeHook;1088 }1089}1090function withDirectives(vnode, directives) {1091 const instance = currentRenderingInstance;1092 if (instance !== null) {1093 vnode.props = vnode.props || {};1094 for (let i = 0; i < directives.length; i++) {1095 const [dir, value, arg, modifiers] = directives[i];1096 applyDirective(vnode.props, instance, dir, value, arg, modifiers);1097 }1098 }1099 else if (process.env.NODE_ENV !== 'production') {1100 warn(`withDirectives can only be used inside render functions.`);1101 }1102 return vnode;1103}1104function invokeDirectiveHook(hook, instance, vnode, prevVNode = null) {1105 callWithAsyncErrorHandling(hook, instance, 7 /* DIRECTIVE_HOOK */, [1106 vnode,1107 prevVNode1108 ]);1109}1110function createAppContext() {1111 return {1112 config: {1113 devtools: true,1114 performance: false,1115 isNativeTag: NO,1116 isCustomElement: NO,1117 errorHandler: undefined,1118 warnHandler: undefined1119 },1120 mixins: [],1121 components: {},1122 directives: {},1123 provides: {}1124 };1125}1126function createAppAPI(render) {1127 return function createApp() {1128 const context = createAppContext();1129 let isMounted = false;1130 const app = {1131 get config() {1132 return context.config;1133 },1134 set config(v) {1135 if (process.env.NODE_ENV !== 'production') {1136 warn(`app.config cannot be replaced. Modify individual options instead.`);1137 }1138 },1139 use(plugin) {1140 if (isFunction(plugin)) {1141 plugin(app);1142 }1143 else if (isFunction(plugin.install)) {1144 plugin.install(app);1145 }1146 else if (process.env.NODE_ENV !== 'production') {1147 warn(`A plugin must either be a function or an object with an "install" ` +1148 `function.`);1149 }1150 return app;1151 },1152 mixin(mixin) {1153 context.mixins.push(mixin);1154 return app;1155 },1156 component(name, component) {1157 if (process.env.NODE_ENV !== 'production') {1158 validateComponentName(name, context.config);1159 }1160 if (!component) {1161 return context.components[name];1162 }1163 else {1164 context.components[name] = component;1165 return app;1166 }1167 },1168 directive(name, directive) {1169 if (process.env.NODE_ENV !== 'production') {1170 validateDirectiveName(name);1171 }1172 if (!directive) {1173 return context.directives[name];1174 }1175 else {1176 context.directives[name] = directive;1177 return app;1178 }1179 },1180 mount(rootComponent, rootContainer, rootProps) {1181 if (!isMounted) {1182 const vnode = createVNode(rootComponent, rootProps);1183 // store app context on the root VNode.1184 // this will be set on the root instance on initial mount.1185 vnode.appContext = context;1186 render(vnode, rootContainer);1187 isMounted = true;1188 return vnode.component.renderProxy;1189 }1190 else if (process.env.NODE_ENV !== 'production') {1191 warn(`App has already been mounted. Create a new app instance instead.`);1192 }1193 },1194 provide(key, value) {1195 if (process.env.NODE_ENV !== 'production' && key in context.provides) {1196 warn(`App already provides property with key "${key}". ` +1197 `It will be overwritten with the new value.`);1198 }1199 // TypeScript doesn't allow symbols as index type1200 // https://github.com/Microsoft/TypeScript/issues/245871201 context.provides[key] = value;1202 }1203 };1204 return app;1205 };1206}1207const SuspenseSymbol = process.env.NODE_ENV !== 'production' ? Symbol('Suspense key') : Symbol();1208function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, optimized) {1209 return {1210 vnode,1211 parent,1212 parentComponent,1213 isSVG,1214 optimized,1215 container,1216 hiddenContainer,1217 anchor,1218 deps: 0,1219 subTree: null,1220 fallbackTree: null,1221 isResolved: false,1222 isUnmounted: false,1223 effects: []1224 };1225}1226function normalizeSuspenseChildren(vnode) {1227 const { shapeFlag, children } = vnode;1228 if (shapeFlag & PublicShapeFlags.SLOTS_CHILDREN) {1229 const { default: d, fallback } = children;1230 return {1231 content: normalizeVNode(isFunction(d) ? d() : d),1232 fallback: normalizeVNode(isFunction(fallback) ? fallback() : fallback)1233 };1234 }1235 else {1236 return {1237 content: normalizeVNode(children),1238 fallback: normalizeVNode(null)1239 };1240 }1241}1242const prodEffectOptions = {1243 scheduler: queueJob1244};1245function createDevEffectOptions(instance) {1246 return {1247 scheduler: queueJob,1248 onTrack: instance.rtc ? e => invokeHooks(instance.rtc, e) : void 0,1249 onTrigger: instance.rtg ? e => invokeHooks(instance.rtg, e) : void 01250 };1251}1252function isSameType$1(n1, n2) {1253 return n1.type === n2.type && n1.key === n2.key;1254}1255function invokeHooks(hooks, arg) {1256 for (let i = 0; i < hooks.length; i++) {1257 hooks[i](arg);1258 }1259}1260function queuePostRenderEffect(fn, suspense) {1261 if (suspense !== null && !suspense.isResolved) {1262 if (isArray(fn)) {1263 suspense.effects.push(...fn);1264 }1265 else {1266 suspense.effects.push(fn);1267 }1268 }1269 else {1270 queuePostFlushCb(fn);1271 }1272}1273/**1274 * The createRenderer function accepts two generic arguments:1275 * HostNode and HostElement, corresponding to Node and Element types in the1276 * host environment. For example, for runtime-dom, HostNode would be the DOM1277 * `Node` interface and HostElement would be the DOM `Element` interface.1278 *1279 * Custom renderers can pass in the platform specific types like this:1280 *1281 * ``` js1282 * const { render, createApp } = createRenderer<Node, Element>({1283 * patchProp,1284 * ...nodeOps1285 * })1286 * ```1287 */1288function createRenderer(options) {1289 const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, querySelector: hostQuerySelector } = options;1290 function patch(n1, // null means this is a mount1291 n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, optimized = false) {1292 // patching & not same type, unmount old tree1293 if (n1 != null) {1294 if (!isSameType$1(n1, n2)) {1295 anchor = getNextHostNode(n1);1296 unmount(n1, parentComponent, parentSuspense, true);1297 n1 = null;1298 }1299 else if (n1.props && n1.props.$once) {1300 return;1301 }1302 }1303 const { type, shapeFlag } = n2;1304 switch (type) {1305 case Text:1306 processText(n1, n2, container, anchor);1307 break;1308 case Comment:1309 processCommentNode(n1, n2, container, anchor);1310 break;1311 case Fragment:1312 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1313 break;1314 case Portal:1315 processPortal(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1316 break;1317 case Suspense:1318 {1319 processSuspense(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1320 }1321 break;1322 default:1323 if (shapeFlag & 1 /* ELEMENT */) {1324 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1325 }1326 else if (shapeFlag & 6 /* COMPONENT */) {1327 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1328 }1329 else if (process.env.NODE_ENV !== 'production') {1330 warn('Invalid HostVNode type:', n2.type, `(${typeof n2.type})`);1331 }1332 }1333 }1334 function processText(n1, n2, container, anchor) {1335 if (n1 == null) {1336 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);1337 }1338 else {1339 const el = (n2.el = n1.el);1340 if (n2.children !== n1.children) {1341 hostSetText(el, n2.children);1342 }1343 }1344 }1345 function processCommentNode(n1, n2, container, anchor) {1346 if (n1 == null) {1347 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);1348 }1349 else {1350 // there's no support for dynamic comments1351 n2.el = n1.el;1352 }1353 }1354 function processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1355 if (n1 == null) {1356 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1357 }1358 else {1359 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized);1360 }1361 if (n2.ref !== null && parentComponent !== null) {1362 setRef(n2.ref, n1 && n1.ref, parentComponent, n2.el);1363 }1364 }1365 function mountElement(vnode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1366 const tag = vnode.type;1367 isSVG = isSVG || tag === 'svg';1368 const el = (vnode.el = hostCreateElement(tag, isSVG));1369 const { props, shapeFlag } = vnode;1370 if (props != null) {1371 for (const key in props) {1372 if (isReservedProp(key))1373 continue;1374 hostPatchProp(el, key, props[key], null, isSVG);1375 }1376 if (props.onVnodeBeforeMount != null) {1377 invokeDirectiveHook(props.onVnodeBeforeMount, parentComponent, vnode);1378 }1379 }1380 if (shapeFlag & 8 /* TEXT_CHILDREN */) {1381 hostSetElementText(el, vnode.children);1382 }1383 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1384 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG, optimized || vnode.dynamicChildren !== null);1385 }1386 hostInsert(el, container, anchor);1387 if (props != null && props.onVnodeMounted != null) {1388 queuePostRenderEffect(() => {1389 invokeDirectiveHook(props.onVnodeMounted, parentComponent, vnode);1390 }, parentSuspense);1391 }1392 }1393 function mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, optimized, start = 0) {1394 for (let i = start; i < children.length; i++) {1395 const child = optimized1396 ? children[i]1397 : (children[i] = normalizeVNode(children[i]));1398 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1399 }1400 }1401 function patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized) {1402 const el = (n2.el = n1.el);1403 const { patchFlag, dynamicChildren } = n2;1404 const oldProps = (n1 && n1.props) || EMPTY_OBJ;1405 const newProps = n2.props || EMPTY_OBJ;1406 if (newProps.onVnodeBeforeUpdate != null) {1407 invokeDirectiveHook(newProps.onVnodeBeforeUpdate, parentComponent, n2, n1);1408 }1409 if (patchFlag > 0) {1410 // the presence of a patchFlag means this element's render code was1411 // generated by the compiler and can take the fast path.1412 // in this path old node and new node are guaranteed to have the same shape1413 // (i.e. at the exact same position in the source template)1414 if (patchFlag & 16 /* FULL_PROPS */) {1415 // element props contain dynamic keys, full diff needed1416 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);1417 }1418 else {1419 // class1420 // this flag is matched when the element has dynamic class bindings.1421 if (patchFlag & 2 /* CLASS */) {1422 if (oldProps.class !== newProps.class) {1423 hostPatchProp(el, 'class', newProps.class, null, isSVG);1424 }1425 }1426 // style1427 // this flag is matched when the element has dynamic style bindings1428 if (patchFlag & 4 /* STYLE */) {1429 hostPatchProp(el, 'style', newProps.style, oldProps.style, isSVG);1430 }1431 // props1432 // This flag is matched when the element has dynamic prop/attr bindings1433 // other than class and style. The keys of dynamic prop/attrs are saved for1434 // faster iteration.1435 // Note dynamic keys like :[foo]="bar" will cause this optimization to1436 // bail out and go through a full diff because we need to unset the old key1437 if (patchFlag & 8 /* PROPS */) {1438 // if the flag is present then dynamicProps must be non-null1439 const propsToUpdate = n2.dynamicProps;1440 for (let i = 0; i < propsToUpdate.length; i++) {1441 const key = propsToUpdate[i];1442 const prev = oldProps[key];1443 const next = newProps[key];1444 if (prev !== next) {1445 hostPatchProp(el, key, next, prev, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);1446 }1447 }1448 }1449 }1450 // text1451 // This flag is matched when the element has only dynamic text children.1452 // this flag is terminal (i.e. skips children diffing).1453 if (patchFlag & 1 /* TEXT */) {1454 if (n1.children !== n2.children) {1455 hostSetElementText(el, n2.children);1456 }1457 return; // terminal1458 }1459 }1460 else if (!optimized && dynamicChildren == null) {1461 // unoptimized, full diff1462 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);1463 }1464 if (dynamicChildren != null) {1465 patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, isSVG);1466 }1467 else if (!optimized) {1468 // full diff1469 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, isSVG);1470 }1471 if (newProps.onVnodeUpdated != null) {1472 queuePostRenderEffect(() => {1473 invokeDirectiveHook(newProps.onVnodeUpdated, parentComponent, n2, n1);1474 }, parentSuspense);1475 }1476 }1477 // The fast path for blocks.1478 function patchBlockChildren(oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG) {1479 for (let i = 0; i < newChildren.length; i++) {1480 const oldVNode = oldChildren[i];1481 patch(oldVNode, newChildren[i], 1482 // in the case of a Fragment, we need to provide the actual parent1483 // of the Fragment itself so it can move its children. In other cases,1484 // the parent container is not actually used so we just pass the1485 // block element here to avoid a DOM parentNode call.1486 oldVNode.type === Fragment1487 ? hostParentNode(oldVNode.el)1488 : fallbackContainer, null, parentComponent, parentSuspense, isSVG, true);1489 }1490 }1491 function patchProps(el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) {1492 if (oldProps !== newProps) {1493 for (const key in newProps) {1494 if (isReservedProp(key))1495 continue;1496 const next = newProps[key];1497 const prev = oldProps[key];1498 if (next !== prev) {1499 hostPatchProp(el, key, next, prev, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);1500 }1501 }1502 if (oldProps !== EMPTY_OBJ) {1503 for (const key in oldProps) {1504 if (isReservedProp(key))1505 continue;1506 if (!(key in newProps)) {1507 hostPatchProp(el, key, null, null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);1508 }1509 }1510 }1511 }1512 }1513 function processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1514 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateComment(''));1515 const fragmentEndAnchor = (n2.anchor = n11516 ? n1.anchor1517 : hostCreateComment(''));1518 if (n1 == null) {1519 hostInsert(fragmentStartAnchor, container, anchor);1520 hostInsert(fragmentEndAnchor, container, anchor);1521 // a fragment can only have array children1522 // since they are either generated by the compiler, or implicitly created1523 // from arrays.1524 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);1525 }1526 else {1527 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);1528 }1529 }1530 function processPortal(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1531 const targetSelector = n2.props && n2.props.target;1532 const { patchFlag, shapeFlag, children } = n2;1533 if (n1 == null) {1534 const target = (n2.target = isString(targetSelector)1535 ? hostQuerySelector(targetSelector)1536 : null);1537 if (target != null) {1538 if (shapeFlag & 8 /* TEXT_CHILDREN */) {1539 hostSetElementText(target, children);1540 }1541 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1542 mountChildren(children, target, null, parentComponent, parentSuspense, isSVG, optimized);1543 }1544 }1545 else if (process.env.NODE_ENV !== 'production') {1546 warn('Invalid Portal target on mount:', target, `(${typeof target})`);1547 }1548 }1549 else {1550 // update content1551 const target = (n2.target = n1.target);1552 if (patchFlag === 1 /* TEXT */) {1553 hostSetElementText(target, children);1554 }1555 else if (n2.dynamicChildren) {1556 // fast path when the portal happens to be a block root1557 patchBlockChildren(n1.dynamicChildren, n2.dynamicChildren, container, parentComponent, parentSuspense, isSVG);1558 }1559 else if (!optimized) {1560 patchChildren(n1, n2, target, null, parentComponent, parentSuspense, isSVG);1561 }1562 // target changed1563 if (targetSelector !== (n1.props && n1.props.target)) {1564 const nextTarget = (n2.target = isString(targetSelector)1565 ? hostQuerySelector(targetSelector)1566 : null);1567 if (nextTarget != null) {1568 // move content1569 if (shapeFlag & 8 /* TEXT_CHILDREN */) {1570 hostSetElementText(target, '');1571 hostSetElementText(nextTarget, children);1572 }1573 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1574 for (let i = 0; i < children.length; i++) {1575 move(children[i], nextTarget, null);1576 }1577 }1578 }1579 else if (process.env.NODE_ENV !== 'production') {1580 warn('Invalid Portal target on update:', target, `(${typeof target})`);1581 }1582 }1583 }1584 // insert an empty node as the placeholder for the portal1585 processCommentNode(n1, n2, container, anchor);1586 }1587 function processSuspense(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1588 if (n1 == null) {1589 mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1590 }1591 else {1592 patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized);1593 }1594 }1595 function mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1596 const hiddenContainer = hostCreateElement('div');1597 const suspense = (n2.suspense = createSuspenseBoundary(n2, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, optimized));1598 const { content, fallback } = normalizeSuspenseChildren(n2);1599 suspense.subTree = content;1600 suspense.fallbackTree = fallback;1601 // start mounting the content subtree in an off-dom container1602 patch(null, content, hiddenContainer, null, parentComponent, suspense, isSVG, optimized);1603 // now check if we have encountered any async deps1604 if (suspense.deps > 0) {1605 // mount the fallback tree1606 patch(null, fallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context1607 isSVG, optimized);1608 n2.el = fallback.el;1609 }1610 else {1611 // Suspense has no async deps. Just resolve.1612 resolveSuspense(suspense);1613 }1614 }1615 function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized) {1616 const suspense = (n2.suspense = n1.suspense);1617 suspense.vnode = n2;1618 const { content, fallback } = normalizeSuspenseChildren(n2);1619 const oldSubTree = suspense.subTree;1620 const oldFallbackTree = suspense.fallbackTree;1621 if (!suspense.isResolved) {1622 patch(oldSubTree, content, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized);1623 if (suspense.deps > 0) {1624 // still pending. patch the fallback tree.1625 patch(oldFallbackTree, fallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context1626 isSVG, optimized);1627 n2.el = fallback.el;1628 }1629 // If deps somehow becomes 0 after the patch it means the patch caused an1630 // async dep component to unmount and removed its dep. It will cause the1631 // suspense to resolve and we don't need to do anything here.1632 }1633 else {1634 // just normal patch inner content as a fragment1635 patch(oldSubTree, content, container, anchor, parentComponent, suspense, isSVG, optimized);1636 n2.el = content.el;1637 }1638 suspense.subTree = content;1639 suspense.fallbackTree = fallback;1640 }1641 function resolveSuspense(suspense) {1642 if (process.env.NODE_ENV !== 'production') {1643 if (suspense.isResolved) {1644 throw new Error(`resolveSuspense() is called on an already resolved suspense boundary.`);1645 }1646 if (suspense.isUnmounted) {1647 throw new Error(`resolveSuspense() is called on an already unmounted suspense boundary.`);1648 }1649 }1650 const { vnode, subTree, fallbackTree, effects, parentComponent, container } = suspense;1651 // this is initial anchor on mount1652 let { anchor } = suspense;1653 // unmount fallback tree1654 if (fallbackTree.el) {1655 // if the fallback tree was mounted, it may have been moved1656 // as part of a parent suspense. get the latest anchor for insertion1657 anchor = getNextHostNode(fallbackTree);1658 unmount(fallbackTree, parentComponent, suspense, true);1659 }1660 // move content from off-dom container to actual container1661 move(subTree, container, anchor);1662 const el = (vnode.el = subTree.el);1663 // suspense as the root node of a component...1664 if (parentComponent && parentComponent.subTree === vnode) {1665 parentComponent.vnode.el = el;1666 updateHOCHostEl(parentComponent, el);1667 }1668 // check if there is a pending parent suspense1669 let parent = suspense.parent;1670 let hasUnresolvedAncestor = false;1671 while (parent) {1672 if (!parent.isResolved) {1673 // found a pending parent suspense, merge buffered post jobs1674 // into that parent1675 parent.effects.push(...effects);1676 hasUnresolvedAncestor = true;1677 break;1678 }1679 parent = parent.parent;1680 }1681 // no pending parent suspense, flush all jobs1682 if (!hasUnresolvedAncestor) {1683 queuePostFlushCb(effects);1684 }1685 suspense.isResolved = true;1686 // invoke @resolve event1687 const onResolve = vnode.props && vnode.props.onResolve;1688 if (isFunction(onResolve)) {1689 onResolve();1690 }1691 }1692 function restartSuspense(suspense) {1693 suspense.isResolved = false;1694 const { vnode, subTree, fallbackTree, parentComponent, container, hiddenContainer, isSVG, optimized } = suspense;1695 // move content tree back to the off-dom container1696 const anchor = getNextHostNode(subTree);1697 move(subTree, hiddenContainer, null);1698 // remount the fallback tree1699 patch(null, fallbackTree, container, anchor, parentComponent, null, // fallback tree will not have suspense context1700 isSVG, optimized);1701 const el = (vnode.el = fallbackTree.el);1702 // suspense as the root node of a component...1703 if (parentComponent && parentComponent.subTree === vnode) {1704 parentComponent.vnode.el = el;1705 updateHOCHostEl(parentComponent, el);1706 }1707 // invoke @suspense event1708 const onSuspense = vnode.props && vnode.props.onSuspense;1709 if (isFunction(onSuspense)) {1710 onSuspense();1711 }1712 }1713 function processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1714 if (n1 == null) {1715 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG);1716 }1717 else {1718 const instance = (n2.component = n1.component);1719 if (shouldUpdateComponent(n1, n2, optimized)) {1720 if (1721 instance.asyncDep &&1722 !instance.asyncResolved) {1723 // async & still pending - just update props and slots1724 // since the component's reactive effect for render isn't set-up yet1725 if (process.env.NODE_ENV !== 'production') {1726 pushWarningContext(n2);1727 }1728 updateComponentPreRender(instance, n2);1729 if (process.env.NODE_ENV !== 'production') {1730 popWarningContext();1731 }1732 return;1733 }1734 else {1735 // normal update1736 instance.next = n2;1737 // instance.update is the reactive effect runner.1738 instance.update();1739 }1740 }1741 else {1742 // no update needed. just copy over properties1743 n2.component = n1.component;1744 n2.el = n1.el;1745 }1746 }1747 if (n2.ref !== null && parentComponent !== null) {1748 setRef(n2.ref, n1 && n1.ref, parentComponent, n2.component.renderProxy);1749 }1750 }1751 function mountComponent(initialVNode, container, anchor, parentComponent, parentSuspense, isSVG) {1752 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent));1753 if (process.env.NODE_ENV !== 'production') {1754 pushWarningContext(initialVNode);1755 }1756 // resolve props and slots for setup context1757 const propsOptions = initialVNode.type.props;1758 resolveProps(instance, initialVNode.props, propsOptions);1759 resolveSlots(instance, initialVNode.children);1760 // setup stateful logic1761 if (initialVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {1762 setupStatefulComponent(instance, parentSuspense);1763 }1764 // setup() is async. This component relies on async logic to be resolved1765 // before proceeding1766 if ( instance.asyncDep) {1767 if (!parentSuspense) {1768 // TODO handle this properly1769 throw new Error('Async component without a suspense boundary!');1770 }1771 // parent suspense already resolved, need to re-suspense1772 // use queueJob so it's handled synchronously after patching the current1773 // suspense tree1774 if (parentSuspense.isResolved) {1775 queueJob(() => {1776 restartSuspense(parentSuspense);1777 });1778 }1779 parentSuspense.deps++;1780 instance.asyncDep1781 .catch(err => {1782 handleError(err, instance, 0 /* SETUP_FUNCTION */);1783 })1784 .then(asyncSetupResult => {1785 // component may be unmounted before resolve1786 if (!instance.isUnmounted && !parentSuspense.isUnmounted) {1787 retryAsyncComponent(instance, asyncSetupResult, parentSuspense, isSVG);1788 }1789 });1790 // give it a placeholder1791 const placeholder = (instance.subTree = createVNode(Comment));1792 processCommentNode(null, placeholder, container, anchor);1793 initialVNode.el = placeholder.el;1794 return;1795 }1796 setupRenderEffect(instance, parentSuspense, initialVNode, container, anchor, isSVG);1797 if (process.env.NODE_ENV !== 'production') {1798 popWarningContext();1799 }1800 }1801 function retryAsyncComponent(instance, asyncSetupResult, parentSuspense, isSVG) {1802 parentSuspense.deps--;1803 // retry from this component1804 instance.asyncResolved = true;1805 const { vnode } = instance;1806 if (process.env.NODE_ENV !== 'production') {1807 pushWarningContext(vnode);1808 }1809 handleSetupResult(instance, asyncSetupResult, parentSuspense);1810 setupRenderEffect(instance, parentSuspense, vnode, 1811 // component may have been moved before resolve1812 hostParentNode(instance.subTree.el), getNextHostNode(instance.subTree), isSVG);1813 updateHOCHostEl(instance, vnode.el);1814 if (process.env.NODE_ENV !== 'production') {1815 popWarningContext();1816 }1817 if (parentSuspense.deps === 0) {1818 resolveSuspense(parentSuspense);1819 }1820 }1821 function setupRenderEffect(instance, parentSuspense, initialVNode, container, anchor, isSVG) {1822 // create reactive effect for rendering1823 let mounted = false;1824 instance.update = effect(function componentEffect() {1825 if (!mounted) {1826 const subTree = (instance.subTree = renderComponentRoot(instance));1827 // beforeMount hook1828 if (instance.bm !== null) {1829 invokeHooks(instance.bm);1830 }1831 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);1832 initialVNode.el = subTree.el;1833 // mounted hook1834 if (instance.m !== null) {1835 queuePostRenderEffect(instance.m, parentSuspense);1836 }1837 mounted = true;1838 }1839 else {1840 // updateComponent1841 // This is triggered by mutation of component's own state (next: null)1842 // OR parent calling processComponent (next: HostVNode)1843 const { next } = instance;1844 if (process.env.NODE_ENV !== 'production') {1845 pushWarningContext(next || instance.vnode);1846 }1847 if (next !== null) {1848 updateComponentPreRender(instance, next);1849 }1850 const prevTree = instance.subTree;1851 const nextTree = (instance.subTree = renderComponentRoot(instance));1852 // beforeUpdate hook1853 if (instance.bu !== null) {1854 invokeHooks(instance.bu);1855 }1856 // reset refs1857 // only needed if previous patch had refs1858 if (instance.refs !== EMPTY_OBJ) {1859 instance.refs = {};1860 }1861 patch(prevTree, nextTree, 1862 // parent may have changed if it's in a portal1863 hostParentNode(prevTree.el), 1864 // anchor may have changed if it's in a fragment1865 getNextHostNode(prevTree), instance, parentSuspense, isSVG);1866 instance.vnode.el = nextTree.el;1867 if (next === null) {1868 // self-triggered update. In case of HOC, update parent component1869 // vnode el. HOC is indicated by parent instance's subTree pointing1870 // to child component's vnode1871 updateHOCHostEl(instance, nextTree.el);1872 }1873 // updated hook1874 if (instance.u !== null) {1875 queuePostRenderEffect(instance.u, parentSuspense);1876 }1877 if (process.env.NODE_ENV !== 'production') {1878 popWarningContext();1879 }1880 }1881 }, process.env.NODE_ENV !== 'production' ? createDevEffectOptions(instance) : prodEffectOptions);1882 }1883 function updateComponentPreRender(instance, nextVNode) {1884 nextVNode.component = instance;1885 instance.vnode = nextVNode;1886 instance.next = null;1887 resolveProps(instance, nextVNode.props, nextVNode.type.props);1888 resolveSlots(instance, nextVNode.children);1889 }1890 function updateHOCHostEl({ vnode, parent }, el) {1891 while (parent && parent.subTree === vnode) {1892 (vnode = parent.vnode).el = el;1893 parent = parent.parent;1894 }1895 }1896 function patchChildren(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized = false) {1897 const c1 = n1 && n1.children;1898 const prevShapeFlag = n1 ? n1.shapeFlag : 0;1899 const c2 = n2.children;1900 const { patchFlag, shapeFlag } = n2;1901 if (patchFlag === -1 /* BAIL */) {1902 optimized = false;1903 }1904 // fast path1905 if (patchFlag > 0) {1906 if (patchFlag & 64 /* KEYED_FRAGMENT */) {1907 // this could be either fully-keyed or mixed (some keyed some not)1908 // presence of patchFlag means children are guaranteed to be arrays1909 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1910 return;1911 }1912 else if (patchFlag & 128 /* UNKEYED_FRAGMENT */) {1913 // unkeyed1914 patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1915 return;1916 }1917 }1918 // children has 3 possibilities: text, array or no children.1919 if (shapeFlag & 8 /* TEXT_CHILDREN */) {1920 // text children fast path1921 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {1922 unmountChildren(c1, parentComponent, parentSuspense);1923 }1924 if (c2 !== c1) {1925 hostSetElementText(container, c2);1926 }1927 }1928 else {1929 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {1930 // prev children was array1931 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1932 // two arrays, cannot assume anything, do full diff1933 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1934 }1935 else {1936 // no new children, just unmount old1937 unmountChildren(c1, parentComponent, parentSuspense, true);1938 }1939 }1940 else {1941 // prev children was text OR null1942 // new children is array OR null1943 if (prevShapeFlag & 8 /* TEXT_CHILDREN */) {1944 hostSetElementText(container, '');1945 }1946 // mount new if array1947 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1948 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1949 }1950 }1951 }1952 }1953 function patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1954 c1 = c1 || EMPTY_ARR;1955 c2 = c2 || EMPTY_ARR;1956 const oldLength = c1.length;1957 const newLength = c2.length;1958 const commonLength = Math.min(oldLength, newLength);1959 let i;1960 for (i = 0; i < commonLength; i++) {1961 const nextChild = optimized1962 ? c2[i]1963 : (c2[i] = normalizeVNode(c2[i]));1964 patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, optimized);1965 }1966 if (oldLength > newLength) {1967 // remove old1968 unmountChildren(c1, parentComponent, parentSuspense, true, commonLength);1969 }1970 else {1971 // mount new1972 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, commonLength);1973 }1974 }1975 // can be all-keyed or mixed1976 function patchKeyedChildren(c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, optimized) {1977 let i = 0;1978 const l2 = c2.length;1979 let e1 = c1.length - 1; // prev ending index1980 let e2 = l2 - 1; // next ending index1981 // 1. sync from start1982 // (a b) c1983 // (a b) d e1984 while (i <= e1 && i <= e2) {1985 const n1 = c1[i];1986 const n2 = optimized1987 ? c2[i]1988 : (c2[i] = normalizeVNode(c2[i]));1989 if (isSameType$1(n1, n2)) {1990 patch(n1, n2, container, parentAnchor, parentComponent, parentSuspense, isSVG, optimized);1991 }1992 else {1993 break;1994 }1995 i++;1996 }1997 // 2. sync from end1998 // a (b c)1999 // d e (b c)2000 while (i <= e1 && i <= e2) {2001 const n1 = c1[e1];2002 const n2 = optimized2003 ? c2[i]2004 : (c2[e2] = normalizeVNode(c2[e2]));2005 if (isSameType$1(n1, n2)) {2006 patch(n1, n2, container, parentAnchor, parentComponent, parentSuspense, isSVG, optimized);2007 }2008 else {2009 break;2010 }2011 e1--;2012 e2--;2013 }2014 // 3. common sequence + mount2015 // (a b)2016 // (a b) c2017 // i = 2, e1 = 1, e2 = 22018 // (a b)2019 // c (a b)2020 // i = 0, e1 = -1, e2 = 02021 if (i > e1) {2022 if (i <= e2) {2023 const nextPos = e2 + 1;2024 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;2025 while (i <= e2) {2026 patch(null, optimized ? c2[i] : (c2[i] = normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG);2027 i++;2028 }2029 }2030 }2031 // 4. common sequence + unmount2032 // (a b) c2033 // (a b)2034 // i = 2, e1 = 2, e2 = 12035 // a (b c)2036 // (b c)2037 // i = 0, e1 = 0, e2 = -12038 else if (i > e2) {2039 while (i <= e1) {2040 unmount(c1[i], parentComponent, parentSuspense, true);2041 i++;2042 }2043 }2044 // 5. unknown sequence2045 // [i ... e1 + 1]: a b [c d e] f g2046 // [i ... e2 + 1]: a b [e d c h] f g2047 // i = 2, e1 = 4, e2 = 52048 else {2049 const s1 = i; // prev starting index2050 const s2 = i; // next starting index2051 // 5.1 build key:index map for newChildren2052 const keyToNewIndexMap = new Map();2053 for (i = s2; i <= e2; i++) {2054 const nextChild = optimized2055 ? c2[i]2056 : (c2[i] = normalizeVNode(c2[i]));2057 if (nextChild.key != null) {2058 if (process.env.NODE_ENV !== 'production' && keyToNewIndexMap.has(nextChild.key)) {2059 warn(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`);2060 }2061 keyToNewIndexMap.set(nextChild.key, i);2062 }2063 }2064 // 5.2 loop through old children left to be patched and try to patch2065 // matching nodes & remove nodes that are no longer present2066 let j;2067 let patched = 0;2068 const toBePatched = e2 - s2 + 1;2069 let moved = false;2070 // used to track whether any node has moved2071 let maxNewIndexSoFar = 0;2072 // works as Map<newIndex, oldIndex>2073 // Note that oldIndex is offset by +12074 // and oldIndex = 0 is a special value indicating the new node has2075 // no corresponding old node.2076 // used for determining longest stable subsequence2077 const newIndexToOldIndexMap = new Array(toBePatched);2078 for (i = 0; i < toBePatched; i++)2079 newIndexToOldIndexMap[i] = 0;2080 for (i = s1; i <= e1; i++) {2081 const prevChild = c1[i];2082 if (patched >= toBePatched) {2083 // all new children have been patched so this can only be a removal2084 unmount(prevChild, parentComponent, parentSuspense, true);2085 continue;2086 }2087 let newIndex;2088 if (prevChild.key != null) {2089 newIndex = keyToNewIndexMap.get(prevChild.key);2090 }2091 else {2092 // key-less node, try to locate a key-less node of the same type2093 for (j = s2; j <= e2; j++) {2094 if (newIndexToOldIndexMap[j - s2] === 0 &&2095 isSameType$1(prevChild, c2[j])) {2096 newIndex = j;2097 break;2098 }2099 }2100 }2101 if (newIndex === undefined) {2102 unmount(prevChild, parentComponent, parentSuspense, true);2103 }2104 else {2105 newIndexToOldIndexMap[newIndex - s2] = i + 1;2106 if (newIndex >= maxNewIndexSoFar) {2107 maxNewIndexSoFar = newIndex;2108 }2109 else {2110 moved = true;2111 }2112 patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, optimized);2113 patched++;2114 }2115 }2116 // 5.3 move and mount2117 // generate longest stable subsequence only when nodes have moved2118 const increasingNewIndexSequence = moved2119 ? getSequence(newIndexToOldIndexMap)2120 : EMPTY_ARR;2121 j = increasingNewIndexSequence.length - 1;2122 // looping backwards so that we can use last patched node as anchor2123 for (i = toBePatched - 1; i >= 0; i--) {2124 const nextIndex = s2 + i;2125 const nextChild = c2[nextIndex];2126 const anchor = nextIndex + 1 < l22127 ? c2[nextIndex + 1].el2128 : parentAnchor;2129 if (newIndexToOldIndexMap[i] === 0) {2130 // mount new2131 patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG);2132 }2133 else if (moved) {2134 // move if:2135 // There is no stable subsequence (e.g. a reverse)2136 // OR current node is not among the stable sequence2137 if (j < 0 || i !== increasingNewIndexSequence[j]) {2138 move(nextChild, container, anchor);2139 }2140 else {2141 j--;2142 }2143 }2144 }2145 }2146 }2147 function move(vnode, container, anchor) {2148 if (vnode.component !== null) {2149 move(vnode.component.subTree, container, anchor);2150 return;2151 }2152 if ( vnode.type === Suspense) {2153 const suspense = vnode.suspense;2154 move(suspense.isResolved ? suspense.subTree : suspense.fallbackTree, container, anchor);2155 suspense.container = container;2156 return;2157 }2158 if (vnode.type === Fragment) {2159 hostInsert(vnode.el, container, anchor);2160 const children = vnode.children;2161 for (let i = 0; i < children.length; i++) {2162 move(children[i], container, anchor);2163 }2164 hostInsert(vnode.anchor, container, anchor);2165 }2166 else {2167 hostInsert(vnode.el, container, anchor);2168 }2169 }2170 function unmount(vnode, parentComponent, parentSuspense, doRemove) {2171 const { props, ref, type, component, suspense, children, dynamicChildren, shapeFlag, anchor } = vnode;2172 // unset ref2173 if (ref !== null && parentComponent !== null) {2174 setRef(ref, null, parentComponent, null);2175 }2176 if (component != null) {2177 unmountComponent(component, parentSuspense, doRemove);2178 return;2179 }2180 if ( suspense != null) {2181 unmountSuspense(suspense, parentComponent, parentSuspense, doRemove);2182 return;2183 }2184 if (props != null && props.onVnodeBeforeUnmount != null) {2185 invokeDirectiveHook(props.onVnodeBeforeUnmount, parentComponent, vnode);2186 }2187 const shouldRemoveChildren = type === Fragment && doRemove;2188 if (dynamicChildren != null) {2189 unmountChildren(dynamicChildren, parentComponent, parentSuspense, shouldRemoveChildren);2190 }2191 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {2192 unmountChildren(children, parentComponent, parentSuspense, shouldRemoveChildren);2193 }2194 if (doRemove) {2195 hostRemove(vnode.el);2196 if (anchor != null)2197 hostRemove(anchor);2198 }2199 if (props != null && props.onVnodeUnmounted != null) {2200 queuePostRenderEffect(() => {2201 invokeDirectiveHook(props.onVnodeUnmounted, parentComponent, vnode);2202 }, parentSuspense);2203 }2204 }2205 function unmountComponent(instance, parentSuspense, doRemove) {2206 const { bum, effects, update, subTree, um } = instance;2207 // beforeUnmount hook2208 if (bum !== null) {2209 invokeHooks(bum);2210 }2211 if (effects !== null) {2212 for (let i = 0; i < effects.length; i++) {2213 stop(effects[i]);2214 }2215 }2216 // update may be null if a component is unmounted before its async2217 // setup has resolved.2218 if (update !== null) {2219 stop(update);2220 unmount(subTree, instance, parentSuspense, doRemove);2221 }2222 // unmounted hook2223 if (um !== null) {2224 queuePostRenderEffect(um, parentSuspense);2225 }2226 queuePostFlushCb(() => {2227 instance.isUnmounted = true;2228 });2229 // A component with async dep inside a pending suspense is unmounted before2230 // its async dep resolves. This should remove the dep from the suspense, and2231 // cause the suspense to resolve immediately if that was the last dep.2232 if (2233 parentSuspense !== null &&2234 !parentSuspense.isResolved &&2235 !parentSuspense.isUnmounted &&2236 instance.asyncDep !== null &&2237 !instance.asyncResolved) {2238 parentSuspense.deps--;2239 if (parentSuspense.deps === 0) {2240 resolveSuspense(parentSuspense);2241 }2242 }2243 }2244 function unmountSuspense(suspense, parentComponent, parentSuspense, doRemove) {2245 suspense.isUnmounted = true;2246 unmount(suspense.subTree, parentComponent, parentSuspense, doRemove);2247 if (!suspense.isResolved) {2248 unmount(suspense.fallbackTree, parentComponent, parentSuspense, doRemove);2249 }2250 }2251 function unmountChildren(children, parentComponent, parentSuspense, doRemove, start = 0) {2252 for (let i = start; i < children.length; i++) {2253 unmount(children[i], parentComponent, parentSuspense, doRemove);2254 }2255 }2256 function getNextHostNode({ component, suspense, anchor, el }) {2257 if (component !== null) {2258 return getNextHostNode(component.subTree);2259 }2260 if ( suspense !== null) {2261 return getNextHostNode(suspense.isResolved ? suspense.subTree : suspense.fallbackTree);2262 }2263 return hostNextSibling((anchor || el));2264 }2265 function setRef(ref, oldRef, parent, value) {2266 const refs = parent.refs === EMPTY_OBJ ? (parent.refs = {}) : parent.refs;2267 const renderContext = toRaw(parent.renderContext);2268 // unset old ref2269 if (oldRef !== null && oldRef !== ref) {2270 if (isString(oldRef)) {2271 refs[oldRef] = null;2272 const oldSetupRef = renderContext[oldRef];2273 if (isRef(oldSetupRef)) {2274 oldSetupRef.value = null;2275 }2276 }2277 else if (isRef(oldRef)) {2278 oldRef.value = null;2279 }2280 }2281 if (isString(ref)) {2282 const setupRef = renderContext[ref];2283 if (isRef(setupRef)) {2284 setupRef.value = value;2285 }2286 refs[ref] = value;2287 }2288 else if (isRef(ref)) {2289 ref.value = value;2290 }2291 else if (isFunction(ref)) {2292 ref(value, refs);2293 }2294 else if (process.env.NODE_ENV !== 'production') {2295 warn('Invalid template ref type:', value, `(${typeof value})`);2296 }2297 }2298 function render(vnode, rawContainer) {2299 let container = rawContainer;2300 if (isString(container)) {2301 container = hostQuerySelector(container);2302 if (!container) {2303 if (process.env.NODE_ENV !== 'production') {2304 warn(`Failed to locate root container: ` + `querySelector returned null.`);2305 }2306 return;2307 }2308 }2309 if (vnode == null) {2310 if (container._vnode) {2311 unmount(container._vnode, null, null, true);2312 }2313 }2314 else {2315 patch(container._vnode || null, vnode, container);2316 }2317 flushPostFlushCbs();2318 container._vnode = vnode;2319 }2320 return {2321 render,2322 createApp: createAppAPI(render)2323 };2324}2325// https://en.wikipedia.org/wiki/Longest_increasing_subsequence2326function getSequence(arr) {2327 const p = arr.slice();2328 const result = [0];2329 let i, j, u, v, c;2330 const len = arr.length;2331 for (i = 0; i < len; i++) {2332 const arrI = arr[i];2333 if (arrI !== 0) {2334 j = result[result.length - 1];2335 if (arr[j] < arrI) {2336 p[i] = j;2337 result.push(i);2338 continue;2339 }2340 u = 0;2341 v = result.length - 1;2342 while (u < v) {2343 c = ((u + v) / 2) | 0;2344 if (arr[result[c]] < arrI) {2345 u = c + 1;2346 }2347 else {2348 v = c;2349 }2350 }2351 if (arrI < arr[result[u]]) {2352 if (u > 0) {2353 p[i] = result[u - 1];2354 }2355 result[u] = i;2356 }2357 }2358 }2359 u = result.length;2360 v = result[u - 1];2361 while (u-- > 0) {2362 result[u] = v;2363 v = p[v];2364 }2365 return result;2366}2367const invoke = (fn) => fn();2368// implementation2369function watch(effectOrSource, cbOrOptions, options) {2370 if (isFunction(cbOrOptions)) {2371 // effect callback as 2nd argument - this is a source watcher2372 return doWatch(effectOrSource, cbOrOptions, options);2373 }2374 else {2375 // 2nd argument is either missing or an options object2376 // - this is a simple effect watcher2377 return doWatch(effectOrSource, null, cbOrOptions);2378 }2379}2380function doWatch(source, cb, { lazy, deep, flush, onTrack, onTrigger } = EMPTY_OBJ) {2381 const instance = currentInstance;2382 const suspense = currentSuspense;2383 let getter;2384 if (isArray(source)) {2385 getter = () => source.map(s => isRef(s)2386 ? s.value2387 : callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */));2388 }2389 else if (isRef(source)) {2390 getter = () => source.value;2391 }2392 else if (cb) {2393 // getter with cb2394 getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */);2395 }2396 else {2397 // no cb -> simple effect2398 getter = () => {2399 if (instance && instance.isUnmounted) {2400 return;2401 }2402 if (cleanup) {2403 cleanup();2404 }2405 return callWithErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [registerCleanup]);2406 };2407 }2408 if (deep) {2409 const baseGetter = getter;2410 getter = () => traverse(baseGetter());2411 }2412 let cleanup;2413 const registerCleanup = (fn) => {2414 // TODO wrap the cleanup fn for error handling2415 cleanup = runner.onStop = () => {2416 callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */);2417 };2418 };2419 let oldValue = isArray(source) ? [] : undefined;2420 const applyCb = cb2421 ? () => {2422 if (instance && instance.isUnmounted) {2423 return;2424 }2425 const newValue = runner();2426 if (deep || newValue !== oldValue) {2427 // cleanup before running cb again2428 if (cleanup) {2429 cleanup();2430 }2431 callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [2432 newValue,2433 oldValue,2434 registerCleanup2435 ]);2436 oldValue = newValue;2437 }2438 }2439 : void 0;2440 let scheduler;2441 if (flush === 'sync') {2442 scheduler = invoke;2443 }2444 else if (flush === 'pre') {2445 scheduler = job => {2446 if (!instance || instance.vnode.el != null) {2447 queueJob(job);2448 }2449 else {2450 // with 'pre' option, the first call must happen before2451 // the component is mounted so it is called synchronously.2452 job();2453 }2454 };2455 }2456 else {2457 scheduler = job => {2458 queuePostRenderEffect(job, suspense);2459 };2460 }2461 const runner = effect(getter, {2462 lazy: true,2463 // so it runs before component update effects in pre flush mode2464 computed: true,2465 onTrack,2466 onTrigger,2467 scheduler: applyCb ? () => scheduler(applyCb) : scheduler2468 });2469 if (!lazy) {2470 if (applyCb) {2471 scheduler(applyCb);2472 }2473 else {2474 scheduler(runner);2475 }2476 }2477 else {2478 oldValue = runner();2479 }2480 recordEffect(runner);2481 return () => {2482 stop(runner);2483 };2484}2485// this.$watch2486function instanceWatch(source, cb, options) {2487 const ctx = this.renderProxy;2488 const getter = isString(source) ? () => ctx[source] : source.bind(ctx);2489 const stop = watch(getter, cb.bind(ctx), options);2490 onBeforeUnmount(stop, this);2491 return stop;2492}2493function traverse(value, seen = new Set()) {2494 if (!isObject(value) || seen.has(value)) {2495 return;2496 }2497 seen.add(value);2498 if (isArray(value)) {2499 for (let i = 0; i < value.length; i++) {2500 traverse(value[i], seen);2501 }2502 }2503 else if (value instanceof Map) {2504 value.forEach((v, key) => {2505 // to register mutation dep for existing keys2506 traverse(value.get(key), seen);2507 });2508 }2509 else if (value instanceof Set) {2510 value.forEach(v => {2511 traverse(v, seen);2512 });2513 }2514 else {2515 for (const key in value) {2516 traverse(value[key], seen);2517 }2518 }2519 return value;2520}2521const publicPropertiesMap = {2522 $data: 'data',2523 $props: 'propsProxy',2524 $attrs: 'attrs',2525 $slots: 'slots',2526 $refs: 'refs',2527 $parent: 'parent',2528 $root: 'root',2529 $emit: 'emit',2530 $options: 'type'2531};2532const PublicInstanceProxyHandlers = {2533 get(target, key) {2534 const { renderContext, data, props, propsProxy, accessCache, type } = target;2535 // This getter gets called for every property access on the render context2536 // during render and is a major hotspot. The most expensive part of this2537 // is the multiple hasOwn() calls. It's much faster to do a simple property2538 // access on a plain object, so we use an accessCache object (with null2539 // prototype) to memoize what access type a key corresponds to.2540 const n = accessCache[key];2541 if (n !== undefined) {2542 switch (n) {2543 case 0 /* DATA */:2544 return data[key];2545 case 1 /* CONTEXT */:2546 return renderContext[key];2547 case 2 /* PROPS */:2548 return propsProxy[key];2549 }2550 }2551 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {2552 accessCache[key] = 0 /* DATA */;2553 return data[key];2554 }2555 else if (hasOwn(renderContext, key)) {2556 accessCache[key] = 1 /* CONTEXT */;2557 return renderContext[key];2558 }2559 else if (hasOwn(props, key)) {2560 // only cache props access if component has declared (thus stable) props2561 if (type.props != null) {2562 accessCache[key] = 2 /* PROPS */;2563 }2564 // return the value from propsProxy for ref unwrapping and readonly2565 return propsProxy[key];2566 }2567 else if (key === '$cache') {2568 return target.renderCache || (target.renderCache = []);2569 }2570 else if (key === '$el') {2571 return target.vnode.el;2572 }2573 else if (hasOwn(publicPropertiesMap, key)) {2574 return target[publicPropertiesMap[key]];2575 }2576 // methods are only exposed when options are supported2577 {2578 switch (key) {2579 case '$forceUpdate':2580 return target.update;2581 case '$nextTick':2582 return nextTick;2583 case '$watch':2584 return instanceWatch.bind(target);2585 }2586 }2587 return target.user[key];2588 },2589 set(target, key, value) {2590 const { data, renderContext } = target;2591 if (data !== EMPTY_OBJ && hasOwn(data, key)) {2592 data[key] = value;2593 }2594 else if (hasOwn(renderContext, key)) {2595 renderContext[key] = value;2596 }2597 else if (key[0] === '$' && key.slice(1) in target) {2598 process.env.NODE_ENV !== 'production' &&2599 warn(`Attempting to mutate public property "${key}". ` +2600 `Properties starting with $ are reserved and readonly.`, target);2601 return false;2602 }2603 else if (key in target.props) {2604 process.env.NODE_ENV !== 'production' &&2605 warn(`Attempting to mutate prop "${key}". Props are readonly.`, target);2606 return false;2607 }2608 else {2609 target.user[key] = value;2610 }2611 return true;2612 }2613};2614function provide(key, value) {2615 if (!currentInstance) {2616 if (process.env.NODE_ENV !== 'production') {2617 warn(`provide() can only be used inside setup().`);2618 }2619 }2620 else {2621 let provides = currentInstance.provides;2622 // by default an instance inherits its parent's provides object2623 // but when it needs to provide values of its own, it creates its2624 // own provides object using parent provides object as prototype.2625 // this way in `inject` we can simply look up injections from direct2626 // parent and let the prototype chain do the work.2627 const parentProvides = currentInstance.parent && currentInstance.parent.provides;2628 if (parentProvides === provides) {2629 provides = currentInstance.provides = Object.create(parentProvides);2630 }2631 // TS doesn't allow symbol as index type2632 provides[key] = value;2633 }2634}2635function inject(key, defaultValue) {2636 if (currentInstance) {2637 const provides = currentInstance.provides;2638 if (key in provides) {2639 // TS doesn't allow symbol as index type2640 return provides[key];2641 }2642 else if (defaultValue !== undefined) {2643 return defaultValue;2644 }2645 else if (process.env.NODE_ENV !== 'production') {2646 warn(`injection "${key}" not found.`);2647 }2648 }2649 else if (process.env.NODE_ENV !== 'production') {2650 warn(`inject() can only be used inside setup().`);2651 }2652}2653function applyOptions(instance, options, asMixin = false) {2654 const renderContext = instance.renderContext === EMPTY_OBJ2655 ? (instance.renderContext = reactive({}))2656 : instance.renderContext;2657 const ctx = instance.renderProxy;2658 const { 2659 // composition2660 mixins, extends: extendsOptions, 2661 // state2662 data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions, 2663 // assets2664 components, directives, 2665 // lifecycle2666 beforeMount, mounted, beforeUpdate, updated, 2667 // TODO activated2668 // TODO deactivated2669 beforeUnmount, unmounted, renderTracked, renderTriggered, errorCaptured } = options;2670 const globalMixins = instance.appContext.mixins;2671 // applyOptions is called non-as-mixin once per instance2672 if (!asMixin) {2673 callSyncHook('beforeCreate', options, ctx, globalMixins);2674 // global mixins are applied first2675 applyMixins(instance, globalMixins);2676 }2677 // extending a base component...2678 if (extendsOptions) {2679 applyOptions(instance, extendsOptions, true);2680 }2681 // local mixins2682 if (mixins) {2683 applyMixins(instance, mixins);2684 }2685 // state options2686 if (dataOptions) {2687 const data = isFunction(dataOptions) ? dataOptions.call(ctx) : dataOptions;2688 if (!isObject(data)) {2689 process.env.NODE_ENV !== 'production' && warn(`data() should return an object.`);2690 }2691 else if (instance.data === EMPTY_OBJ) {2692 instance.data = reactive(data);2693 }2694 else {2695 // existing data: this is a mixin or extends.2696 extend(instance.data, data);2697 }2698 }2699 if (computedOptions) {2700 for (const key in computedOptions) {2701 const opt = computedOptions[key];2702 if (isFunction(opt)) {2703 renderContext[key] = computed(opt.bind(ctx));2704 }2705 else {2706 const { get, set } = opt;2707 if (isFunction(get)) {2708 renderContext[key] = computed({2709 get: get.bind(ctx),2710 set: isFunction(set)2711 ? set.bind(ctx)2712 : process.env.NODE_ENV !== 'production'2713 ? () => {2714 warn(`Computed property "${key}" was assigned to but it has no setter.`);2715 }2716 : NOOP2717 });2718 }2719 else if (process.env.NODE_ENV !== 'production') {2720 warn(`Computed property "${key}" has no getter.`);2721 }2722 }2723 }2724 }2725 if (methods) {2726 for (const key in methods) {2727 renderContext[key] = methods[key].bind(ctx);2728 }2729 }2730 if (watchOptions) {2731 for (const key in watchOptions) {2732 const raw = watchOptions[key];2733 const getter = () => ctx[key];2734 if (isString(raw)) {2735 const handler = renderContext[raw];2736 if (isFunction(handler)) {2737 watch(getter, handler);2738 }2739 else if (process.env.NODE_ENV !== 'production') {2740 warn(`Invalid watch handler specified by key "${raw}"`, handler);2741 }2742 }2743 else if (isFunction(raw)) {2744 watch(getter, raw.bind(ctx));2745 }2746 else if (isObject(raw)) {2747 // TODO 2.x compat2748 watch(getter, raw.handler.bind(ctx), raw);2749 }2750 else if (process.env.NODE_ENV !== 'production') {2751 warn(`Invalid watch option: "${key}"`);2752 }2753 }2754 }2755 if (provideOptions) {2756 const provides = isFunction(provideOptions)2757 ? provideOptions.call(ctx)2758 : provideOptions;2759 for (const key in provides) {2760 provide(key, provides[key]);2761 }2762 }2763 if (injectOptions) {2764 if (isArray(injectOptions)) {2765 for (let i = 0; i < injectOptions.length; i++) {2766 const key = injectOptions[i];2767 renderContext[key] = inject(key);2768 }2769 }2770 else {2771 for (const key in injectOptions) {2772 const opt = injectOptions[key];2773 if (isObject(opt)) {2774 renderContext[key] = inject(opt.from, opt.default);2775 }2776 else {2777 renderContext[key] = inject(opt);2778 }2779 }2780 }2781 }2782 // asset options2783 if (components) {2784 extend(instance.components, components);2785 }2786 if (directives) {2787 extend(instance.directives, directives);2788 }2789 // lifecycle options2790 if (!asMixin) {2791 callSyncHook('created', options, ctx, globalMixins);2792 }2793 if (beforeMount) {2794 onBeforeMount(beforeMount.bind(ctx));2795 }2796 if (mounted) {2797 onMounted(mounted.bind(ctx));2798 }2799 if (beforeUpdate) {2800 onBeforeUpdate(beforeUpdate.bind(ctx));2801 }2802 if (updated) {2803 onUpdated(updated.bind(ctx));2804 }2805 if (errorCaptured) {2806 onErrorCaptured(errorCaptured.bind(ctx));2807 }2808 if (renderTracked) {2809 onRenderTracked(renderTracked.bind(ctx));2810 }2811 if (renderTriggered) {2812 onRenderTriggered(renderTriggered.bind(ctx));2813 }2814 if (beforeUnmount) {2815 onBeforeUnmount(beforeUnmount.bind(ctx));2816 }2817 if (unmounted) {2818 onUnmounted(unmounted.bind(ctx));2819 }2820}2821function callSyncHook(name, options, ctx, globalMixins) {2822 callHookFromMixins(name, globalMixins, ctx);2823 const baseHook = options.extends && options.extends[name];2824 if (baseHook) {2825 baseHook.call(ctx);2826 }2827 const mixins = options.mixins;2828 if (mixins) {2829 callHookFromMixins(name, mixins, ctx);2830 }2831 const selfHook = options[name];2832 if (selfHook) {2833 selfHook.call(ctx);2834 }2835}2836function callHookFromMixins(name, mixins, ctx) {2837 for (let i = 0; i < mixins.length; i++) {2838 const fn = mixins[i][name];2839 if (fn) {2840 fn.call(ctx);2841 }2842 }2843}2844function applyMixins(instance, mixins) {2845 for (let i = 0; i < mixins.length; i++) {2846 applyOptions(instance, mixins[i], true);2847 }2848}2849const emptyAppContext = createAppContext();2850function createComponentInstance(vnode, parent) {2851 // inherit parent app context - or - if root, adopt from root vnode2852 const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;2853 const instance = {2854 vnode,2855 parent,2856 appContext,2857 type: vnode.type,2858 root: null,2859 next: null,2860 subTree: null,2861 update: null,2862 render: null,2863 renderProxy: null,2864 propsProxy: null,2865 setupContext: null,2866 effects: null,2867 provides: parent ? parent.provides : Object.create(appContext.provides),2868 accessCache: null,2869 renderCache: null,2870 // setup context properties2871 renderContext: EMPTY_OBJ,2872 data: EMPTY_OBJ,2873 props: EMPTY_OBJ,2874 attrs: EMPTY_OBJ,2875 slots: EMPTY_OBJ,2876 refs: EMPTY_OBJ,2877 // per-instance asset storage (mutable during options resolution)2878 components: Object.create(appContext.components),2879 directives: Object.create(appContext.directives),2880 // async dependency management2881 asyncDep: null,2882 asyncResult: null,2883 asyncResolved: false,2884 // user namespace for storing whatever the user assigns to `this`2885 user: {},2886 // lifecycle hooks2887 // not using enums here because it results in computed properties2888 isUnmounted: false,2889 bc: null,2890 c: null,2891 bm: null,2892 m: null,2893 bu: null,2894 u: null,2895 um: null,2896 bum: null,2897 da: null,2898 a: null,2899 rtg: null,2900 rtc: null,2901 ec: null,2902 emit: (event, ...args) => {2903 const props = instance.vnode.props || EMPTY_OBJ;2904 const handler = props[`on${event}`] || props[`on${capitalize(event)}`];2905 if (handler) {2906 callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);2907 }2908 }2909 };2910 instance.root = parent ? parent.root : instance;2911 return instance;2912}2913let currentInstance = null;2914let currentSuspense = null;2915const getCurrentInstance = () => currentInstance;2916const setCurrentInstance = (instance) => {2917 currentInstance = instance;2918};2919const isBuiltInTag = /*#__PURE__*/ makeMap('slot,component');2920function validateComponentName(name, config) {2921 const appIsNativeTag = config.isNativeTag || NO;2922 if (isBuiltInTag(name) || appIsNativeTag(name)) {2923 warn('Do not use built-in or reserved HTML elements as component id: ' + name);2924 }2925}2926function setupStatefulComponent(instance, parentSuspense) {2927 const Component = instance.type;2928 if (process.env.NODE_ENV !== 'production') {2929 if (Component.name) {2930 validateComponentName(Component.name, instance.appContext.config);2931 }2932 if (Component.components) {2933 const names = Object.keys(Component.components);2934 for (let i = 0; i < names.length; i++) {2935 const name = names[i];2936 validateComponentName(name, instance.appContext.config);2937 }2938 }2939 if (Component.directives) {2940 const names = Object.keys(Component.directives);2941 for (let i = 0; i < names.length; i++) {2942 validateDirectiveName(names[i]);2943 }2944 }2945 }2946 // 0. create render proxy property access cache2947 instance.accessCache = {};2948 // 1. create render proxy2949 instance.renderProxy = new Proxy(instance, PublicInstanceProxyHandlers);2950 // 2. create props proxy2951 // the propsProxy is a reactive AND readonly proxy to the actual props.2952 // it will be updated in resolveProps() on updates before render2953 const propsProxy = (instance.propsProxy = readonly(instance.props));2954 // 3. call setup()2955 const { setup } = Component;2956 if (setup) { ...

Full Screen

Full Screen

runtime-core.cjs.js

Source:runtime-core.cjs.js Github

copy

Full Screen

...1045])1046*/1047const valueCache = new WeakMap();1048const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text');1049function validateDirectiveName(name) {1050 if (isBuiltInDirective(name)) {1051 warn('Do not use built-in directive ids as custom directive id: ' + name);1052 }1053}1054function applyDirective(props, instance, directive, value, arg, modifiers = EMPTY_OBJ) {1055 let valueCacheForDir = valueCache.get(directive);1056 if (!valueCacheForDir) {1057 valueCacheForDir = new WeakMap();1058 valueCache.set(directive, valueCacheForDir);1059 }1060 if (isFunction(directive)) {1061 directive = {1062 mounted: directive,1063 updated: directive1064 };1065 }1066 for (const key in directive) {1067 const hook = directive[key];1068 const hookKey = `onVnode` + key[0].toUpperCase() + key.slice(1);1069 const vnodeHook = (vnode, prevVNode) => {1070 let oldValue;1071 if (prevVNode != null) {1072 oldValue = valueCacheForDir.get(prevVNode);1073 valueCacheForDir.delete(prevVNode);1074 }1075 valueCacheForDir.set(vnode, value);1076 hook(vnode.el, {1077 instance: instance.renderProxy,1078 value,1079 oldValue,1080 arg,1081 modifiers1082 }, vnode, prevVNode);1083 };1084 const existing = props[hookKey];1085 props[hookKey] = existing1086 ? [].concat(existing, vnodeHook)1087 : vnodeHook;1088 }1089}1090function withDirectives(vnode, directives) {1091 const instance = currentRenderingInstance;1092 if (instance !== null) {1093 vnode.props = vnode.props || {};1094 for (let i = 0; i < directives.length; i++) {1095 const [dir, value, arg, modifiers] = directives[i];1096 applyDirective(vnode.props, instance, dir, value, arg, modifiers);1097 }1098 }1099 else {1100 warn(`withDirectives can only be used inside render functions.`);1101 }1102 return vnode;1103}1104function invokeDirectiveHook(hook, instance, vnode, prevVNode = null) {1105 callWithAsyncErrorHandling(hook, instance, 7 /* DIRECTIVE_HOOK */, [1106 vnode,1107 prevVNode1108 ]);1109}1110function createAppContext() {1111 return {1112 config: {1113 devtools: true,1114 performance: false,1115 isNativeTag: NO,1116 isCustomElement: NO,1117 errorHandler: undefined,1118 warnHandler: undefined1119 },1120 mixins: [],1121 components: {},1122 directives: {},1123 provides: {}1124 };1125}1126function createAppAPI(render) {1127 return function createApp() {1128 const context = createAppContext();1129 let isMounted = false;1130 const app = {1131 get config() {1132 return context.config;1133 },1134 set config(v) {1135 {1136 warn(`app.config cannot be replaced. Modify individual options instead.`);1137 }1138 },1139 use(plugin) {1140 if (isFunction(plugin)) {1141 plugin(app);1142 }1143 else if (isFunction(plugin.install)) {1144 plugin.install(app);1145 }1146 else {1147 warn(`A plugin must either be a function or an object with an "install" ` +1148 `function.`);1149 }1150 return app;1151 },1152 mixin(mixin) {1153 context.mixins.push(mixin);1154 return app;1155 },1156 component(name, component) {1157 {1158 validateComponentName(name, context.config);1159 }1160 if (!component) {1161 return context.components[name];1162 }1163 else {1164 context.components[name] = component;1165 return app;1166 }1167 },1168 directive(name, directive) {1169 {1170 validateDirectiveName(name);1171 }1172 if (!directive) {1173 return context.directives[name];1174 }1175 else {1176 context.directives[name] = directive;1177 return app;1178 }1179 },1180 mount(rootComponent, rootContainer, rootProps) {1181 if (!isMounted) {1182 const vnode = createVNode(rootComponent, rootProps);1183 // store app context on the root VNode.1184 // this will be set on the root instance on initial mount.1185 vnode.appContext = context;1186 render(vnode, rootContainer);1187 isMounted = true;1188 return vnode.component.renderProxy;1189 }1190 else {1191 warn(`App has already been mounted. Create a new app instance instead.`);1192 }1193 },1194 provide(key, value) {1195 if ( key in context.provides) {1196 warn(`App already provides property with key "${key}". ` +1197 `It will be overwritten with the new value.`);1198 }1199 // TypeScript doesn't allow symbols as index type1200 // https://github.com/Microsoft/TypeScript/issues/245871201 context.provides[key] = value;1202 }1203 };1204 return app;1205 };1206}1207function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, optimized) {1208 return {1209 vnode,1210 parent,1211 parentComponent,1212 isSVG,1213 optimized,1214 container,1215 hiddenContainer,1216 anchor,1217 deps: 0,1218 subTree: null,1219 fallbackTree: null,1220 isResolved: false,1221 isUnmounted: false,1222 effects: []1223 };1224}1225function normalizeSuspenseChildren(vnode) {1226 const { shapeFlag, children } = vnode;1227 if (shapeFlag & PublicShapeFlags.SLOTS_CHILDREN) {1228 const { default: d, fallback } = children;1229 return {1230 content: normalizeVNode(isFunction(d) ? d() : d),1231 fallback: normalizeVNode(isFunction(fallback) ? fallback() : fallback)1232 };1233 }1234 else {1235 return {1236 content: normalizeVNode(children),1237 fallback: normalizeVNode(null)1238 };1239 }1240}1241function createDevEffectOptions(instance) {1242 return {1243 scheduler: queueJob,1244 onTrack: instance.rtc ? e => invokeHooks(instance.rtc, e) : void 0,1245 onTrigger: instance.rtg ? e => invokeHooks(instance.rtg, e) : void 01246 };1247}1248function isSameType$1(n1, n2) {1249 return n1.type === n2.type && n1.key === n2.key;1250}1251function invokeHooks(hooks, arg) {1252 for (let i = 0; i < hooks.length; i++) {1253 hooks[i](arg);1254 }1255}1256function queuePostRenderEffect(fn, suspense) {1257 if (suspense !== null && !suspense.isResolved) {1258 if (isArray(fn)) {1259 suspense.effects.push(...fn);1260 }1261 else {1262 suspense.effects.push(fn);1263 }1264 }1265 else {1266 queuePostFlushCb(fn);1267 }1268}1269/**1270 * The createRenderer function accepts two generic arguments:1271 * HostNode and HostElement, corresponding to Node and Element types in the1272 * host environment. For example, for runtime-dom, HostNode would be the DOM1273 * `Node` interface and HostElement would be the DOM `Element` interface.1274 *1275 * Custom renderers can pass in the platform specific types like this:1276 *1277 * ``` js1278 * const { render, createApp } = createRenderer<Node, Element>({1279 * patchProp,1280 * ...nodeOps1281 * })1282 * ```1283 */1284function createRenderer(options) {1285 const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, querySelector: hostQuerySelector } = options;1286 function patch(n1, // null means this is a mount1287 n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, optimized = false) {1288 // patching & not same type, unmount old tree1289 if (n1 != null) {1290 if (!isSameType$1(n1, n2)) {1291 anchor = getNextHostNode(n1);1292 unmount(n1, parentComponent, parentSuspense, true);1293 n1 = null;1294 }1295 else if (n1.props && n1.props.$once) {1296 return;1297 }1298 }1299 const { type, shapeFlag } = n2;1300 switch (type) {1301 case Text:1302 processText(n1, n2, container, anchor);1303 break;1304 case Comment:1305 processCommentNode(n1, n2, container, anchor);1306 break;1307 case Fragment:1308 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1309 break;1310 case Portal:1311 processPortal(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1312 break;1313 case Suspense:1314 {1315 processSuspense(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1316 }1317 break;1318 default:1319 if (shapeFlag & 1 /* ELEMENT */) {1320 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1321 }1322 else if (shapeFlag & 6 /* COMPONENT */) {1323 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1324 }1325 else {1326 warn('Invalid HostVNode type:', n2.type, `(${typeof n2.type})`);1327 }1328 }1329 }1330 function processText(n1, n2, container, anchor) {1331 if (n1 == null) {1332 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);1333 }1334 else {1335 const el = (n2.el = n1.el);1336 if (n2.children !== n1.children) {1337 hostSetText(el, n2.children);1338 }1339 }1340 }1341 function processCommentNode(n1, n2, container, anchor) {1342 if (n1 == null) {1343 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);1344 }1345 else {1346 // there's no support for dynamic comments1347 n2.el = n1.el;1348 }1349 }1350 function processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1351 if (n1 == null) {1352 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1353 }1354 else {1355 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized);1356 }1357 if (n2.ref !== null && parentComponent !== null) {1358 setRef(n2.ref, n1 && n1.ref, parentComponent, n2.el);1359 }1360 }1361 function mountElement(vnode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1362 const tag = vnode.type;1363 isSVG = isSVG || tag === 'svg';1364 const el = (vnode.el = hostCreateElement(tag, isSVG));1365 const { props, shapeFlag } = vnode;1366 if (props != null) {1367 for (const key in props) {1368 if (isReservedProp(key))1369 continue;1370 hostPatchProp(el, key, props[key], null, isSVG);1371 }1372 if (props.onVnodeBeforeMount != null) {1373 invokeDirectiveHook(props.onVnodeBeforeMount, parentComponent, vnode);1374 }1375 }1376 if (shapeFlag & 8 /* TEXT_CHILDREN */) {1377 hostSetElementText(el, vnode.children);1378 }1379 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1380 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG, optimized || vnode.dynamicChildren !== null);1381 }1382 hostInsert(el, container, anchor);1383 if (props != null && props.onVnodeMounted != null) {1384 queuePostRenderEffect(() => {1385 invokeDirectiveHook(props.onVnodeMounted, parentComponent, vnode);1386 }, parentSuspense);1387 }1388 }1389 function mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, optimized, start = 0) {1390 for (let i = start; i < children.length; i++) {1391 const child = optimized1392 ? children[i]1393 : (children[i] = normalizeVNode(children[i]));1394 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1395 }1396 }1397 function patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized) {1398 const el = (n2.el = n1.el);1399 const { patchFlag, dynamicChildren } = n2;1400 const oldProps = (n1 && n1.props) || EMPTY_OBJ;1401 const newProps = n2.props || EMPTY_OBJ;1402 if (newProps.onVnodeBeforeUpdate != null) {1403 invokeDirectiveHook(newProps.onVnodeBeforeUpdate, parentComponent, n2, n1);1404 }1405 if (patchFlag > 0) {1406 // the presence of a patchFlag means this element's render code was1407 // generated by the compiler and can take the fast path.1408 // in this path old node and new node are guaranteed to have the same shape1409 // (i.e. at the exact same position in the source template)1410 if (patchFlag & 16 /* FULL_PROPS */) {1411 // element props contain dynamic keys, full diff needed1412 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);1413 }1414 else {1415 // class1416 // this flag is matched when the element has dynamic class bindings.1417 if (patchFlag & 2 /* CLASS */) {1418 if (oldProps.class !== newProps.class) {1419 hostPatchProp(el, 'class', newProps.class, null, isSVG);1420 }1421 }1422 // style1423 // this flag is matched when the element has dynamic style bindings1424 if (patchFlag & 4 /* STYLE */) {1425 hostPatchProp(el, 'style', newProps.style, oldProps.style, isSVG);1426 }1427 // props1428 // This flag is matched when the element has dynamic prop/attr bindings1429 // other than class and style. The keys of dynamic prop/attrs are saved for1430 // faster iteration.1431 // Note dynamic keys like :[foo]="bar" will cause this optimization to1432 // bail out and go through a full diff because we need to unset the old key1433 if (patchFlag & 8 /* PROPS */) {1434 // if the flag is present then dynamicProps must be non-null1435 const propsToUpdate = n2.dynamicProps;1436 for (let i = 0; i < propsToUpdate.length; i++) {1437 const key = propsToUpdate[i];1438 const prev = oldProps[key];1439 const next = newProps[key];1440 if (prev !== next) {1441 hostPatchProp(el, key, next, prev, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);1442 }1443 }1444 }1445 }1446 // text1447 // This flag is matched when the element has only dynamic text children.1448 // this flag is terminal (i.e. skips children diffing).1449 if (patchFlag & 1 /* TEXT */) {1450 if (n1.children !== n2.children) {1451 hostSetElementText(el, n2.children);1452 }1453 return; // terminal1454 }1455 }1456 else if (!optimized && dynamicChildren == null) {1457 // unoptimized, full diff1458 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);1459 }1460 if (dynamicChildren != null) {1461 patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, isSVG);1462 }1463 else if (!optimized) {1464 // full diff1465 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, isSVG);1466 }1467 if (newProps.onVnodeUpdated != null) {1468 queuePostRenderEffect(() => {1469 invokeDirectiveHook(newProps.onVnodeUpdated, parentComponent, n2, n1);1470 }, parentSuspense);1471 }1472 }1473 // The fast path for blocks.1474 function patchBlockChildren(oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG) {1475 for (let i = 0; i < newChildren.length; i++) {1476 const oldVNode = oldChildren[i];1477 patch(oldVNode, newChildren[i], 1478 // in the case of a Fragment, we need to provide the actual parent1479 // of the Fragment itself so it can move its children. In other cases,1480 // the parent container is not actually used so we just pass the1481 // block element here to avoid a DOM parentNode call.1482 oldVNode.type === Fragment1483 ? hostParentNode(oldVNode.el)1484 : fallbackContainer, null, parentComponent, parentSuspense, isSVG, true);1485 }1486 }1487 function patchProps(el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) {1488 if (oldProps !== newProps) {1489 for (const key in newProps) {1490 if (isReservedProp(key))1491 continue;1492 const next = newProps[key];1493 const prev = oldProps[key];1494 if (next !== prev) {1495 hostPatchProp(el, key, next, prev, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);1496 }1497 }1498 if (oldProps !== EMPTY_OBJ) {1499 for (const key in oldProps) {1500 if (isReservedProp(key))1501 continue;1502 if (!(key in newProps)) {1503 hostPatchProp(el, key, null, null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);1504 }1505 }1506 }1507 }1508 }1509 function processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1510 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateComment(''));1511 const fragmentEndAnchor = (n2.anchor = n11512 ? n1.anchor1513 : hostCreateComment(''));1514 if (n1 == null) {1515 hostInsert(fragmentStartAnchor, container, anchor);1516 hostInsert(fragmentEndAnchor, container, anchor);1517 // a fragment can only have array children1518 // since they are either generated by the compiler, or implicitly created1519 // from arrays.1520 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);1521 }1522 else {1523 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);1524 }1525 }1526 function processPortal(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1527 const targetSelector = n2.props && n2.props.target;1528 const { patchFlag, shapeFlag, children } = n2;1529 if (n1 == null) {1530 const target = (n2.target = isString(targetSelector)1531 ? hostQuerySelector(targetSelector)1532 : null);1533 if (target != null) {1534 if (shapeFlag & 8 /* TEXT_CHILDREN */) {1535 hostSetElementText(target, children);1536 }1537 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1538 mountChildren(children, target, null, parentComponent, parentSuspense, isSVG, optimized);1539 }1540 }1541 else {1542 warn('Invalid Portal target on mount:', target, `(${typeof target})`);1543 }1544 }1545 else {1546 // update content1547 const target = (n2.target = n1.target);1548 if (patchFlag === 1 /* TEXT */) {1549 hostSetElementText(target, children);1550 }1551 else if (n2.dynamicChildren) {1552 // fast path when the portal happens to be a block root1553 patchBlockChildren(n1.dynamicChildren, n2.dynamicChildren, container, parentComponent, parentSuspense, isSVG);1554 }1555 else if (!optimized) {1556 patchChildren(n1, n2, target, null, parentComponent, parentSuspense, isSVG);1557 }1558 // target changed1559 if (targetSelector !== (n1.props && n1.props.target)) {1560 const nextTarget = (n2.target = isString(targetSelector)1561 ? hostQuerySelector(targetSelector)1562 : null);1563 if (nextTarget != null) {1564 // move content1565 if (shapeFlag & 8 /* TEXT_CHILDREN */) {1566 hostSetElementText(target, '');1567 hostSetElementText(nextTarget, children);1568 }1569 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1570 for (let i = 0; i < children.length; i++) {1571 move(children[i], nextTarget, null);1572 }1573 }1574 }1575 else {1576 warn('Invalid Portal target on update:', target, `(${typeof target})`);1577 }1578 }1579 }1580 // insert an empty node as the placeholder for the portal1581 processCommentNode(n1, n2, container, anchor);1582 }1583 function processSuspense(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1584 if (n1 == null) {1585 mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1586 }1587 else {1588 patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized);1589 }1590 }1591 function mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1592 const hiddenContainer = hostCreateElement('div');1593 const suspense = (n2.suspense = createSuspenseBoundary(n2, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, optimized));1594 const { content, fallback } = normalizeSuspenseChildren(n2);1595 suspense.subTree = content;1596 suspense.fallbackTree = fallback;1597 // start mounting the content subtree in an off-dom container1598 patch(null, content, hiddenContainer, null, parentComponent, suspense, isSVG, optimized);1599 // now check if we have encountered any async deps1600 if (suspense.deps > 0) {1601 // mount the fallback tree1602 patch(null, fallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context1603 isSVG, optimized);1604 n2.el = fallback.el;1605 }1606 else {1607 // Suspense has no async deps. Just resolve.1608 resolveSuspense(suspense);1609 }1610 }1611 function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized) {1612 const suspense = (n2.suspense = n1.suspense);1613 suspense.vnode = n2;1614 const { content, fallback } = normalizeSuspenseChildren(n2);1615 const oldSubTree = suspense.subTree;1616 const oldFallbackTree = suspense.fallbackTree;1617 if (!suspense.isResolved) {1618 patch(oldSubTree, content, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized);1619 if (suspense.deps > 0) {1620 // still pending. patch the fallback tree.1621 patch(oldFallbackTree, fallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context1622 isSVG, optimized);1623 n2.el = fallback.el;1624 }1625 // If deps somehow becomes 0 after the patch it means the patch caused an1626 // async dep component to unmount and removed its dep. It will cause the1627 // suspense to resolve and we don't need to do anything here.1628 }1629 else {1630 // just normal patch inner content as a fragment1631 patch(oldSubTree, content, container, anchor, parentComponent, suspense, isSVG, optimized);1632 n2.el = content.el;1633 }1634 suspense.subTree = content;1635 suspense.fallbackTree = fallback;1636 }1637 function resolveSuspense(suspense) {1638 {1639 if (suspense.isResolved) {1640 throw new Error(`resolveSuspense() is called on an already resolved suspense boundary.`);1641 }1642 if (suspense.isUnmounted) {1643 throw new Error(`resolveSuspense() is called on an already unmounted suspense boundary.`);1644 }1645 }1646 const { vnode, subTree, fallbackTree, effects, parentComponent, container } = suspense;1647 // this is initial anchor on mount1648 let { anchor } = suspense;1649 // unmount fallback tree1650 if (fallbackTree.el) {1651 // if the fallback tree was mounted, it may have been moved1652 // as part of a parent suspense. get the latest anchor for insertion1653 anchor = getNextHostNode(fallbackTree);1654 unmount(fallbackTree, parentComponent, suspense, true);1655 }1656 // move content from off-dom container to actual container1657 move(subTree, container, anchor);1658 const el = (vnode.el = subTree.el);1659 // suspense as the root node of a component...1660 if (parentComponent && parentComponent.subTree === vnode) {1661 parentComponent.vnode.el = el;1662 updateHOCHostEl(parentComponent, el);1663 }1664 // check if there is a pending parent suspense1665 let parent = suspense.parent;1666 let hasUnresolvedAncestor = false;1667 while (parent) {1668 if (!parent.isResolved) {1669 // found a pending parent suspense, merge buffered post jobs1670 // into that parent1671 parent.effects.push(...effects);1672 hasUnresolvedAncestor = true;1673 break;1674 }1675 parent = parent.parent;1676 }1677 // no pending parent suspense, flush all jobs1678 if (!hasUnresolvedAncestor) {1679 queuePostFlushCb(effects);1680 }1681 suspense.isResolved = true;1682 // invoke @resolve event1683 const onResolve = vnode.props && vnode.props.onResolve;1684 if (isFunction(onResolve)) {1685 onResolve();1686 }1687 }1688 function restartSuspense(suspense) {1689 suspense.isResolved = false;1690 const { vnode, subTree, fallbackTree, parentComponent, container, hiddenContainer, isSVG, optimized } = suspense;1691 // move content tree back to the off-dom container1692 const anchor = getNextHostNode(subTree);1693 move(subTree, hiddenContainer, null);1694 // remount the fallback tree1695 patch(null, fallbackTree, container, anchor, parentComponent, null, // fallback tree will not have suspense context1696 isSVG, optimized);1697 const el = (vnode.el = fallbackTree.el);1698 // suspense as the root node of a component...1699 if (parentComponent && parentComponent.subTree === vnode) {1700 parentComponent.vnode.el = el;1701 updateHOCHostEl(parentComponent, el);1702 }1703 // invoke @suspense event1704 const onSuspense = vnode.props && vnode.props.onSuspense;1705 if (isFunction(onSuspense)) {1706 onSuspense();1707 }1708 }1709 function processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1710 if (n1 == null) {1711 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG);1712 }1713 else {1714 const instance = (n2.component = n1.component);1715 if (shouldUpdateComponent(n1, n2, optimized)) {1716 if (1717 instance.asyncDep &&1718 !instance.asyncResolved) {1719 // async & still pending - just update props and slots1720 // since the component's reactive effect for render isn't set-up yet1721 {1722 pushWarningContext(n2);1723 }1724 updateComponentPreRender(instance, n2);1725 {1726 popWarningContext();1727 }1728 return;1729 }1730 else {1731 // normal update1732 instance.next = n2;1733 // instance.update is the reactive effect runner.1734 instance.update();1735 }1736 }1737 else {1738 // no update needed. just copy over properties1739 n2.component = n1.component;1740 n2.el = n1.el;1741 }1742 }1743 if (n2.ref !== null && parentComponent !== null) {1744 setRef(n2.ref, n1 && n1.ref, parentComponent, n2.component.renderProxy);1745 }1746 }1747 function mountComponent(initialVNode, container, anchor, parentComponent, parentSuspense, isSVG) {1748 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent));1749 {1750 pushWarningContext(initialVNode);1751 }1752 // resolve props and slots for setup context1753 const propsOptions = initialVNode.type.props;1754 resolveProps(instance, initialVNode.props, propsOptions);1755 resolveSlots(instance, initialVNode.children);1756 // setup stateful logic1757 if (initialVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {1758 setupStatefulComponent(instance, parentSuspense);1759 }1760 // setup() is async. This component relies on async logic to be resolved1761 // before proceeding1762 if ( instance.asyncDep) {1763 if (!parentSuspense) {1764 // TODO handle this properly1765 throw new Error('Async component without a suspense boundary!');1766 }1767 // parent suspense already resolved, need to re-suspense1768 // use queueJob so it's handled synchronously after patching the current1769 // suspense tree1770 if (parentSuspense.isResolved) {1771 queueJob(() => {1772 restartSuspense(parentSuspense);1773 });1774 }1775 parentSuspense.deps++;1776 instance.asyncDep1777 .catch(err => {1778 handleError(err, instance, 0 /* SETUP_FUNCTION */);1779 })1780 .then(asyncSetupResult => {1781 // component may be unmounted before resolve1782 if (!instance.isUnmounted && !parentSuspense.isUnmounted) {1783 retryAsyncComponent(instance, asyncSetupResult, parentSuspense, isSVG);1784 }1785 });1786 // give it a placeholder1787 const placeholder = (instance.subTree = createVNode(Comment));1788 processCommentNode(null, placeholder, container, anchor);1789 initialVNode.el = placeholder.el;1790 return;1791 }1792 setupRenderEffect(instance, parentSuspense, initialVNode, container, anchor, isSVG);1793 {1794 popWarningContext();1795 }1796 }1797 function retryAsyncComponent(instance, asyncSetupResult, parentSuspense, isSVG) {1798 parentSuspense.deps--;1799 // retry from this component1800 instance.asyncResolved = true;1801 const { vnode } = instance;1802 {1803 pushWarningContext(vnode);1804 }1805 handleSetupResult(instance, asyncSetupResult, parentSuspense);1806 setupRenderEffect(instance, parentSuspense, vnode, 1807 // component may have been moved before resolve1808 hostParentNode(instance.subTree.el), getNextHostNode(instance.subTree), isSVG);1809 updateHOCHostEl(instance, vnode.el);1810 {1811 popWarningContext();1812 }1813 if (parentSuspense.deps === 0) {1814 resolveSuspense(parentSuspense);1815 }1816 }1817 function setupRenderEffect(instance, parentSuspense, initialVNode, container, anchor, isSVG) {1818 // create reactive effect for rendering1819 let mounted = false;1820 instance.update = reactivity.effect(function componentEffect() {1821 if (!mounted) {1822 const subTree = (instance.subTree = renderComponentRoot(instance));1823 // beforeMount hook1824 if (instance.bm !== null) {1825 invokeHooks(instance.bm);1826 }1827 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);1828 initialVNode.el = subTree.el;1829 // mounted hook1830 if (instance.m !== null) {1831 queuePostRenderEffect(instance.m, parentSuspense);1832 }1833 mounted = true;1834 }1835 else {1836 // updateComponent1837 // This is triggered by mutation of component's own state (next: null)1838 // OR parent calling processComponent (next: HostVNode)1839 const { next } = instance;1840 {1841 pushWarningContext(next || instance.vnode);1842 }1843 if (next !== null) {1844 updateComponentPreRender(instance, next);1845 }1846 const prevTree = instance.subTree;1847 const nextTree = (instance.subTree = renderComponentRoot(instance));1848 // beforeUpdate hook1849 if (instance.bu !== null) {1850 invokeHooks(instance.bu);1851 }1852 // reset refs1853 // only needed if previous patch had refs1854 if (instance.refs !== EMPTY_OBJ) {1855 instance.refs = {};1856 }1857 patch(prevTree, nextTree, 1858 // parent may have changed if it's in a portal1859 hostParentNode(prevTree.el), 1860 // anchor may have changed if it's in a fragment1861 getNextHostNode(prevTree), instance, parentSuspense, isSVG);1862 instance.vnode.el = nextTree.el;1863 if (next === null) {1864 // self-triggered update. In case of HOC, update parent component1865 // vnode el. HOC is indicated by parent instance's subTree pointing1866 // to child component's vnode1867 updateHOCHostEl(instance, nextTree.el);1868 }1869 // updated hook1870 if (instance.u !== null) {1871 queuePostRenderEffect(instance.u, parentSuspense);1872 }1873 {1874 popWarningContext();1875 }1876 }1877 }, createDevEffectOptions(instance) );1878 }1879 function updateComponentPreRender(instance, nextVNode) {1880 nextVNode.component = instance;1881 instance.vnode = nextVNode;1882 instance.next = null;1883 resolveProps(instance, nextVNode.props, nextVNode.type.props);1884 resolveSlots(instance, nextVNode.children);1885 }1886 function updateHOCHostEl({ vnode, parent }, el) {1887 while (parent && parent.subTree === vnode) {1888 (vnode = parent.vnode).el = el;1889 parent = parent.parent;1890 }1891 }1892 function patchChildren(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized = false) {1893 const c1 = n1 && n1.children;1894 const prevShapeFlag = n1 ? n1.shapeFlag : 0;1895 const c2 = n2.children;1896 const { patchFlag, shapeFlag } = n2;1897 if (patchFlag === -1 /* BAIL */) {1898 optimized = false;1899 }1900 // fast path1901 if (patchFlag > 0) {1902 if (patchFlag & 64 /* KEYED_FRAGMENT */) {1903 // this could be either fully-keyed or mixed (some keyed some not)1904 // presence of patchFlag means children are guaranteed to be arrays1905 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1906 return;1907 }1908 else if (patchFlag & 128 /* UNKEYED_FRAGMENT */) {1909 // unkeyed1910 patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1911 return;1912 }1913 }1914 // children has 3 possibilities: text, array or no children.1915 if (shapeFlag & 8 /* TEXT_CHILDREN */) {1916 // text children fast path1917 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {1918 unmountChildren(c1, parentComponent, parentSuspense);1919 }1920 if (c2 !== c1) {1921 hostSetElementText(container, c2);1922 }1923 }1924 else {1925 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {1926 // prev children was array1927 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1928 // two arrays, cannot assume anything, do full diff1929 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1930 }1931 else {1932 // no new children, just unmount old1933 unmountChildren(c1, parentComponent, parentSuspense, true);1934 }1935 }1936 else {1937 // prev children was text OR null1938 // new children is array OR null1939 if (prevShapeFlag & 8 /* TEXT_CHILDREN */) {1940 hostSetElementText(container, '');1941 }1942 // mount new if array1943 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1944 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1945 }1946 }1947 }1948 }1949 function patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1950 c1 = c1 || EMPTY_ARR;1951 c2 = c2 || EMPTY_ARR;1952 const oldLength = c1.length;1953 const newLength = c2.length;1954 const commonLength = Math.min(oldLength, newLength);1955 let i;1956 for (i = 0; i < commonLength; i++) {1957 const nextChild = optimized1958 ? c2[i]1959 : (c2[i] = normalizeVNode(c2[i]));1960 patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, optimized);1961 }1962 if (oldLength > newLength) {1963 // remove old1964 unmountChildren(c1, parentComponent, parentSuspense, true, commonLength);1965 }1966 else {1967 // mount new1968 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, commonLength);1969 }1970 }1971 // can be all-keyed or mixed1972 function patchKeyedChildren(c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, optimized) {1973 let i = 0;1974 const l2 = c2.length;1975 let e1 = c1.length - 1; // prev ending index1976 let e2 = l2 - 1; // next ending index1977 // 1. sync from start1978 // (a b) c1979 // (a b) d e1980 while (i <= e1 && i <= e2) {1981 const n1 = c1[i];1982 const n2 = optimized1983 ? c2[i]1984 : (c2[i] = normalizeVNode(c2[i]));1985 if (isSameType$1(n1, n2)) {1986 patch(n1, n2, container, parentAnchor, parentComponent, parentSuspense, isSVG, optimized);1987 }1988 else {1989 break;1990 }1991 i++;1992 }1993 // 2. sync from end1994 // a (b c)1995 // d e (b c)1996 while (i <= e1 && i <= e2) {1997 const n1 = c1[e1];1998 const n2 = optimized1999 ? c2[i]2000 : (c2[e2] = normalizeVNode(c2[e2]));2001 if (isSameType$1(n1, n2)) {2002 patch(n1, n2, container, parentAnchor, parentComponent, parentSuspense, isSVG, optimized);2003 }2004 else {2005 break;2006 }2007 e1--;2008 e2--;2009 }2010 // 3. common sequence + mount2011 // (a b)2012 // (a b) c2013 // i = 2, e1 = 1, e2 = 22014 // (a b)2015 // c (a b)2016 // i = 0, e1 = -1, e2 = 02017 if (i > e1) {2018 if (i <= e2) {2019 const nextPos = e2 + 1;2020 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;2021 while (i <= e2) {2022 patch(null, optimized ? c2[i] : (c2[i] = normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG);2023 i++;2024 }2025 }2026 }2027 // 4. common sequence + unmount2028 // (a b) c2029 // (a b)2030 // i = 2, e1 = 2, e2 = 12031 // a (b c)2032 // (b c)2033 // i = 0, e1 = 0, e2 = -12034 else if (i > e2) {2035 while (i <= e1) {2036 unmount(c1[i], parentComponent, parentSuspense, true);2037 i++;2038 }2039 }2040 // 5. unknown sequence2041 // [i ... e1 + 1]: a b [c d e] f g2042 // [i ... e2 + 1]: a b [e d c h] f g2043 // i = 2, e1 = 4, e2 = 52044 else {2045 const s1 = i; // prev starting index2046 const s2 = i; // next starting index2047 // 5.1 build key:index map for newChildren2048 const keyToNewIndexMap = new Map();2049 for (i = s2; i <= e2; i++) {2050 const nextChild = optimized2051 ? c2[i]2052 : (c2[i] = normalizeVNode(c2[i]));2053 if (nextChild.key != null) {2054 if ( keyToNewIndexMap.has(nextChild.key)) {2055 warn(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`);2056 }2057 keyToNewIndexMap.set(nextChild.key, i);2058 }2059 }2060 // 5.2 loop through old children left to be patched and try to patch2061 // matching nodes & remove nodes that are no longer present2062 let j;2063 let patched = 0;2064 const toBePatched = e2 - s2 + 1;2065 let moved = false;2066 // used to track whether any node has moved2067 let maxNewIndexSoFar = 0;2068 // works as Map<newIndex, oldIndex>2069 // Note that oldIndex is offset by +12070 // and oldIndex = 0 is a special value indicating the new node has2071 // no corresponding old node.2072 // used for determining longest stable subsequence2073 const newIndexToOldIndexMap = new Array(toBePatched);2074 for (i = 0; i < toBePatched; i++)2075 newIndexToOldIndexMap[i] = 0;2076 for (i = s1; i <= e1; i++) {2077 const prevChild = c1[i];2078 if (patched >= toBePatched) {2079 // all new children have been patched so this can only be a removal2080 unmount(prevChild, parentComponent, parentSuspense, true);2081 continue;2082 }2083 let newIndex;2084 if (prevChild.key != null) {2085 newIndex = keyToNewIndexMap.get(prevChild.key);2086 }2087 else {2088 // key-less node, try to locate a key-less node of the same type2089 for (j = s2; j <= e2; j++) {2090 if (newIndexToOldIndexMap[j - s2] === 0 &&2091 isSameType$1(prevChild, c2[j])) {2092 newIndex = j;2093 break;2094 }2095 }2096 }2097 if (newIndex === undefined) {2098 unmount(prevChild, parentComponent, parentSuspense, true);2099 }2100 else {2101 newIndexToOldIndexMap[newIndex - s2] = i + 1;2102 if (newIndex >= maxNewIndexSoFar) {2103 maxNewIndexSoFar = newIndex;2104 }2105 else {2106 moved = true;2107 }2108 patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, optimized);2109 patched++;2110 }2111 }2112 // 5.3 move and mount2113 // generate longest stable subsequence only when nodes have moved2114 const increasingNewIndexSequence = moved2115 ? getSequence(newIndexToOldIndexMap)2116 : EMPTY_ARR;2117 j = increasingNewIndexSequence.length - 1;2118 // looping backwards so that we can use last patched node as anchor2119 for (i = toBePatched - 1; i >= 0; i--) {2120 const nextIndex = s2 + i;2121 const nextChild = c2[nextIndex];2122 const anchor = nextIndex + 1 < l22123 ? c2[nextIndex + 1].el2124 : parentAnchor;2125 if (newIndexToOldIndexMap[i] === 0) {2126 // mount new2127 patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG);2128 }2129 else if (moved) {2130 // move if:2131 // There is no stable subsequence (e.g. a reverse)2132 // OR current node is not among the stable sequence2133 if (j < 0 || i !== increasingNewIndexSequence[j]) {2134 move(nextChild, container, anchor);2135 }2136 else {2137 j--;2138 }2139 }2140 }2141 }2142 }2143 function move(vnode, container, anchor) {2144 if (vnode.component !== null) {2145 move(vnode.component.subTree, container, anchor);2146 return;2147 }2148 if ( vnode.type === Suspense) {2149 const suspense = vnode.suspense;2150 move(suspense.isResolved ? suspense.subTree : suspense.fallbackTree, container, anchor);2151 suspense.container = container;2152 return;2153 }2154 if (vnode.type === Fragment) {2155 hostInsert(vnode.el, container, anchor);2156 const children = vnode.children;2157 for (let i = 0; i < children.length; i++) {2158 move(children[i], container, anchor);2159 }2160 hostInsert(vnode.anchor, container, anchor);2161 }2162 else {2163 hostInsert(vnode.el, container, anchor);2164 }2165 }2166 function unmount(vnode, parentComponent, parentSuspense, doRemove) {2167 const { props, ref, type, component, suspense, children, dynamicChildren, shapeFlag, anchor } = vnode;2168 // unset ref2169 if (ref !== null && parentComponent !== null) {2170 setRef(ref, null, parentComponent, null);2171 }2172 if (component != null) {2173 unmountComponent(component, parentSuspense, doRemove);2174 return;2175 }2176 if ( suspense != null) {2177 unmountSuspense(suspense, parentComponent, parentSuspense, doRemove);2178 return;2179 }2180 if (props != null && props.onVnodeBeforeUnmount != null) {2181 invokeDirectiveHook(props.onVnodeBeforeUnmount, parentComponent, vnode);2182 }2183 const shouldRemoveChildren = type === Fragment && doRemove;2184 if (dynamicChildren != null) {2185 unmountChildren(dynamicChildren, parentComponent, parentSuspense, shouldRemoveChildren);2186 }2187 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {2188 unmountChildren(children, parentComponent, parentSuspense, shouldRemoveChildren);2189 }2190 if (doRemove) {2191 hostRemove(vnode.el);2192 if (anchor != null)2193 hostRemove(anchor);2194 }2195 if (props != null && props.onVnodeUnmounted != null) {2196 queuePostRenderEffect(() => {2197 invokeDirectiveHook(props.onVnodeUnmounted, parentComponent, vnode);2198 }, parentSuspense);2199 }2200 }2201 function unmountComponent(instance, parentSuspense, doRemove) {2202 const { bum, effects, update, subTree, um } = instance;2203 // beforeUnmount hook2204 if (bum !== null) {2205 invokeHooks(bum);2206 }2207 if (effects !== null) {2208 for (let i = 0; i < effects.length; i++) {2209 reactivity.stop(effects[i]);2210 }2211 }2212 // update may be null if a component is unmounted before its async2213 // setup has resolved.2214 if (update !== null) {2215 reactivity.stop(update);2216 unmount(subTree, instance, parentSuspense, doRemove);2217 }2218 // unmounted hook2219 if (um !== null) {2220 queuePostRenderEffect(um, parentSuspense);2221 }2222 queuePostFlushCb(() => {2223 instance.isUnmounted = true;2224 });2225 // A component with async dep inside a pending suspense is unmounted before2226 // its async dep resolves. This should remove the dep from the suspense, and2227 // cause the suspense to resolve immediately if that was the last dep.2228 if (2229 parentSuspense !== null &&2230 !parentSuspense.isResolved &&2231 !parentSuspense.isUnmounted &&2232 instance.asyncDep !== null &&2233 !instance.asyncResolved) {2234 parentSuspense.deps--;2235 if (parentSuspense.deps === 0) {2236 resolveSuspense(parentSuspense);2237 }2238 }2239 }2240 function unmountSuspense(suspense, parentComponent, parentSuspense, doRemove) {2241 suspense.isUnmounted = true;2242 unmount(suspense.subTree, parentComponent, parentSuspense, doRemove);2243 if (!suspense.isResolved) {2244 unmount(suspense.fallbackTree, parentComponent, parentSuspense, doRemove);2245 }2246 }2247 function unmountChildren(children, parentComponent, parentSuspense, doRemove, start = 0) {2248 for (let i = start; i < children.length; i++) {2249 unmount(children[i], parentComponent, parentSuspense, doRemove);2250 }2251 }2252 function getNextHostNode({ component, suspense, anchor, el }) {2253 if (component !== null) {2254 return getNextHostNode(component.subTree);2255 }2256 if ( suspense !== null) {2257 return getNextHostNode(suspense.isResolved ? suspense.subTree : suspense.fallbackTree);2258 }2259 return hostNextSibling((anchor || el));2260 }2261 function setRef(ref, oldRef, parent, value) {2262 const refs = parent.refs === EMPTY_OBJ ? (parent.refs = {}) : parent.refs;2263 const renderContext = reactivity.toRaw(parent.renderContext);2264 // unset old ref2265 if (oldRef !== null && oldRef !== ref) {2266 if (isString(oldRef)) {2267 refs[oldRef] = null;2268 const oldSetupRef = renderContext[oldRef];2269 if (reactivity.isRef(oldSetupRef)) {2270 oldSetupRef.value = null;2271 }2272 }2273 else if (reactivity.isRef(oldRef)) {2274 oldRef.value = null;2275 }2276 }2277 if (isString(ref)) {2278 const setupRef = renderContext[ref];2279 if (reactivity.isRef(setupRef)) {2280 setupRef.value = value;2281 }2282 refs[ref] = value;2283 }2284 else if (reactivity.isRef(ref)) {2285 ref.value = value;2286 }2287 else if (isFunction(ref)) {2288 ref(value, refs);2289 }2290 else {2291 warn('Invalid template ref type:', value, `(${typeof value})`);2292 }2293 }2294 function render(vnode, rawContainer) {2295 let container = rawContainer;2296 if (isString(container)) {2297 container = hostQuerySelector(container);2298 if (!container) {2299 {2300 warn(`Failed to locate root container: ` + `querySelector returned null.`);2301 }2302 return;2303 }2304 }2305 if (vnode == null) {2306 if (container._vnode) {2307 unmount(container._vnode, null, null, true);2308 }2309 }2310 else {2311 patch(container._vnode || null, vnode, container);2312 }2313 flushPostFlushCbs();2314 container._vnode = vnode;2315 }2316 return {2317 render,2318 createApp: createAppAPI(render)2319 };2320}2321// https://en.wikipedia.org/wiki/Longest_increasing_subsequence2322function getSequence(arr) {2323 const p = arr.slice();2324 const result = [0];2325 let i, j, u, v, c;2326 const len = arr.length;2327 for (i = 0; i < len; i++) {2328 const arrI = arr[i];2329 if (arrI !== 0) {2330 j = result[result.length - 1];2331 if (arr[j] < arrI) {2332 p[i] = j;2333 result.push(i);2334 continue;2335 }2336 u = 0;2337 v = result.length - 1;2338 while (u < v) {2339 c = ((u + v) / 2) | 0;2340 if (arr[result[c]] < arrI) {2341 u = c + 1;2342 }2343 else {2344 v = c;2345 }2346 }2347 if (arrI < arr[result[u]]) {2348 if (u > 0) {2349 p[i] = result[u - 1];2350 }2351 result[u] = i;2352 }2353 }2354 }2355 u = result.length;2356 v = result[u - 1];2357 while (u-- > 0) {2358 result[u] = v;2359 v = p[v];2360 }2361 return result;2362}2363const invoke = (fn) => fn();2364// implementation2365function watch(effectOrSource, cbOrOptions, options) {2366 if (isFunction(cbOrOptions)) {2367 // effect callback as 2nd argument - this is a source watcher2368 return doWatch(effectOrSource, cbOrOptions, options);2369 }2370 else {2371 // 2nd argument is either missing or an options object2372 // - this is a simple effect watcher2373 return doWatch(effectOrSource, null, cbOrOptions);2374 }2375}2376function doWatch(source, cb, { lazy, deep, flush, onTrack, onTrigger } = EMPTY_OBJ) {2377 const instance = currentInstance;2378 const suspense = currentSuspense;2379 let getter;2380 if (isArray(source)) {2381 getter = () => source.map(s => reactivity.isRef(s)2382 ? s.value2383 : callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */));2384 }2385 else if (reactivity.isRef(source)) {2386 getter = () => source.value;2387 }2388 else if (cb) {2389 // getter with cb2390 getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */);2391 }2392 else {2393 // no cb -> simple effect2394 getter = () => {2395 if (instance && instance.isUnmounted) {2396 return;2397 }2398 if (cleanup) {2399 cleanup();2400 }2401 return callWithErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [registerCleanup]);2402 };2403 }2404 if (deep) {2405 const baseGetter = getter;2406 getter = () => traverse(baseGetter());2407 }2408 let cleanup;2409 const registerCleanup = (fn) => {2410 // TODO wrap the cleanup fn for error handling2411 cleanup = runner.onStop = () => {2412 callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */);2413 };2414 };2415 let oldValue = isArray(source) ? [] : undefined;2416 const applyCb = cb2417 ? () => {2418 if (instance && instance.isUnmounted) {2419 return;2420 }2421 const newValue = runner();2422 if (deep || newValue !== oldValue) {2423 // cleanup before running cb again2424 if (cleanup) {2425 cleanup();2426 }2427 callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [2428 newValue,2429 oldValue,2430 registerCleanup2431 ]);2432 oldValue = newValue;2433 }2434 }2435 : void 0;2436 let scheduler;2437 if (flush === 'sync') {2438 scheduler = invoke;2439 }2440 else if (flush === 'pre') {2441 scheduler = job => {2442 if (!instance || instance.vnode.el != null) {2443 queueJob(job);2444 }2445 else {2446 // with 'pre' option, the first call must happen before2447 // the component is mounted so it is called synchronously.2448 job();2449 }2450 };2451 }2452 else {2453 scheduler = job => {2454 queuePostRenderEffect(job, suspense);2455 };2456 }2457 const runner = reactivity.effect(getter, {2458 lazy: true,2459 // so it runs before component update effects in pre flush mode2460 computed: true,2461 onTrack,2462 onTrigger,2463 scheduler: applyCb ? () => scheduler(applyCb) : scheduler2464 });2465 if (!lazy) {2466 if (applyCb) {2467 scheduler(applyCb);2468 }2469 else {2470 scheduler(runner);2471 }2472 }2473 else {2474 oldValue = runner();2475 }2476 recordEffect(runner);2477 return () => {2478 reactivity.stop(runner);2479 };2480}2481// this.$watch2482function instanceWatch(source, cb, options) {2483 const ctx = this.renderProxy;2484 const getter = isString(source) ? () => ctx[source] : source.bind(ctx);2485 const stop = watch(getter, cb.bind(ctx), options);2486 onBeforeUnmount(stop, this);2487 return stop;2488}2489function traverse(value, seen = new Set()) {2490 if (!isObject(value) || seen.has(value)) {2491 return;2492 }2493 seen.add(value);2494 if (isArray(value)) {2495 for (let i = 0; i < value.length; i++) {2496 traverse(value[i], seen);2497 }2498 }2499 else if (value instanceof Map) {2500 value.forEach((v, key) => {2501 // to register mutation dep for existing keys2502 traverse(value.get(key), seen);2503 });2504 }2505 else if (value instanceof Set) {2506 value.forEach(v => {2507 traverse(v, seen);2508 });2509 }2510 else {2511 for (const key in value) {2512 traverse(value[key], seen);2513 }2514 }2515 return value;2516}2517const publicPropertiesMap = {2518 $data: 'data',2519 $props: 'propsProxy',2520 $attrs: 'attrs',2521 $slots: 'slots',2522 $refs: 'refs',2523 $parent: 'parent',2524 $root: 'root',2525 $emit: 'emit',2526 $options: 'type'2527};2528const PublicInstanceProxyHandlers = {2529 get(target, key) {2530 const { renderContext, data, props, propsProxy, accessCache, type } = target;2531 // This getter gets called for every property access on the render context2532 // during render and is a major hotspot. The most expensive part of this2533 // is the multiple hasOwn() calls. It's much faster to do a simple property2534 // access on a plain object, so we use an accessCache object (with null2535 // prototype) to memoize what access type a key corresponds to.2536 const n = accessCache[key];2537 if (n !== undefined) {2538 switch (n) {2539 case 0 /* DATA */:2540 return data[key];2541 case 1 /* CONTEXT */:2542 return renderContext[key];2543 case 2 /* PROPS */:2544 return propsProxy[key];2545 }2546 }2547 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {2548 accessCache[key] = 0 /* DATA */;2549 return data[key];2550 }2551 else if (hasOwn(renderContext, key)) {2552 accessCache[key] = 1 /* CONTEXT */;2553 return renderContext[key];2554 }2555 else if (hasOwn(props, key)) {2556 // only cache props access if component has declared (thus stable) props2557 if (type.props != null) {2558 accessCache[key] = 2 /* PROPS */;2559 }2560 // return the value from propsProxy for ref unwrapping and readonly2561 return propsProxy[key];2562 }2563 else if (key === '$cache') {2564 return target.renderCache || (target.renderCache = []);2565 }2566 else if (key === '$el') {2567 return target.vnode.el;2568 }2569 else if (hasOwn(publicPropertiesMap, key)) {2570 return target[publicPropertiesMap[key]];2571 }2572 // methods are only exposed when options are supported2573 {2574 switch (key) {2575 case '$forceUpdate':2576 return target.update;2577 case '$nextTick':2578 return nextTick;2579 case '$watch':2580 return instanceWatch.bind(target);2581 }2582 }2583 return target.user[key];2584 },2585 set(target, key, value) {2586 const { data, renderContext } = target;2587 if (data !== EMPTY_OBJ && hasOwn(data, key)) {2588 data[key] = value;2589 }2590 else if (hasOwn(renderContext, key)) {2591 renderContext[key] = value;2592 }2593 else if (key[0] === '$' && key.slice(1) in target) {2594 2595 warn(`Attempting to mutate public property "${key}". ` +2596 `Properties starting with $ are reserved and readonly.`, target);2597 return false;2598 }2599 else if (key in target.props) {2600 2601 warn(`Attempting to mutate prop "${key}". Props are readonly.`, target);2602 return false;2603 }2604 else {2605 target.user[key] = value;2606 }2607 return true;2608 }2609};2610function provide(key, value) {2611 if (!currentInstance) {2612 {2613 warn(`provide() can only be used inside setup().`);2614 }2615 }2616 else {2617 let provides = currentInstance.provides;2618 // by default an instance inherits its parent's provides object2619 // but when it needs to provide values of its own, it creates its2620 // own provides object using parent provides object as prototype.2621 // this way in `inject` we can simply look up injections from direct2622 // parent and let the prototype chain do the work.2623 const parentProvides = currentInstance.parent && currentInstance.parent.provides;2624 if (parentProvides === provides) {2625 provides = currentInstance.provides = Object.create(parentProvides);2626 }2627 // TS doesn't allow symbol as index type2628 provides[key] = value;2629 }2630}2631function inject(key, defaultValue) {2632 if (currentInstance) {2633 const provides = currentInstance.provides;2634 if (key in provides) {2635 // TS doesn't allow symbol as index type2636 return provides[key];2637 }2638 else if (defaultValue !== undefined) {2639 return defaultValue;2640 }2641 else {2642 warn(`injection "${key}" not found.`);2643 }2644 }2645 else {2646 warn(`inject() can only be used inside setup().`);2647 }2648}2649function applyOptions(instance, options, asMixin = false) {2650 const renderContext = instance.renderContext === EMPTY_OBJ2651 ? (instance.renderContext = reactivity.reactive({}))2652 : instance.renderContext;2653 const ctx = instance.renderProxy;2654 const { 2655 // composition2656 mixins, extends: extendsOptions, 2657 // state2658 data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions, 2659 // assets2660 components, directives, 2661 // lifecycle2662 beforeMount, mounted, beforeUpdate, updated, 2663 // TODO activated2664 // TODO deactivated2665 beforeUnmount, unmounted, renderTracked, renderTriggered, errorCaptured } = options;2666 const globalMixins = instance.appContext.mixins;2667 // applyOptions is called non-as-mixin once per instance2668 if (!asMixin) {2669 callSyncHook('beforeCreate', options, ctx, globalMixins);2670 // global mixins are applied first2671 applyMixins(instance, globalMixins);2672 }2673 // extending a base component...2674 if (extendsOptions) {2675 applyOptions(instance, extendsOptions, true);2676 }2677 // local mixins2678 if (mixins) {2679 applyMixins(instance, mixins);2680 }2681 // state options2682 if (dataOptions) {2683 const data = isFunction(dataOptions) ? dataOptions.call(ctx) : dataOptions;2684 if (!isObject(data)) {2685 warn(`data() should return an object.`);2686 }2687 else if (instance.data === EMPTY_OBJ) {2688 instance.data = reactivity.reactive(data);2689 }2690 else {2691 // existing data: this is a mixin or extends.2692 extend(instance.data, data);2693 }2694 }2695 if (computedOptions) {2696 for (const key in computedOptions) {2697 const opt = computedOptions[key];2698 if (isFunction(opt)) {2699 renderContext[key] = computed(opt.bind(ctx));2700 }2701 else {2702 const { get, set } = opt;2703 if (isFunction(get)) {2704 renderContext[key] = computed({2705 get: get.bind(ctx),2706 set: isFunction(set)2707 ? set.bind(ctx)2708 : () => {2709 warn(`Computed property "${key}" was assigned to but it has no setter.`);2710 }2711 2712 });2713 }2714 else {2715 warn(`Computed property "${key}" has no getter.`);2716 }2717 }2718 }2719 }2720 if (methods) {2721 for (const key in methods) {2722 renderContext[key] = methods[key].bind(ctx);2723 }2724 }2725 if (watchOptions) {2726 for (const key in watchOptions) {2727 const raw = watchOptions[key];2728 const getter = () => ctx[key];2729 if (isString(raw)) {2730 const handler = renderContext[raw];2731 if (isFunction(handler)) {2732 watch(getter, handler);2733 }2734 else {2735 warn(`Invalid watch handler specified by key "${raw}"`, handler);2736 }2737 }2738 else if (isFunction(raw)) {2739 watch(getter, raw.bind(ctx));2740 }2741 else if (isObject(raw)) {2742 // TODO 2.x compat2743 watch(getter, raw.handler.bind(ctx), raw);2744 }2745 else {2746 warn(`Invalid watch option: "${key}"`);2747 }2748 }2749 }2750 if (provideOptions) {2751 const provides = isFunction(provideOptions)2752 ? provideOptions.call(ctx)2753 : provideOptions;2754 for (const key in provides) {2755 provide(key, provides[key]);2756 }2757 }2758 if (injectOptions) {2759 if (isArray(injectOptions)) {2760 for (let i = 0; i < injectOptions.length; i++) {2761 const key = injectOptions[i];2762 renderContext[key] = inject(key);2763 }2764 }2765 else {2766 for (const key in injectOptions) {2767 const opt = injectOptions[key];2768 if (isObject(opt)) {2769 renderContext[key] = inject(opt.from, opt.default);2770 }2771 else {2772 renderContext[key] = inject(opt);2773 }2774 }2775 }2776 }2777 // asset options2778 if (components) {2779 extend(instance.components, components);2780 }2781 if (directives) {2782 extend(instance.directives, directives);2783 }2784 // lifecycle options2785 if (!asMixin) {2786 callSyncHook('created', options, ctx, globalMixins);2787 }2788 if (beforeMount) {2789 onBeforeMount(beforeMount.bind(ctx));2790 }2791 if (mounted) {2792 onMounted(mounted.bind(ctx));2793 }2794 if (beforeUpdate) {2795 onBeforeUpdate(beforeUpdate.bind(ctx));2796 }2797 if (updated) {2798 onUpdated(updated.bind(ctx));2799 }2800 if (errorCaptured) {2801 onErrorCaptured(errorCaptured.bind(ctx));2802 }2803 if (renderTracked) {2804 onRenderTracked(renderTracked.bind(ctx));2805 }2806 if (renderTriggered) {2807 onRenderTriggered(renderTriggered.bind(ctx));2808 }2809 if (beforeUnmount) {2810 onBeforeUnmount(beforeUnmount.bind(ctx));2811 }2812 if (unmounted) {2813 onUnmounted(unmounted.bind(ctx));2814 }2815}2816function callSyncHook(name, options, ctx, globalMixins) {2817 callHookFromMixins(name, globalMixins, ctx);2818 const baseHook = options.extends && options.extends[name];2819 if (baseHook) {2820 baseHook.call(ctx);2821 }2822 const mixins = options.mixins;2823 if (mixins) {2824 callHookFromMixins(name, mixins, ctx);2825 }2826 const selfHook = options[name];2827 if (selfHook) {2828 selfHook.call(ctx);2829 }2830}2831function callHookFromMixins(name, mixins, ctx) {2832 for (let i = 0; i < mixins.length; i++) {2833 const fn = mixins[i][name];2834 if (fn) {2835 fn.call(ctx);2836 }2837 }2838}2839function applyMixins(instance, mixins) {2840 for (let i = 0; i < mixins.length; i++) {2841 applyOptions(instance, mixins[i], true);2842 }2843}2844const emptyAppContext = createAppContext();2845function createComponentInstance(vnode, parent) {2846 // inherit parent app context - or - if root, adopt from root vnode2847 const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;2848 const instance = {2849 vnode,2850 parent,2851 appContext,2852 type: vnode.type,2853 root: null,2854 next: null,2855 subTree: null,2856 update: null,2857 render: null,2858 renderProxy: null,2859 propsProxy: null,2860 setupContext: null,2861 effects: null,2862 provides: parent ? parent.provides : Object.create(appContext.provides),2863 accessCache: null,2864 renderCache: null,2865 // setup context properties2866 renderContext: EMPTY_OBJ,2867 data: EMPTY_OBJ,2868 props: EMPTY_OBJ,2869 attrs: EMPTY_OBJ,2870 slots: EMPTY_OBJ,2871 refs: EMPTY_OBJ,2872 // per-instance asset storage (mutable during options resolution)2873 components: Object.create(appContext.components),2874 directives: Object.create(appContext.directives),2875 // async dependency management2876 asyncDep: null,2877 asyncResult: null,2878 asyncResolved: false,2879 // user namespace for storing whatever the user assigns to `this`2880 user: {},2881 // lifecycle hooks2882 // not using enums here because it results in computed properties2883 isUnmounted: false,2884 bc: null,2885 c: null,2886 bm: null,2887 m: null,2888 bu: null,2889 u: null,2890 um: null,2891 bum: null,2892 da: null,2893 a: null,2894 rtg: null,2895 rtc: null,2896 ec: null,2897 emit: (event, ...args) => {2898 const props = instance.vnode.props || EMPTY_OBJ;2899 const handler = props[`on${event}`] || props[`on${capitalize(event)}`];2900 if (handler) {2901 callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);2902 }2903 }2904 };2905 instance.root = parent ? parent.root : instance;2906 return instance;2907}2908let currentInstance = null;2909let currentSuspense = null;2910const getCurrentInstance = () => currentInstance;2911const setCurrentInstance = (instance) => {2912 currentInstance = instance;2913};2914const isBuiltInTag = /*#__PURE__*/ makeMap('slot,component');2915function validateComponentName(name, config) {2916 const appIsNativeTag = config.isNativeTag || NO;2917 if (isBuiltInTag(name) || appIsNativeTag(name)) {2918 warn('Do not use built-in or reserved HTML elements as component id: ' + name);2919 }2920}2921function setupStatefulComponent(instance, parentSuspense) {2922 const Component = instance.type;2923 {2924 if (Component.name) {2925 validateComponentName(Component.name, instance.appContext.config);2926 }2927 if (Component.components) {2928 const names = Object.keys(Component.components);2929 for (let i = 0; i < names.length; i++) {2930 const name = names[i];2931 validateComponentName(name, instance.appContext.config);2932 }2933 }2934 if (Component.directives) {2935 const names = Object.keys(Component.directives);2936 for (let i = 0; i < names.length; i++) {2937 validateDirectiveName(names[i]);2938 }2939 }2940 }2941 // 0. create render proxy property access cache2942 instance.accessCache = {};2943 // 1. create render proxy2944 instance.renderProxy = new Proxy(instance, PublicInstanceProxyHandlers);2945 // 2. create props proxy2946 // the propsProxy is a reactive AND readonly proxy to the actual props.2947 // it will be updated in resolveProps() on updates before render2948 const propsProxy = (instance.propsProxy = reactivity.readonly(instance.props));2949 // 3. call setup()2950 const { setup } = Component;2951 if (setup) { ...

Full Screen

Full Screen

render.js

Source:render.js Github

copy

Full Screen

...90 return app;91 },92 directive(name, directive) {93 {94 validateDirectiveName(name);95 }96 if (!directive) {97 return context.directives[name];98 }99 if ( context.directives[name]) {100 warn(`Directive "${name}" has already been registered in target app.`);101 }102 context.directives[name] = directive;103 return app;104 },105 mount(rootContainer, isHydrate) {106 if (!isMounted) {107 const vnode = createVNode(rootComponent, rootProps);108 // store app context on the root VNode.109 // this will be set on the root instance on initial mount.110 vnode.appContext = context;111 // HMR root reload112 {113 context.reload = () => {114 render(cloneVNode(vnode), rootContainer);115 };116 }117 if (isHydrate && hydrate) {118 hydrate(vnode, rootContainer);119 }120 else {121 render(vnode, rootContainer);122 }123 isMounted = true;124 app._container = rootContainer;125 rootContainer.__vue_app__ = app;126 {127 devtoolsInitApp(app, version);128 }129 return vnode.component.proxy;130 }131 else {132 warn(`App has already been mounted.\n` +133 `If you want to remount the same app, move your app creation logic ` +134 `into a factory function and create fresh app instances for each ` +135 `mount - e.g. \`const createMyApp = () => createApp(App)\``);136 }137 },138 unmount() {139 if (isMounted) {140 render(null, app._container);141 {142 devtoolsUnmountApp(app);143 }144 }145 else {146 warn(`Cannot unmount an app that is not mounted.`);147 }148 },149 provide(key, value) {150 if ( key in context.provides) {151 warn(`App already provides property with key "${String(key)}". ` +152 `It will be overwritten with the new value.`);153 }154 // TypeScript doesn't allow symbols as index type155 // https://github.com/Microsoft/TypeScript/issues/24587156 context.provides[key] = value;157 return app;158 }159 });160 return app;161 };162}163function mount(rootContainer, isHydrate) {164 if (!isMounted) {165 const vnode = createVNode(rootComponent, rootProps);166 // store app context on the root VNode.167 // this will be set on the root instance on initial mount.168 vnode.appContext = context;169 // HMR root reload170 {171 context.reload = () => {172 render(cloneVNode(vnode), rootContainer);173 };174 }175 if (isHydrate && hydrate) {176 hydrate(vnode, rootContainer);177 }178 else {179 render(vnode, rootContainer);180 }181 isMounted = true;182 app._container = rootContainer;183 rootContainer.__vue_app__ = app;184 {185 devtoolsInitApp(app, version);186 }187 return vnode.component.proxy;188 }189 else {190 warn(`App has already been mounted.\n` +191 `If you want to remount the same app, move your app creation logic ` +192 `into a factory function and create fresh app instances for each ` +193 `mount - e.g. \`const createMyApp = () => createApp(App)\``);194 }195}196const render = (vnode, container) => {197 if (vnode == null) {198 if (container._vnode) {199 unmount(container._vnode, null, null, true);200 }201 }202 else {203 patch(container._vnode || null, vnode, container);204 }205 flushPostFlushCbs();206 container._vnode = vnode;207};208// 1. createVNode209const createVNode = ( createVNodeWithArgsTransform);210const createVNodeWithArgsTransform = (...args) => {211 return _createVNode(...(vnodeArgsTransformer212 ? vnodeArgsTransformer(args, currentRenderingInstance)213 : args));214};215function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {216 if (!type || type === NULL_DYNAMIC_COMPONENT) {217 if ( !type) {218 warn(`Invalid vnode type when creating vnode: ${type}.`);219 }220 type = Comment;221 }222 if (isVNode(type)) {223 // createVNode receiving an existing vnode. This happens in cases like224 // <component :is="vnode"/>225 // #2078 make sure to merge refs during the clone instead of overwriting it226 const cloned = cloneVNode(type, props, true /* mergeRef: true */);227 if (children) {228 normalizeChildren(cloned, children);229 }230 return cloned;231 }232 // class component normalization.233 if (isClassComponent(type)) {234 type = type.__vccOpts;235 }236 // class & style normalization.237 if (props) {238 // for reactive or proxy objects, we need to clone it to enable mutation.239 if (isProxy(props) || InternalObjectKey in props) {240 props = extend({}, props);241 }242 let { class: klass, style } = props;243 if (klass && !isString(klass)) {244 props.class = normalizeClass(klass);245 }246 if (isObject(style)) {247 // reactive state objects need to be cloned since they are likely to be248 // mutated249 if (isProxy(style) && !isArray(style)) {250 style = extend({}, style);251 }252 props.style = normalizeStyle(style);253 }254 }255 // encode the vnode type information into a bitmap256 const shapeFlag = isString(type)257 ? 1 /* ELEMENT */258 : isSuspense(type)259 ? 128 /* SUSPENSE */260 : isTeleport(type)261 ? 64 /* TELEPORT */262 : isObject(type)263 ? 4 /* STATEFUL_COMPONENT */264 : isFunction(type)265 ? 2 /* FUNCTIONAL_COMPONENT */266 : 0;267 if ( shapeFlag & 4 /* STATEFUL_COMPONENT */ && isProxy(type)) {268 type = toRaw(type);269 warn(`Vue received a Component which was made a reactive object. This can ` +270 `lead to unnecessary performance overhead, and should be avoided by ` +271 `marking the component with \`markRaw\` or using \`shallowRef\` ` +272 `instead of \`ref\`.`, `\nComponent that was made reactive: `, type);273 }274 const vnode = {275 __v_isVNode: true,276 ["__v_skip" /* SKIP */]: true,277 type,278 props,279 key: props && normalizeKey(props),280 ref: props && normalizeRef(props),281 scopeId: currentScopeId,282 children: null,283 component: null,284 suspense: null,285 ssContent: null,286 ssFallback: null,287 dirs: null,288 transition: null,289 el: null,290 anchor: null,291 target: null,292 targetAnchor: null,293 staticCount: 0,294 shapeFlag,295 patchFlag,296 dynamicProps,297 dynamicChildren: null,298 appContext: null299 };300 // validate key301 if ( vnode.key !== vnode.key) {302 warn(`VNode created with invalid key (NaN). VNode type:`, vnode.type);303 }304 normalizeChildren(vnode, children);305 // normalize suspense children306 if ( shapeFlag & 128 /* SUSPENSE */) {307 const { content, fallback } = normalizeSuspenseChildren(vnode);308 vnode.ssContent = content;309 vnode.ssFallback = fallback;310 }311 if (shouldTrack$1 > 0 &&312 // avoid a block node from tracking itself313 !isBlockNode &&314 // has current parent block315 currentBlock &&316 // presence of a patch flag indicates this node needs patching on updates.317 // component nodes also should always be patched, because even if the318 // component doesn't need to update, it needs to persist the instance on to319 // the next vnode so that it can be properly unmounted later.320 (patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) &&321 // the EVENTS flag is only for hydration and if it is the only flag, the322 // vnode should not be considered dynamic due to handler caching.323 patchFlag !== 32 /* HYDRATE_EVENTS */) {324 currentBlock.push(vnode);325 }326 return vnode;327}328function normalizeVNode(child) {329 if (child == null || typeof child === 'boolean') {330 // empty placeholder331 return createVNode(Comment);332 }333 else if (isArray(child)) {334 // fragment335 return createVNode(Fragment, null, child);336 }337 else if (typeof child === 'object') {338 // already vnode, this should be the most common since compiled templates339 // always produce all-vnode children arrays340 return child.el === null ? child : cloneVNode(child);341 }342 else {343 // strings and numbers344 return createVNode(Text, null, String(child));345 }346}347const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, optimized, start = 0) => {348 for (let i = start; i < children.length; i++) {349 const child = (children[i] = optimized350 ? cloneIfMounted(children[i])351 : normalizeVNode(children[i]));352 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, optimized);353 }354};355const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, optimized = false) => {356 // patching & not same type, unmount old tree357 if (n1 && !isSameVNodeType(n1, n2)) {358 anchor = getNextHostNode(n1);359 unmount(n1, parentComponent, parentSuspense, true);360 n1 = null;361 }362 if (n2.patchFlag === -2 /* BAIL */) {363 optimized = false;364 n2.dynamicChildren = null;365 }366 const { type, ref, shapeFlag } = n2;367 switch (type) {368 case Text:369 processText(n1, n2, container, anchor);370 break;371 case Comment:372 processCommentNode(n1, n2, container, anchor);373 break;374 case Static:375 if (n1 == null) {376 mountStaticNode(n2, container, anchor, isSVG);377 }378 else {379 patchStaticNode(n1, n2, container, isSVG);380 }381 break;382 case Fragment:383 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);384 break;385 default:386 if (shapeFlag & 1 /* ELEMENT */) {387 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);388 }389 else if (shapeFlag & 6 /* COMPONENT */) {390 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);391 }392 else if (shapeFlag & 64 /* TELEPORT */) {393 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals);394 }395 else if ( shapeFlag & 128 /* SUSPENSE */) {396 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals);397 }398 else {399 warn('Invalid VNode type:', type, `(${typeof type})`);400 }401 }402 // set ref403 if (ref != null && parentComponent) {404 setRef(ref, n1 && n1.ref, parentComponent, parentSuspense, n2);405 }406};407 // const { 408 // insert: hostInsert, 409 // remove: hostRemove, 410 // patchProp: hostPatchProp, 411 // forcePatchProp: hostForcePatchProp, 412 // createElement: hostCreateElement, 413 // createText: hostCreateText, 414 // createComment: hostCreateComment, 415 // setText: hostSetText, 416 // setElementText: hostSetElementText, 417 // parentNode: hostParentNode, 418 // nextSibling: hostNextSibling, 419 // setScopeId: hostSetScopeId = NOOP, 420 // cloneNode: hostCloneNode, 421 // insertStaticContent: hostInsertStaticContent 422 // } = options;423 424 const nodeOps = {425 insert: (child, parent, anchor) => {426 parent.insertBefore(child, anchor || null);427 },428 remove: child => {429 const parent = child.parentNode;430 if (parent) {431 parent.removeChild(child);432 }433 },434 createElement: (tag, isSVG, is) => isSVG435 ? doc.createElementNS(svgNS, tag)436 : doc.createElement(tag, is ? { is } : undefined),437 createText: text => doc.createTextNode(text),438 createComment: text => doc.createComment(text),439 setText: (node, text) => {440 node.nodeValue = text;441 },442 setElementText: (el, text) => {443 el.textContent = text;444 },445 parentNode: node => node.parentNode,446 nextSibling: node => node.nextSibling,447 querySelector: selector => doc.querySelector(selector),448 setScopeId(el, id) {449 el.setAttribute(id, '');450 },451 cloneNode(el) {452 return el.cloneNode(true);453 },454 // __UNSAFE__455 // Reason: innerHTML.456 // Static content here can only come from compiled templates.457 // As long as the user only uses trusted templates, this is safe.458 insertStaticContent(content, parent, anchor, isSVG) {459 const temp = isSVG460 ? tempSVGContainer ||461 (tempSVGContainer = doc.createElementNS(svgNS, 'svg'))462 : tempContainer || (tempContainer = doc.createElement('div'));463 temp.innerHTML = content;464 const first = temp.firstChild;465 let node = first;466 let last = node;467 while (node) {468 last = node;469 nodeOps.insert(node, parent, anchor);470 node = temp.firstChild;471 }472 return [first, last];473 }474 };475 const processText = (n1, n2, container, anchor) => {476 if (n1 == null) {477 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);478 }479 else {480 const el = (n2.el = n1.el);481 if (n2.children !== n1.children) {482 hostSetText(el, n2.children);483 }484 }485 };486 const processCommentNode = (n1, n2, container, anchor) => {487 if (n1 == null) {488 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);489 }490 else {491 // there's no support for dynamic comments492 n2.el = n1.el;493 }494 };495 const mountStaticNode = (n2, container, anchor, isSVG) => {496 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);497 };498 /**499 * Dev / HMR only500 */501 const patchStaticNode = (n1, n2, container, isSVG) => {502 // static nodes are only patched during dev for HMR503 if (n2.children !== n1.children) {504 const anchor = hostNextSibling(n1.anchor);505 // remove existing506 removeStaticNode(n1);507 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);508 }509 else {510 n2.el = n1.el;511 n2.anchor = n1.anchor;512 }513 };514 const removeStaticNode = (vnode) => {515 let cur = vnode.el;516 while (cur && cur !== vnode.anchor) {517 const next = hostNextSibling(cur);518 hostRemove(cur);519 cur = next;520 }521 hostRemove(vnode.anchor);522 };523 // function normalizeVNode(child) {524 // if (child == null || typeof child === 'boolean') {525 // // empty placeholder526 // return createVNode(Comment);527 // }528 // else if (isArray(child)) {529 // // fragment530 // return createVNode(Fragment, null, child);531 // }532 // else if (typeof child === 'object') {533 // // already vnode, this should be the most common since compiled templates534 // // always produce all-vnode children arrays535 // return child.el === null ? child : cloneVNode(child);536 // }537 // else {538 // // strings and numbers539 // return createVNode(Text, null, String(child));540 // }541 // }542 const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {543 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''));544 const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''));545 let { patchFlag, dynamicChildren } = n2;546 if (patchFlag > 0) {547 optimized = true;548 }549 if ( isHmrUpdating) {550 // HMR updated, force full diff551 patchFlag = 0;552 optimized = false;553 dynamicChildren = null;554 }555 if (n1 == null) {556 hostInsert(fragmentStartAnchor, container, anchor);557 hostInsert(fragmentEndAnchor, container, anchor);558 // a fragment can only have array children559 // since they are either generated by the compiler, or implicitly created560 // from arrays.561 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);562 }563 else {564 if (patchFlag > 0 &&565 patchFlag & 64 /* STABLE_FRAGMENT */ &&566 dynamicChildren) {567 // a stable fragment (template root or <template v-for>) doesn't need to568 // patch children order, but it may contain dynamicChildren.569 patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG);570 if ( parentComponent && parentComponent.type.__hmrId) {571 traverseStaticChildren(n1, n2);572 }573 else if (574 // #2080 if the stable fragment has a key, it's a <template v-for> that may575 // get moved around. Make sure all root level vnodes inherit el.576 // #2134 or if it's a component root, it may also get moved around577 // as the component is being moved.578 n2.key != null ||579 (parentComponent && n2 === parentComponent.subTree)) {580 traverseStaticChildren(n1, n2, true /* shallow */);581 }582 }583 else {584 // keyed / unkeyed, or manual fragments.585 // for keyed & unkeyed, since they are compiler generated from v-for,586 // each child is guaranteed to be a block so the fragment will never587 // have dynamicChildren.588 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);589 }590 }591 };592 const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {593 isSVG = isSVG || n2.type === 'svg';594 if (n1 == null) {595 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);596 }597 else {598 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized);599 }600 };601 const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {602 let el;603 let vnodeHook;604 const { type, props, shapeFlag, transition, scopeId, patchFlag, dirs } = vnode;605 {606 el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is);607 // mount children first, since some props may rely on child content608 // being already rendered, e.g. `<select value>`609 if (shapeFlag & 8 /* TEXT_CHILDREN */) {610 hostSetElementText(el, vnode.children);611 }612 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {613 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', optimized || !!vnode.dynamicChildren);614 }615 if (dirs) {616 invokeDirectiveHook(vnode, null, parentComponent, 'created');617 }618 // props619 if (props) {620 for (const key in props) {621 if (!isReservedProp(key)) {622 hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);623 }624 }625 if ((vnodeHook = props.onVnodeBeforeMount)) {626 invokeVNodeHook(vnodeHook, parentComponent, vnode);627 }628 }629 // scopeId630 setScopeId(el, scopeId, vnode, parentComponent);631 }632 {633 Object.defineProperty(el, '__vnode', {634 value: vnode,635 enumerable: false636 });637 Object.defineProperty(el, '__vueParentComponent', {638 value: parentComponent,639 enumerable: false640 });641 }642 if (dirs) {643 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');644 }645 // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved646 // #1689 For inside suspense + suspense resolved case, just call it647 const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) &&648 transition &&649 !transition.persisted;650 if (needCallTransitionHooks) {651 transition.beforeEnter(el);652 }653 hostInsert(el, container, anchor);654 if ((vnodeHook = props && props.onVnodeMounted) ||655 needCallTransitionHooks ||656 dirs) {657 queuePostRenderEffect(() => {658 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);659 needCallTransitionHooks && transition.enter(el);660 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');661 }, parentSuspense);662 }663 };664 const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, optimized) => {665 const el = (n2.el = n1.el);666 let { patchFlag, dynamicChildren, dirs } = n2;667 // #1426 take the old vnode's patch flag into account since user may clone a668 // compiler-generated vnode, which de-opts to FULL_PROPS669 patchFlag |= n1.patchFlag & 16 /* FULL_PROPS */;670 const oldProps = n1.props || EMPTY_OBJ;671 const newProps = n2.props || EMPTY_OBJ;672 let vnodeHook;673 if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {674 invokeVNodeHook(vnodeHook, parentComponent, n2, n1);675 }676 if (dirs) {677 invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');678 }679 if ( isHmrUpdating) {680 // HMR updated, force full diff681 patchFlag = 0;682 optimized = false;683 dynamicChildren = null;684 }685 if (patchFlag > 0) {686 // the presence of a patchFlag means this element's render code was687 // generated by the compiler and can take the fast path.688 // in this path old node and new node are guaranteed to have the same shape689 // (i.e. at the exact same position in the source template)690 if (patchFlag & 16 /* FULL_PROPS */) {691 // element props contain dynamic keys, full diff needed692 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);693 }694 else {695 // class696 // this flag is matched when the element has dynamic class bindings.697 if (patchFlag & 2 /* CLASS */) {698 if (oldProps.class !== newProps.class) {699 hostPatchProp(el, 'class', null, newProps.class, isSVG);700 }701 }702 // style703 // this flag is matched when the element has dynamic style bindings704 if (patchFlag & 4 /* STYLE */) {705 hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG);706 }707 // props708 // This flag is matched when the element has dynamic prop/attr bindings709 // other than class and style. The keys of dynamic prop/attrs are saved for710 // faster iteration.711 // Note dynamic keys like :[foo]="bar" will cause this optimization to712 // bail out and go through a full diff because we need to unset the old key713 if (patchFlag & 8 /* PROPS */) {714 // if the flag is present then dynamicProps must be non-null715 const propsToUpdate = n2.dynamicProps;716 for (let i = 0; i < propsToUpdate.length; i++) {717 const key = propsToUpdate[i];718 const prev = oldProps[key];719 const next = newProps[key];720 if (next !== prev ||721 (hostForcePatchProp && hostForcePatchProp(el, key))) {722 hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);723 }724 }725 }726 }727 // text728 // This flag is matched when the element has only dynamic text children.729 if (patchFlag & 1 /* TEXT */) {730 if (n1.children !== n2.children) {731 hostSetElementText(el, n2.children);732 }733 }734 }735 else if (!optimized && dynamicChildren == null) {736 // unoptimized, full diff737 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);738 }739 const areChildrenSVG = isSVG && n2.type !== 'foreignObject';740 if (dynamicChildren) {741 patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG);742 if ( parentComponent && parentComponent.type.__hmrId) {743 traverseStaticChildren(n1, n2);744 }745 }746 else if (!optimized) {747 // full diff748 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG);749 }750 if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {751 queuePostRenderEffect(() => {752 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1);753 dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated');754 }, parentSuspense);755 }756 };757 const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {758 if (n1 == null) {759 if (n2.shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {760 parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized);761 }762 else {763 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);764 }765 }766 else {767 updateComponent(n1, n2, optimized);768 }769 };770 const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {771 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));772 if ( instance.type.__hmrId) {773 registerHMR(instance);774 }775 {776 pushWarningContext(initialVNode);777 startMeasure(instance, `mount`);778 }779 // inject renderer internals for keepAlive780 if (isKeepAlive(initialVNode)) {781 instance.ctx.renderer = internals;782 }783 // resolve props and slots for setup context784 {785 startMeasure(instance, `init`);786 }787 setupComponent(instance);788 {789 endMeasure(instance, `init`);790 }791 // setup() is async. This component relies on async logic to be resolved792 // before proceeding793 if ( instance.asyncDep) {794 parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect);795 // Give it a placeholder if this is not hydration796 // TODO handle self-defined fallback797 if (!initialVNode.el) {798 const placeholder = (instance.subTree = createVNode(Comment));799 processCommentNode(null, placeholder, container, anchor);800 }801 return;802 }803 // setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized);804 setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized);805 {806 popWarningContext();807 endMeasure(instance, `mount`);808 }809 };810 function setupComponent(instance, isSSR = false) {811 isInSSRComponentSetup = isSSR;812 const { props, children, shapeFlag } = instance.vnode;813 const isStateful = shapeFlag & 4 /* STATEFUL_COMPONENT */;814 initProps(instance, props, isStateful, isSSR);815 initSlots(instance, children);816 const setupResult = isStateful817 ? setupStatefulComponent(instance, isSSR)818 : undefined;819 isInSSRComponentSetup = false;820 return setupResult;821 }822 function setupStatefulComponent(instance, isSSR) {823 const Component = instance.type;824 {825 if (Component.name) {826 validateComponentName(Component.name, instance.appContext.config);827 }828 if (Component.components) {829 const names = Object.keys(Component.components);830 for (let i = 0; i < names.length; i++) {831 validateComponentName(names[i], instance.appContext.config);832 }833 }834 if (Component.directives) {835 const names = Object.keys(Component.directives);836 for (let i = 0; i < names.length; i++) {837 validateDirectiveName(names[i]);838 }839 }840 }841 // 0. create render proxy property access cache842 instance.accessCache = {};843 // 1. create public instance / render proxy844 // also mark it raw so it's never observed845 instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers);846 {847 exposePropsOnRenderContext(instance);848 }849 // 2. call setup()850 const { setup } = Component;851 if (setup) {...

Full Screen

Full Screen

note.js

Source:note.js Github

copy

Full Screen

...66 return app;67 },68 directive(name, directive) {69 {70 validateDirectiveName(name);71 }72 if (!directive) {73 return context.directives[name];74 }75 if ( context.directives[name]) {76 warn(`Directive "${name}" has already been registered in target app.`);77 }78 context.directives[name] = directive;79 return app;80 },81 mount(rootContainer, isHydrate) {82 if (!isMounted) {83 const vnode = createVNode(rootComponent, rootProps);84 // store app context on the root VNode.85 // this will be set on the root instance on initial mount.86 vnode.appContext = context;87 // HMR root reload88 {89 context.reload = () => {90 render(cloneVNode(vnode), rootContainer);91 };92 }93 if (isHydrate && hydrate) {94 hydrate(vnode, rootContainer);95 }96 else {97 render(vnode, rootContainer);98 }99 isMounted = true;100 app._container = rootContainer;101 rootContainer.__vue_app__ = app;102 {103 devtoolsInitApp(app, version);104 }105 return vnode.component.proxy;106 }107 else {108 warn(`App has already been mounted.\n` +109 `If you want to remount the same app, move your app creation logic ` +110 `into a factory function and create fresh app instances for each ` +111 `mount - e.g. \`const createMyApp = () => createApp(App)\``);112 }113 },114 unmount() {115 if (isMounted) {116 render(null, app._container);117 {118 devtoolsUnmountApp(app);119 }120 }121 else {122 warn(`Cannot unmount an app that is not mounted.`);123 }124 },125 provide(key, value) {126 if ( key in context.provides) {127 warn(`App already provides property with key "${String(key)}". ` +128 `It will be overwritten with the new value.`);129 }130 // TypeScript doesn't allow symbols as index type131 // https://github.com/Microsoft/TypeScript/issues/24587132 context.provides[key] = value;133 return app;134 }135 });136 return app;137};138// app context139function createAppContext() {140 return {141 app: null,142 config: {143 isNativeTag: NO,144 performance: false,145 globalProperties: {},146 optionMergeStrategies: {},147 isCustomElement: NO,148 errorHandler: undefined,149 warnHandler: undefined150 },151 mixins: [],152 components: {},153 directives: {},154 provides: Object.create(null)155 };156}157/**158 * mount159 * 1. createVNode(rootComponent, rootProps)160 * 2. render(cloneVNode(vnode), rootContainer) | hydrate(vnode, rootContainer);161 * 3. devtoolsInitApp(app, version);162 */163function mount(rootContainer, isHydrate) {164 if (!isMounted) {165 const vnode = createVNode(rootComponent, rootProps);166 // store app context on the root VNode.167 // this will be set on the root instance on initial mount.168 vnode.appContext = context;169 // HMR root reload170 {171 context.reload = () => {172 render(cloneVNode(vnode), rootContainer);173 };174 }175 if (isHydrate && hydrate) {176 hydrate(vnode, rootContainer);177 }178 else {179 render(vnode, rootContainer);180 }181 isMounted = true;182 app._container = rootContainer;183 rootContainer.__vue_app__ = app;184 {185 devtoolsInitApp(app, version);186 }187 return vnode.component.proxy;188 }189 else {190 warn(`App has already been mounted.\n` +191 `If you want to remount the same app, move your app creation logic ` +192 `into a factory function and create fresh app instances for each ` +193 `mount - e.g. \`const createMyApp = () => createApp(App)\``);194 }195}196// createVNode 2997197const createVNode = ( createVNodeWithArgsTransform);198const createVNodeWithArgsTransform = (...args) => {199 return _createVNode(...(vnodeArgsTransformer ? vnodeArgsTransformer(args, currentRenderingInstance) : args))200}201function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {202 if (!type || type === NULL_DYNAMIC_COMPONENT) {203 if ( !type) {204 warn(`Invalid vnode type when creating vnode: ${type}.`);205 }206 type = Comment;207 }208 if (isVNode(type)) {209 // createVNode receiving an existing vnode. This happens in cases like210 // <component :is="vnode"/>211 // #2078 make sure to merge refs during the clone instead of overwriting it212 const cloned = cloneVNode(type, props, true /* mergeRef: true */);213 if (children) {214 normalizeChildren(cloned, children);215 }216 return cloned;217 }218 // class component normalization.219 if (isClassComponent(type)) {220 type = type.__vccOpts;221 }222 // class & style normalization.223 if (props) {224 // for reactive or proxy objects, we need to clone it to enable mutation.225 if (isProxy(props) || InternalObjectKey in props) {226 props = extend({}, props);227 }228 let { class: klass, style } = props;229 if (klass && !isString(klass)) {230 props.class = normalizeClass(klass);231 }232 if (isObject(style)) {233 // reactive state objects need to be cloned since they are likely to be234 // mutated235 if (isProxy(style) && !isArray(style)) {236 style = extend({}, style);237 }238 props.style = normalizeStyle(style);239 }240 }241 // encode the vnode type information into a bitmap242 const shapeFlag = isString(type)243 ? 1 /* ELEMENT */244 : isSuspense(type)245 ? 128 /* SUSPENSE */246 : isTeleport(type)247 ? 64 /* TELEPORT */248 : isObject(type)249 ? 4 /* STATEFUL_COMPONENT */250 : isFunction(type)251 ? 2 /* FUNCTIONAL_COMPONENT */252 : 0;253 if ( shapeFlag & 4 /* STATEFUL_COMPONENT */ && isProxy(type)) {254 type = toRaw(type);255 warn(`Vue received a Component which was made a reactive object. This can ` +256 `lead to unnecessary performance overhead, and should be avoided by ` +257 `marking the component with \`markRaw\` or using \`shallowRef\` ` +258 `instead of \`ref\`.`, `\nComponent that was made reactive: `, type);259 }260 const vnode = {261 __v_isVNode: true,262 ["__v_skip" /* SKIP */]: true,263 type,264 props,265 key: props && normalizeKey(props),266 ref: props && normalizeRef(props),267 scopeId: currentScopeId,268 children: null,269 component: null,270 suspense: null,271 ssContent: null,272 ssFallback: null,273 dirs: null,274 transition: null,275 el: null,276 anchor: null,277 target: null,278 targetAnchor: null,279 staticCount: 0,280 shapeFlag,281 patchFlag,282 dynamicProps,283 dynamicChildren: null,284 appContext: null285 };286 // validate key287 if ( vnode.key !== vnode.key) {288 warn(`VNode created with invalid key (NaN). VNode type:`, vnode.type);289 }290 normalizeChildren(vnode, children);291 // normalize suspense children292 if ( shapeFlag & 128 /* SUSPENSE */) {293 const { content, fallback } = normalizeSuspenseChildren(vnode);294 vnode.ssContent = content;295 vnode.ssFallback = fallback;296 }297 if (shouldTrack$1 > 0 &&298 // avoid a block node from tracking itself299 !isBlockNode &&300 // has current parent block301 currentBlock &&302 // presence of a patch flag indicates this node needs patching on updates.303 // component nodes also should always be patched, because even if the304 // component doesn't need to update, it needs to persist the instance on to305 // the next vnode so that it can be properly unmounted later.306 (patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) &&307 // the EVENTS flag is only for hydration and if it is the only flag, the308 // vnode should not be considered dynamic due to handler caching.309 patchFlag !== 32 /* HYDRATE_EVENTS */) {310 currentBlock.push(vnode);311 }312 return vnode;313}314// render 8936315const render = ((...args) => {316 ensureRenderer().render(...args);317});318function ensureRenderer() { // 8925319 return renderer || (renderer = createRenderer(rendererOptions));320}321function createRenderer(options) {322 return baseCreateRenderer(options);323}324// implementation 5106325function baseCreateRenderer(options, createHydrationFns) {326 const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, forcePatchProp: hostForcePatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, setScopeId: hostSetScopeId = NOOP, cloneNode: hostCloneNode, insertStaticContent: hostInsertStaticContent } = options;327 // Note: functions inside this closure should use `const xxx = () => {}`328 // style in order to prevent being inlined by minifiers.329 const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, optimized = false) => {330 // patching & not same type, unmount old tree331 if (n1 && !isSameVNodeType(n1, n2)) {332 anchor = getNextHostNode(n1);333 unmount(n1, parentComponent, parentSuspense, true);334 n1 = null;335 }336 if (n2.patchFlag === -2 /* BAIL */) {337 optimized = false;338 n2.dynamicChildren = null;339 }340 const { type, ref, shapeFlag } = n2;341 switch (type) {342 case Text:343 processText(n1, n2, container, anchor);344 break;345 case Comment:346 processCommentNode(n1, n2, container, anchor);347 break;348 case Static:349 if (n1 == null) {350 mountStaticNode(n2, container, anchor, isSVG);351 }352 else {353 patchStaticNode(n1, n2, container, isSVG);354 }355 break;356 case Fragment:357 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);358 break;359 default:360 if (shapeFlag & 1 /* ELEMENT */) {361 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);362 }363 else if (shapeFlag & 6 /* COMPONENT */) {364 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);365 }366 else if (shapeFlag & 64 /* TELEPORT */) {367 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals);368 }369 else if ( shapeFlag & 128 /* SUSPENSE */) {370 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals);371 }372 else {373 warn('Invalid VNode type:', type, `(${typeof type})`);374 }375 }376 // set ref377 if (ref != null && parentComponent) {378 setRef(ref, n1 && n1.ref, parentComponent, parentSuspense, n2);379 }380 };381 const processText = (n1, n2, container, anchor) => {382 if (n1 == null) {383 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);384 }385 else {386 const el = (n2.el = n1.el);387 if (n2.children !== n1.children) {388 hostSetText(el, n2.children);389 }390 }391 };392 const processCommentNode = (n1, n2, container, anchor) => {393 if (n1 == null) {394 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);395 }396 else {397 // there's no support for dynamic comments398 n2.el = n1.el;399 }400 };401 const mountStaticNode = (n2, container, anchor, isSVG) => {402 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);403 };404 /**405 * Dev / HMR only406 */407 const patchStaticNode = (n1, n2, container, isSVG) => {408 // static nodes are only patched during dev for HMR409 if (n2.children !== n1.children) {410 const anchor = hostNextSibling(n1.anchor);411 // remove existing412 removeStaticNode(n1);413 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);414 }415 else {416 n2.el = n1.el;417 n2.anchor = n1.anchor;418 }419 };420 /**421 * Dev / HMR only422 */423 const moveStaticNode = (vnode, container, anchor) => {424 let cur = vnode.el;425 const end = vnode.anchor;426 while (cur && cur !== end) {427 const next = hostNextSibling(cur);428 hostInsert(cur, container, anchor);429 cur = next;430 }431 hostInsert(end, container, anchor);432 };433 /**434 * Dev / HMR only435 */436 const removeStaticNode = (vnode) => {437 let cur = vnode.el;438 while (cur && cur !== vnode.anchor) {439 const next = hostNextSibling(cur);440 hostRemove(cur);441 cur = next;442 }443 hostRemove(vnode.anchor);444 };445 const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {446 isSVG = isSVG || n2.type === 'svg';447 if (n1 == null) {448 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);449 }450 else {451 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized);452 }453 };454 const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {455 let el;456 let vnodeHook;457 const { type, props, shapeFlag, transition, scopeId, patchFlag, dirs } = vnode;458 {459 el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is);460 // mount children first, since some props may rely on child content461 // being already rendered, e.g. `<select value>`462 if (shapeFlag & 8 /* TEXT_CHILDREN */) {463 hostSetElementText(el, vnode.children);464 }465 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {466 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', optimized || !!vnode.dynamicChildren);467 }468 if (dirs) {469 invokeDirectiveHook(vnode, null, parentComponent, 'created');470 }471 // props472 if (props) {473 for (const key in props) {474 if (!isReservedProp(key)) {475 hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);476 }477 }478 if ((vnodeHook = props.onVnodeBeforeMount)) {479 invokeVNodeHook(vnodeHook, parentComponent, vnode);480 }481 }482 // scopeId483 setScopeId(el, scopeId, vnode, parentComponent);484 }485 {486 Object.defineProperty(el, '__vnode', {487 value: vnode,488 enumerable: false489 });490 Object.defineProperty(el, '__vueParentComponent', {491 value: parentComponent,492 enumerable: false493 });494 }495 if (dirs) {496 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');497 }498 // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved499 // #1689 For inside suspense + suspense resolved case, just call it500 const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) &&501 transition &&502 !transition.persisted;503 if (needCallTransitionHooks) {504 transition.beforeEnter(el);505 }506 hostInsert(el, container, anchor);507 if ((vnodeHook = props && props.onVnodeMounted) ||508 needCallTransitionHooks ||509 dirs) {510 queuePostRenderEffect(() => {511 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);512 needCallTransitionHooks && transition.enter(el);513 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');514 }, parentSuspense);515 }516 };517 const setScopeId = (el, scopeId, vnode, parentComponent) => {518 if (scopeId) {519 hostSetScopeId(el, scopeId);520 }521 if (parentComponent) {522 const treeOwnerId = parentComponent.type.__scopeId;523 // vnode's own scopeId and the current patched component's scopeId is524 // different - this is a slot content node.525 if (treeOwnerId && treeOwnerId !== scopeId) {526 hostSetScopeId(el, treeOwnerId + '-s');527 }528 let subTree = parentComponent.subTree;529 if ( subTree.type === Fragment) {530 subTree =531 filterSingleRoot(subTree.children) || subTree;532 }533 if (vnode === subTree) {534 setScopeId(el, parentComponent.vnode.scopeId, parentComponent.vnode, parentComponent.parent);535 }536 }537 };538 const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, optimized, start = 0) => {539 for (let i = start; i < children.length; i++) {540 const child = (children[i] = optimized541 ? cloneIfMounted(children[i])542 : normalizeVNode(children[i]));543 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, optimized);544 }545 };546 const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, optimized) => {547 const el = (n2.el = n1.el);548 let { patchFlag, dynamicChildren, dirs } = n2;549 // #1426 take the old vnode's patch flag into account since user may clone a550 // compiler-generated vnode, which de-opts to FULL_PROPS551 patchFlag |= n1.patchFlag & 16 /* FULL_PROPS */;552 const oldProps = n1.props || EMPTY_OBJ;553 const newProps = n2.props || EMPTY_OBJ;554 let vnodeHook;555 if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {556 invokeVNodeHook(vnodeHook, parentComponent, n2, n1);557 }558 if (dirs) {559 invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');560 }561 if ( isHmrUpdating) {562 // HMR updated, force full diff563 patchFlag = 0;564 optimized = false;565 dynamicChildren = null;566 }567 if (patchFlag > 0) {568 // the presence of a patchFlag means this element's render code was569 // generated by the compiler and can take the fast path.570 // in this path old node and new node are guaranteed to have the same shape571 // (i.e. at the exact same position in the source template)572 if (patchFlag & 16 /* FULL_PROPS */) {573 // element props contain dynamic keys, full diff needed574 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);575 }576 else {577 // class578 // this flag is matched when the element has dynamic class bindings.579 if (patchFlag & 2 /* CLASS */) {580 if (oldProps.class !== newProps.class) {581 hostPatchProp(el, 'class', null, newProps.class, isSVG);582 }583 }584 // style585 // this flag is matched when the element has dynamic style bindings586 if (patchFlag & 4 /* STYLE */) {587 hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG);588 }589 // props590 // This flag is matched when the element has dynamic prop/attr bindings591 // other than class and style. The keys of dynamic prop/attrs are saved for592 // faster iteration.593 // Note dynamic keys like :[foo]="bar" will cause this optimization to594 // bail out and go through a full diff because we need to unset the old key595 if (patchFlag & 8 /* PROPS */) {596 // if the flag is present then dynamicProps must be non-null597 const propsToUpdate = n2.dynamicProps;598 for (let i = 0; i < propsToUpdate.length; i++) {599 const key = propsToUpdate[i];600 const prev = oldProps[key];601 const next = newProps[key];602 if (next !== prev ||603 (hostForcePatchProp && hostForcePatchProp(el, key))) {604 hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);605 }606 }607 }608 }609 // text610 // This flag is matched when the element has only dynamic text children.611 if (patchFlag & 1 /* TEXT */) {612 if (n1.children !== n2.children) {613 hostSetElementText(el, n2.children);614 }615 }616 }617 else if (!optimized && dynamicChildren == null) {618 // unoptimized, full diff619 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);620 }621 const areChildrenSVG = isSVG && n2.type !== 'foreignObject';622 if (dynamicChildren) {623 patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG);624 if ( parentComponent && parentComponent.type.__hmrId) {625 traverseStaticChildren(n1, n2);626 }627 }628 else if (!optimized) {629 // full diff630 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG);631 }632 if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {633 queuePostRenderEffect(() => {634 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1);635 dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated');636 }, parentSuspense);637 }638 };639 // The fast path for blocks.640 const patchBlockChildren = (oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG) => {641 for (let i = 0; i < newChildren.length; i++) {642 const oldVNode = oldChildren[i];643 const newVNode = newChildren[i];644 // Determine the container (parent element) for the patch.645 const container = 646 // - In the case of a Fragment, we need to provide the actual parent647 // of the Fragment itself so it can move its children.648 oldVNode.type === Fragment ||649 // - In the case of different nodes, there is going to be a replacement650 // which also requires the correct parent container651 !isSameVNodeType(oldVNode, newVNode) ||652 // - In the case of a component, it could contain anything.653 oldVNode.shapeFlag & 6 /* COMPONENT */ ||654 oldVNode.shapeFlag & 64 /* TELEPORT */655 ? hostParentNode(oldVNode.el)656 : // In other cases, the parent container is not actually used so we657 // just pass the block element here to avoid a DOM parentNode call.658 fallbackContainer;659 patch(oldVNode, newVNode, container, null, parentComponent, parentSuspense, isSVG, true);660 }661 };662 const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {663 if (oldProps !== newProps) {664 for (const key in newProps) {665 if (isReservedProp(key))666 continue;667 const next = newProps[key];668 const prev = oldProps[key];669 if (next !== prev ||670 (hostForcePatchProp && hostForcePatchProp(el, key))) {671 hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);672 }673 }674 if (oldProps !== EMPTY_OBJ) {675 for (const key in oldProps) {676 if (!isReservedProp(key) && !(key in newProps)) {677 hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);678 }679 }680 }681 }682 };683 const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {684 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''));685 const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''));686 let { patchFlag, dynamicChildren } = n2;687 if (patchFlag > 0) {688 optimized = true;689 }690 if ( isHmrUpdating) {691 // HMR updated, force full diff692 patchFlag = 0;693 optimized = false;694 dynamicChildren = null;695 }696 if (n1 == null) {697 hostInsert(fragmentStartAnchor, container, anchor);698 hostInsert(fragmentEndAnchor, container, anchor);699 // a fragment can only have array children700 // since they are either generated by the compiler, or implicitly created701 // from arrays.702 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);703 }704 else {705 if (patchFlag > 0 &&706 patchFlag & 64 /* STABLE_FRAGMENT */ &&707 dynamicChildren) {708 // a stable fragment (template root or <template v-for>) doesn't need to709 // patch children order, but it may contain dynamicChildren.710 patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG);711 if ( parentComponent && parentComponent.type.__hmrId) {712 traverseStaticChildren(n1, n2);713 }714 else if (715 // #2080 if the stable fragment has a key, it's a <template v-for> that may716 // get moved around. Make sure all root level vnodes inherit el.717 // #2134 or if it's a component root, it may also get moved around718 // as the component is being moved.719 n2.key != null ||720 (parentComponent && n2 === parentComponent.subTree)) {721 traverseStaticChildren(n1, n2, true /* shallow */);722 }723 }724 else {725 // keyed / unkeyed, or manual fragments.726 // for keyed & unkeyed, since they are compiler generated from v-for,727 // each child is guaranteed to be a block so the fragment will never728 // have dynamicChildren.729 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);730 }731 }732 };733 const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {734 if (n1 == null) {735 if (n2.shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {736 parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized);737 }738 else {739 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);740 }741 }742 else {743 updateComponent(n1, n2, optimized);744 }745 };746 const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {747 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));748 if ( instance.type.__hmrId) {749 registerHMR(instance);750 }751 {752 pushWarningContext(initialVNode);753 startMeasure(instance, `mount`);754 }755 // inject renderer internals for keepAlive756 if (isKeepAlive(initialVNode)) {757 instance.ctx.renderer = internals;758 }759 // resolve props and slots for setup context760 {761 startMeasure(instance, `init`);762 }763 setupComponent(instance);764 {765 endMeasure(instance, `init`);766 }767 // setup() is async. This component relies on async logic to be resolved768 // before proceeding769 if ( instance.asyncDep) {770 parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect);771 // Give it a placeholder if this is not hydration772 // TODO handle self-defined fallback773 if (!initialVNode.el) {774 const placeholder = (instance.subTree = createVNode(Comment));775 processCommentNode(null, placeholder, container, anchor);776 }777 return;778 }779 setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized);780 {781 popWarningContext();782 endMeasure(instance, `mount`);783 }784 };785 const updateComponent = (n1, n2, optimized) => {786 const instance = (n2.component = n1.component);787 if (shouldUpdateComponent(n1, n2, optimized)) {788 if (789 instance.asyncDep &&790 !instance.asyncResolved) {791 // async & still pending - just update props and slots792 // since the component's reactive effect for render isn't set-up yet793 {794 pushWarningContext(n2);795 }796 updateComponentPreRender(instance, n2, optimized);797 {798 popWarningContext();799 }800 return;801 }802 else {803 // normal update804 instance.next = n2;805 // in case the child component is also queued, remove it to avoid806 // double updating the same child component in the same flush.807 invalidateJob(instance.update);808 // instance.update is the reactive effect runner.809 instance.update();810 }811 }812 else {813 // no update needed. just copy over properties814 n2.component = n1.component;815 n2.el = n1.el;816 instance.vnode = n2;817 }818 };819 const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => {820 // create reactive effect for rendering821 instance.update = effect(function componentEffect() {822 if (!instance.isMounted) {823 let vnodeHook;824 const { el, props } = initialVNode;825 const { bm, m, parent } = instance;826 // beforeMount hook827 if (bm) {828 invokeArrayFns(bm);829 }830 // onVnodeBeforeMount831 if ((vnodeHook = props && props.onVnodeBeforeMount)) {832 invokeVNodeHook(vnodeHook, parent, initialVNode);833 }834 // render835 {836 startMeasure(instance, `render`);837 }838 const subTree = (instance.subTree = renderComponentRoot(instance));839 {840 endMeasure(instance, `render`);841 }842 if (el && hydrateNode) {843 {844 startMeasure(instance, `hydrate`);845 }846 // vnode has adopted host node - perform hydration instead of mount.847 hydrateNode(initialVNode.el, subTree, instance, parentSuspense);848 {849 endMeasure(instance, `hydrate`);850 }851 }852 else {853 {854 startMeasure(instance, `patch`);855 }856 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);857 {858 endMeasure(instance, `patch`);859 }860 initialVNode.el = subTree.el;861 }862 // mounted hook863 if (m) {864 queuePostRenderEffect(m, parentSuspense);865 }866 // onVnodeMounted867 if ((vnodeHook = props && props.onVnodeMounted)) {868 queuePostRenderEffect(() => {869 invokeVNodeHook(vnodeHook, parent, initialVNode);870 }, parentSuspense);871 }872 // activated hook for keep-alive roots.873 // #1742 activated hook must be accessed after first render874 // since the hook may be injected by a child keep-alive875 const { a } = instance;876 if (a &&877 initialVNode.shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {878 queuePostRenderEffect(a, parentSuspense);879 }880 instance.isMounted = true;881 }882 else {883 // updateComponent884 // This is triggered by mutation of component's own state (next: null)885 // OR parent calling processComponent (next: VNode)886 let { next, bu, u, parent, vnode } = instance;887 let originNext = next;888 let vnodeHook;889 {890 pushWarningContext(next || instance.vnode);891 }892 if (next) {893 updateComponentPreRender(instance, next, optimized);894 }895 else {896 next = vnode;897 }898 next.el = vnode.el;899 // beforeUpdate hook900 if (bu) {901 invokeArrayFns(bu);902 }903 // onVnodeBeforeUpdate904 if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {905 invokeVNodeHook(vnodeHook, parent, next, vnode);906 }907 // render908 {909 startMeasure(instance, `render`);910 }911 const nextTree = renderComponentRoot(instance);912 {913 endMeasure(instance, `render`);914 }915 const prevTree = instance.subTree;916 instance.subTree = nextTree;917 // reset refs918 // only needed if previous patch had refs919 if (instance.refs !== EMPTY_OBJ) {920 instance.refs = {};921 }922 {923 startMeasure(instance, `patch`);924 }925 patch(prevTree, nextTree, 926 // parent may have changed if it's in a teleport927 hostParentNode(prevTree.el), 928 // anchor may have changed if it's in a fragment929 getNextHostNode(prevTree), instance, parentSuspense, isSVG);930 {931 endMeasure(instance, `patch`);932 }933 next.el = nextTree.el;934 if (originNext === null) {935 // self-triggered update. In case of HOC, update parent component936 // vnode el. HOC is indicated by parent instance's subTree pointing937 // to child component's vnode938 updateHOCHostEl(instance, nextTree.el);939 }940 // updated hook941 if (u) {942 queuePostRenderEffect(u, parentSuspense);943 }944 // onVnodeUpdated945 if ((vnodeHook = next.props && next.props.onVnodeUpdated)) {946 queuePostRenderEffect(() => {947 invokeVNodeHook(vnodeHook, parent, next, vnode);948 }, parentSuspense);949 }950 {951 devtoolsComponentUpdated(instance);952 }953 {954 popWarningContext();955 }956 }957 }, createDevEffectOptions(instance) );958 };959 const updateComponentPreRender = (instance, nextVNode, optimized) => {960 nextVNode.component = instance;961 const prevProps = instance.vnode.props;962 instance.vnode = nextVNode;963 instance.next = null;964 updateProps(instance, nextVNode.props, prevProps, optimized);965 updateSlots(instance, nextVNode.children);966 // props update may have triggered pre-flush watchers.967 // flush them before the render update.968 flushPreFlushCbs(undefined, instance.update);969 };970 const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized = false) => {971 const c1 = n1 && n1.children;972 const prevShapeFlag = n1 ? n1.shapeFlag : 0;973 const c2 = n2.children;974 const { patchFlag, shapeFlag } = n2;975 // fast path976 if (patchFlag > 0) {977 if (patchFlag & 128 /* KEYED_FRAGMENT */) {978 // this could be either fully-keyed or mixed (some keyed some not)979 // presence of patchFlag means children are guaranteed to be arrays980 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);981 return;982 }983 else if (patchFlag & 256 /* UNKEYED_FRAGMENT */) {984 // unkeyed985 patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);986 return;987 }988 }989 // children has 3 possibilities: text, array or no children.990 if (shapeFlag & 8 /* TEXT_CHILDREN */) {991 // text children fast path992 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {993 unmountChildren(c1, parentComponent, parentSuspense);994 }995 if (c2 !== c1) {996 hostSetElementText(container, c2);997 }998 }999 else {1000 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {1001 // prev children was array1002 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1003 // two arrays, cannot assume anything, do full diff1004 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1005 }1006 else {1007 // no new children, just unmount old1008 unmountChildren(c1, parentComponent, parentSuspense, true);1009 }1010 }1011 else {1012 // prev children was text OR null1013 // new children is array OR null1014 if (prevShapeFlag & 8 /* TEXT_CHILDREN */) {1015 hostSetElementText(container, '');1016 }1017 // mount new if array1018 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1019 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1020 }1021 }1022 }1023 };1024 const patchUnkeyedChildren = (c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {1025 c1 = c1 || EMPTY_ARR;1026 c2 = c2 || EMPTY_ARR;1027 const oldLength = c1.length;1028 const newLength = c2.length;1029 const commonLength = Math.min(oldLength, newLength);1030 let i;1031 for (i = 0; i < commonLength; i++) {1032 const nextChild = (c2[i] = optimized1033 ? cloneIfMounted(c2[i])1034 : normalizeVNode(c2[i]));1035 patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, optimized);1036 }1037 if (oldLength > newLength) {1038 // remove old1039 unmountChildren(c1, parentComponent, parentSuspense, true, commonLength);1040 }1041 else {1042 // mount new1043 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, commonLength);1044 }1045 };1046 // can be all-keyed or mixed1047 const patchKeyedChildren = (c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, optimized) => {1048 let i = 0;1049 const l2 = c2.length;1050 let e1 = c1.length - 1; // prev ending index1051 let e2 = l2 - 1; // next ending index1052 // 1. sync from start1053 // (a b) c1054 // (a b) d e1055 while (i <= e1 && i <= e2) {1056 const n1 = c1[i];1057 const n2 = (c2[i] = optimized1058 ? cloneIfMounted(c2[i])1059 : normalizeVNode(c2[i]));1060 if (isSameVNodeType(n1, n2)) {1061 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, optimized);1062 }1063 else {1064 break;1065 }1066 i++;1067 }1068 // 2. sync from end1069 // a (b c)1070 // d e (b c)1071 while (i <= e1 && i <= e2) {1072 const n1 = c1[e1];1073 const n2 = (c2[e2] = optimized1074 ? cloneIfMounted(c2[e2])1075 : normalizeVNode(c2[e2]));1076 if (isSameVNodeType(n1, n2)) {1077 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, optimized);1078 }1079 else {1080 break;1081 }1082 e1--;1083 e2--;1084 }1085 // 3. common sequence + mount1086 // (a b)1087 // (a b) c1088 // i = 2, e1 = 1, e2 = 21089 // (a b)1090 // c (a b)1091 // i = 0, e1 = -1, e2 = 01092 if (i > e1) {1093 if (i <= e2) {1094 const nextPos = e2 + 1;1095 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;1096 while (i <= e2) {1097 patch(null, (c2[i] = optimized1098 ? cloneIfMounted(c2[i])1099 : normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG);1100 i++;1101 }1102 }1103 }1104 // 4. common sequence + unmount1105 // (a b) c1106 // (a b)1107 // i = 2, e1 = 2, e2 = 11108 // a (b c)1109 // (b c)1110 // i = 0, e1 = 0, e2 = -11111 else if (i > e2) {1112 while (i <= e1) {1113 unmount(c1[i], parentComponent, parentSuspense, true);1114 i++;1115 }1116 }1117 // 5. unknown sequence1118 // [i ... e1 + 1]: a b [c d e] f g1119 // [i ... e2 + 1]: a b [e d c h] f g1120 // i = 2, e1 = 4, e2 = 51121 else {1122 const s1 = i; // prev starting index1123 const s2 = i; // next starting index1124 // 5.1 build key:index map for newChildren1125 const keyToNewIndexMap = new Map();1126 for (i = s2; i <= e2; i++) {1127 const nextChild = (c2[i] = optimized1128 ? cloneIfMounted(c2[i])1129 : normalizeVNode(c2[i]));1130 if (nextChild.key != null) {1131 if ( keyToNewIndexMap.has(nextChild.key)) {1132 warn(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`);1133 }1134 keyToNewIndexMap.set(nextChild.key, i);1135 }1136 }1137 // 5.2 loop through old children left to be patched and try to patch1138 // matching nodes & remove nodes that are no longer present1139 let j;1140 let patched = 0;1141 const toBePatched = e2 - s2 + 1;1142 let moved = false;1143 // used to track whether any node has moved1144 let maxNewIndexSoFar = 0;1145 // works as Map<newIndex, oldIndex>1146 // Note that oldIndex is offset by +11147 // and oldIndex = 0 is a special value indicating the new node has1148 // no corresponding old node.1149 // used for determining longest stable subsequence1150 const newIndexToOldIndexMap = new Array(toBePatched);1151 for (i = 0; i < toBePatched; i++)1152 newIndexToOldIndexMap[i] = 0;1153 for (i = s1; i <= e1; i++) {1154 const prevChild = c1[i];1155 if (patched >= toBePatched) {1156 // all new children have been patched so this can only be a removal1157 unmount(prevChild, parentComponent, parentSuspense, true);1158 continue;1159 }1160 let newIndex;1161 if (prevChild.key != null) {1162 newIndex = keyToNewIndexMap.get(prevChild.key);1163 }1164 else {1165 // key-less node, try to locate a key-less node of the same type1166 for (j = s2; j <= e2; j++) {1167 if (newIndexToOldIndexMap[j - s2] === 0 &&1168 isSameVNodeType(prevChild, c2[j])) {1169 newIndex = j;1170 break;1171 }1172 }1173 }1174 if (newIndex === undefined) {1175 unmount(prevChild, parentComponent, parentSuspense, true);1176 }1177 else {1178 newIndexToOldIndexMap[newIndex - s2] = i + 1;1179 if (newIndex >= maxNewIndexSoFar) {1180 maxNewIndexSoFar = newIndex;1181 }1182 else {1183 moved = true;1184 }1185 patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, optimized);1186 patched++;1187 }1188 }1189 // 5.3 move and mount1190 // generate longest stable subsequence only when nodes have moved1191 const increasingNewIndexSequence = moved1192 ? getSequence(newIndexToOldIndexMap)1193 : EMPTY_ARR;1194 j = increasingNewIndexSequence.length - 1;1195 // looping backwards so that we can use last patched node as anchor1196 for (i = toBePatched - 1; i >= 0; i--) {1197 const nextIndex = s2 + i;1198 const nextChild = c2[nextIndex];1199 const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor;1200 if (newIndexToOldIndexMap[i] === 0) {1201 // mount new1202 patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG);1203 }1204 else if (moved) {1205 // move if:1206 // There is no stable subsequence (e.g. a reverse)1207 // OR current node is not among the stable sequence1208 if (j < 0 || i !== increasingNewIndexSequence[j]) {1209 move(nextChild, container, anchor, 2 /* REORDER */);1210 }1211 else {1212 j--;1213 }1214 }1215 }1216 }1217 };1218 const move = (vnode, container, anchor, moveType, parentSuspense = null) => {1219 const { el, type, transition, children, shapeFlag } = vnode;1220 if (shapeFlag & 6 /* COMPONENT */) {1221 move(vnode.component.subTree, container, anchor, moveType);1222 return;1223 }1224 if ( shapeFlag & 128 /* SUSPENSE */) {1225 vnode.suspense.move(container, anchor, moveType);1226 return;1227 }1228 if (shapeFlag & 64 /* TELEPORT */) {1229 type.move(vnode, container, anchor, internals);1230 return;1231 }1232 if (type === Fragment) {1233 hostInsert(el, container, anchor);1234 for (let i = 0; i < children.length; i++) {1235 move(children[i], container, anchor, moveType);1236 }1237 hostInsert(vnode.anchor, container, anchor);1238 return;1239 }1240 // static node move can only happen when force updating HMR1241 if ( type === Static) {1242 moveStaticNode(vnode, container, anchor);1243 return;1244 }1245 // single nodes1246 const needTransition = moveType !== 2 /* REORDER */ &&1247 shapeFlag & 1 /* ELEMENT */ &&1248 transition;1249 if (needTransition) {1250 if (moveType === 0 /* ENTER */) {1251 transition.beforeEnter(el);1252 hostInsert(el, container, anchor);1253 queuePostRenderEffect(() => transition.enter(el), parentSuspense);1254 }1255 else {1256 const { leave, delayLeave, afterLeave } = transition;1257 const remove = () => hostInsert(el, container, anchor);1258 const performLeave = () => {1259 leave(el, () => {1260 remove();1261 afterLeave && afterLeave();1262 });1263 };1264 if (delayLeave) {1265 delayLeave(el, remove, performLeave);1266 }1267 else {1268 performLeave();1269 }1270 }1271 }1272 else {1273 hostInsert(el, container, anchor);1274 }1275 };1276 const unmount = (vnode, parentComponent, parentSuspense, doRemove = false) => {1277 const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode;1278 // unset ref1279 if (ref != null && parentComponent) {1280 setRef(ref, null, parentComponent, parentSuspense, null);1281 }1282 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {1283 parentComponent.ctx.deactivate(vnode);1284 return;1285 }1286 const shouldInvokeDirs = shapeFlag & 1 /* ELEMENT */ && dirs;1287 let vnodeHook;1288 if ((vnodeHook = props && props.onVnodeBeforeUnmount)) {1289 invokeVNodeHook(vnodeHook, parentComponent, vnode);1290 }1291 if (shapeFlag & 6 /* COMPONENT */) {1292 unmountComponent(vnode.component, parentSuspense, doRemove);1293 }1294 else {1295 if ( shapeFlag & 128 /* SUSPENSE */) {1296 vnode.suspense.unmount(parentSuspense, doRemove);1297 return;1298 }1299 if (shouldInvokeDirs) {1300 invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount');1301 }1302 if (dynamicChildren &&1303 // #1153: fast path should not be taken for non-stable (v-for) fragments1304 (type !== Fragment ||1305 (patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) {1306 // fast path for block nodes: only need to unmount dynamic children.1307 unmountChildren(dynamicChildren, parentComponent, parentSuspense);1308 }1309 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1310 unmountChildren(children, parentComponent, parentSuspense);1311 }1312 // an unmounted teleport should always remove its children1313 if (shapeFlag & 64 /* TELEPORT */) {1314 vnode.type.remove(vnode, internals);1315 }1316 if (doRemove) {1317 remove(vnode);1318 }1319 }1320 if ((vnodeHook = props && props.onVnodeUnmounted) || shouldInvokeDirs) {1321 queuePostRenderEffect(() => {1322 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);1323 shouldInvokeDirs &&1324 invokeDirectiveHook(vnode, null, parentComponent, 'unmounted');1325 }, parentSuspense);1326 }1327 };1328 const remove = vnode => {1329 const { type, el, anchor, transition } = vnode;1330 if (type === Fragment) {1331 removeFragment(el, anchor);1332 return;1333 }1334 if ( type === Static) {1335 removeStaticNode(vnode);1336 return;1337 }1338 const performRemove = () => {1339 hostRemove(el);1340 if (transition && !transition.persisted && transition.afterLeave) {1341 transition.afterLeave();1342 }1343 };1344 if (vnode.shapeFlag & 1 /* ELEMENT */ &&1345 transition &&1346 !transition.persisted) {1347 const { leave, delayLeave } = transition;1348 const performLeave = () => leave(el, performRemove);1349 if (delayLeave) {1350 delayLeave(vnode.el, performRemove, performLeave);1351 }1352 else {1353 performLeave();1354 }1355 }1356 else {1357 performRemove();1358 }1359 };1360 const removeFragment = (cur, end) => {1361 // For fragments, directly remove all contained DOM nodes.1362 // (fragment child nodes cannot have transition)1363 let next;1364 while (cur !== end) {1365 next = hostNextSibling(cur);1366 hostRemove(cur);1367 cur = next;1368 }1369 hostRemove(end);1370 };1371 const unmountComponent = (instance, parentSuspense, doRemove) => {1372 if ( instance.type.__hmrId) {1373 unregisterHMR(instance);1374 }1375 const { bum, effects, update, subTree, um } = instance;1376 // beforeUnmount hook1377 if (bum) {1378 invokeArrayFns(bum);1379 }1380 if (effects) {1381 for (let i = 0; i < effects.length; i++) {1382 stop(effects[i]);1383 }1384 }1385 // update may be null if a component is unmounted before its async1386 // setup has resolved.1387 if (update) {1388 stop(update);1389 unmount(subTree, instance, parentSuspense, doRemove);1390 }1391 // unmounted hook1392 if (um) {1393 queuePostRenderEffect(um, parentSuspense);1394 }1395 queuePostRenderEffect(() => {1396 instance.isUnmounted = true;1397 }, parentSuspense);1398 // A component with async dep inside a pending suspense is unmounted before1399 // its async dep resolves. This should remove the dep from the suspense, and1400 // cause the suspense to resolve immediately if that was the last dep.1401 if (1402 parentSuspense &&1403 parentSuspense.pendingBranch &&1404 !parentSuspense.isUnmounted &&1405 instance.asyncDep &&1406 !instance.asyncResolved &&1407 instance.suspenseId === parentSuspense.pendingId) {1408 parentSuspense.deps--;1409 if (parentSuspense.deps === 0) {1410 parentSuspense.resolve();1411 }1412 }1413 {1414 devtoolsComponentRemoved(instance);1415 }1416 };1417 const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, start = 0) => {1418 for (let i = start; i < children.length; i++) {1419 unmount(children[i], parentComponent, parentSuspense, doRemove);1420 }1421 };1422 const getNextHostNode = vnode => {1423 if (vnode.shapeFlag & 6 /* COMPONENT */) {1424 return getNextHostNode(vnode.component.subTree);1425 }1426 if ( vnode.shapeFlag & 128 /* SUSPENSE */) {1427 return vnode.suspense.next();1428 }1429 return hostNextSibling((vnode.anchor || vnode.el));1430 };1431 /**1432 * #11561433 * When a component is HMR-enabled, we need to make sure that all static nodes1434 * inside a block also inherit the DOM element from the previous tree so that1435 * HMR updates (which are full updates) can retrieve the element for patching.1436 *1437 * #20801438 * Inside keyed `template` fragment static children, if a fragment is moved,1439 * the children will always moved so that need inherit el form previous nodes1440 * to ensure correct moved position.1441 */1442 const traverseStaticChildren = (n1, n2, shallow = false) => {1443 const ch1 = n1.children;1444 const ch2 = n2.children;1445 if (isArray(ch1) && isArray(ch2)) {1446 for (let i = 0; i < ch1.length; i++) {1447 // this is only called in the optimized path so array children are1448 // guaranteed to be vnodes1449 const c1 = ch1[i];1450 const c2 = (ch2[i] = cloneIfMounted(ch2[i]));1451 if (c2.shapeFlag & 1 /* ELEMENT */ && !c2.dynamicChildren) {1452 if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* HYDRATE_EVENTS */) {1453 c2.el = c1.el;1454 }1455 if (!shallow)1456 traverseStaticChildren(c1, c2);1457 }1458 if ( c2.type === Comment) {1459 c2.el = c1.el;1460 }1461 }1462 }1463 };1464 const render = (vnode, container) => {1465 if (vnode == null) {1466 if (container._vnode) {1467 unmount(container._vnode, null, null, true);1468 }1469 }1470 else {1471 patch(container._vnode || null, vnode, container);1472 }1473 flushPostFlushCbs();1474 container._vnode = vnode;1475 };1476 const internals = {1477 p: patch,1478 um: unmount,1479 m: move,1480 r: remove,1481 mt: mountComponent,1482 mc: mountChildren,1483 pc: patchChildren,1484 pbc: patchBlockChildren,1485 n: getNextHostNode,1486 o: options1487 };1488 let hydrate;1489 let hydrateNode;1490 if (createHydrationFns) {1491 [hydrate, hydrateNode] = createHydrationFns(internals);1492 }1493 return {1494 render,1495 hydrate,1496 createApp: createAppAPI(render, hydrate)1497 };1498}1499// render.render 62451500const render = (vnode, container) => {1501 if (vnode == null) {1502 if (container._vnode) {1503 unmount(container._vnode, null, null, true);1504 }1505 }1506 else {1507 patch(container._vnode || null, vnode, container);1508 }1509 flushPostFlushCbs();1510 container._vnode = vnode;1511};1512/**1513 * render 62451514 * 1. unmount(container._vnode, null, null, true);1515 * 2. patch(container._vnode || null, vnode, container);1516 * 3. flushPostFlushCbs();1517 */1518 // patch 51101519 const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, optimized = false) => {1520 // patching & not same type, unmount old tree1521 if (n1 && !isSameVNodeType(n1, n2)) {1522 anchor = getNextHostNode(n1);1523 unmount(n1, parentComponent, parentSuspense, true);1524 n1 = null;1525 }1526 if (n2.patchFlag === -2 /* BAIL */) {1527 optimized = false;1528 n2.dynamicChildren = null;1529 }1530 const { type, ref, shapeFlag } = n2;1531 switch (type) {1532 case Text:1533 processText(n1, n2, container, anchor);1534 break;1535 case Comment:1536 processCommentNode(n1, n2, container, anchor);1537 break;1538 case Static:1539 if (n1 == null) {1540 mountStaticNode(n2, container, anchor, isSVG);1541 }1542 else {1543 patchStaticNode(n1, n2, container, isSVG);1544 }1545 break;1546 case Fragment:1547 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1548 break;1549 default:1550 if (shapeFlag & 1 /* ELEMENT */) {1551 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1552 }1553 else if (shapeFlag & 6 /* COMPONENT */) {1554 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1555 }1556 else if (shapeFlag & 64 /* TELEPORT */) {1557 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals);1558 }1559 else if ( shapeFlag & 128 /* SUSPENSE */) {1560 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals);1561 }1562 else {1563 warn('Invalid VNode type:', type, `(${typeof type})`);1564 }1565 }1566 // set ref1567 if (ref != null && parentComponent) {1568 setRef(ref, n1 && n1.ref, parentComponent, parentSuspense, n2);1569 }1570};1571function isSameVNodeType(n1, n2) {1572 if (1573 n2.shapeFlag & 6 /* COMPONENT */ &&1574 hmrDirtyComponents.has(n2.type)) {1575 // HMR only: if the component has been hot-updated, force a reload.1576 return false;1577 }1578 return n1.type === n2.type && n1.key === n2.key;1579}1580const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {1581 if (n1 == null) {1582 if (n2.shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {1583 parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized);1584 }1585 else {1586 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1587 }1588 }1589 else {1590 updateComponent(n1, n2, optimized);1591 }1592};1593const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {1594 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));1595 if ( instance.type.__hmrId) {1596 registerHMR(instance);1597 }1598 {1599 pushWarningContext(initialVNode);1600 startMeasure(instance, `mount`);1601 }1602 // inject renderer internals for keepAlive1603 if (isKeepAlive(initialVNode)) {1604 instance.ctx.renderer = internals;1605 }1606 // resolve props and slots for setup context1607 {1608 startMeasure(instance, `init`);1609 }1610 setupComponent(instance);1611 {1612 endMeasure(instance, `init`);1613 }1614 // setup() is async. This component relies on async logic to be resolved1615 // before proceeding1616 if ( instance.asyncDep) {1617 parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect);1618 // Give it a placeholder if this is not hydration1619 // TODO handle self-defined fallback1620 if (!initialVNode.el) {1621 const placeholder = (instance.subTree = createVNode(Comment));1622 processCommentNode(null, placeholder, container, anchor);1623 }1624 return;1625 }1626 setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized);1627 {1628 popWarningContext();1629 endMeasure(instance, `mount`);1630 }1631};1632function createComponentInstance(vnode, parent, suspense) {1633 const type = vnode.type;1634 // inherit parent app context - or - if root, adopt from root vnode1635 const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;1636 const instance = {1637 uid: uid$2++,1638 vnode,1639 type,1640 parent,1641 appContext,1642 root: null,1643 next: null,1644 subTree: null,1645 update: null,1646 render: null,1647 proxy: null,1648 withProxy: null,1649 effects: null,1650 provides: parent ? parent.provides : Object.create(appContext.provides),1651 accessCache: null,1652 renderCache: [],1653 // local resovled assets1654 components: null,1655 directives: null,1656 // resolved props and emits options1657 propsOptions: normalizePropsOptions(type, appContext),1658 emitsOptions: normalizeEmitsOptions(type, appContext),1659 // emit1660 emit: null,1661 emitted: null,1662 // state1663 ctx: EMPTY_OBJ,1664 data: EMPTY_OBJ,1665 props: EMPTY_OBJ,1666 attrs: EMPTY_OBJ,1667 slots: EMPTY_OBJ,1668 refs: EMPTY_OBJ,1669 setupState: EMPTY_OBJ,1670 setupContext: null,1671 // suspense related1672 suspense,1673 suspenseId: suspense ? suspense.pendingId : 0,1674 asyncDep: null,1675 asyncResolved: false,1676 // lifecycle hooks1677 // not using enums here because it results in computed properties1678 isMounted: false,1679 isUnmounted: false,1680 isDeactivated: false,1681 bc: null,1682 c: null,1683 bm: null,1684 m: null,1685 bu: null,1686 u: null,1687 um: null,1688 bum: null,1689 da: null,1690 a: null,1691 rtg: null,1692 rtc: null,1693 ec: null1694 };1695 {1696 instance.ctx = createRenderContext(instance);1697 }1698 instance.root = parent ? parent.root : instance;1699 instance.emit = emit.bind(null, instance);1700 {1701 devtoolsComponentAdded(instance);1702 }1703 return instance;1704}1705// In dev mode, the proxy target exposes the same properties as seen on `this`1706// for easier console inspection. In prod mode it will be an empty object so1707// these properties definitions can be skipped.1708const publicPropertiesMap = extend(Object.create(null), {1709 $: i => i,1710 $el: i => i.vnode.el,1711 $data: i => i.data,1712 $props: i => ( shallowReadonly(i.props) ),1713 $attrs: i => ( shallowReadonly(i.attrs) ),1714 $slots: i => ( shallowReadonly(i.slots) ),1715 $refs: i => ( shallowReadonly(i.refs) ),1716 $parent: i => i.parent && i.parent.proxy,1717 $root: i => i.root && i.root.proxy,1718 $emit: i => i.emit,1719 $options: i => ( resolveMergedOptions(i) ),1720 $forceUpdate: i => () => queueJob(i.update),1721 $nextTick: () => nextTick,1722 $watch: i => ( instanceWatch.bind(i) )1723});1724function createRenderContext(instance) {1725 const target = {};1726 // expose internal instance for proxy handlers1727 Object.defineProperty(target, `_`, {1728 configurable: true,1729 enumerable: false,1730 get: () => instance1731 });1732 // expose public properties1733 Object.keys(publicPropertiesMap).forEach(key => {1734 Object.defineProperty(target, key, {1735 configurable: true,1736 enumerable: false,1737 get: () => publicPropertiesMap[key](instance),1738 // intercepted by the proxy so no need for implementation,1739 // but needed to prevent set errors1740 set: NOOP1741 });1742 });1743 // expose global properties1744 const { globalProperties } = instance.appContext.config;1745 Object.keys(globalProperties).forEach(key => {1746 Object.defineProperty(target, key, {1747 configurable: true,1748 enumerable: false,1749 get: () => globalProperties[key],1750 set: NOOP1751 });1752 });1753 return target;1754}1755function emit(instance, event, ...args) {1756 const props = instance.vnode.props || EMPTY_OBJ;1757 {1758 const { emitsOptions, propsOptions: [propsOptions] } = instance;1759 if (emitsOptions) {1760 if (!(event in emitsOptions)) {1761 if (!propsOptions || !(`on` + capitalize(event) in propsOptions)) {1762 warn(`Component emitted event "${event}" but it is neither declared in ` +1763 `the emits option nor as an "on${capitalize(event)}" prop.`);1764 }1765 }1766 else {1767 const validator = emitsOptions[event];1768 if (isFunction(validator)) {1769 const isValid = validator(...args);1770 if (!isValid) {1771 warn(`Invalid event arguments: event validation failed for event "${event}".`);1772 }1773 }1774 }1775 }1776 }1777 {1778 devtoolsComponentEmit(instance, event, args);1779 }1780 let handlerName = `on${capitalize(event)}`;1781 let handler = props[handlerName];1782 // for v-model update:xxx events, also trigger kebab-case equivalent1783 // for props passed via kebab-case1784 if (!handler && event.startsWith('update:')) {1785 handlerName = `on${capitalize(hyphenate(event))}`;1786 handler = props[handlerName];1787 }1788 if (!handler) {1789 handler = props[handlerName + `Once`];1790 if (!instance.emitted) {1791 (instance.emitted = {})[handlerName] = true;1792 }1793 else if (instance.emitted[handlerName]) {1794 return;1795 }1796 }1797 if (handler) {1798 callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);1799 }1800}1801function setupComponent(instance, isSSR = false) {1802 isInSSRComponentSetup = isSSR;1803 const { props, children, shapeFlag } = instance.vnode;1804 const isStateful = shapeFlag & 4 /* STATEFUL_COMPONENT */;1805 initProps(instance, props, isStateful, isSSR);1806 initSlots(instance, children);1807 const setupResult = isStateful1808 ? setupStatefulComponent(instance, isSSR)1809 : undefined;1810 isInSSRComponentSetup = false;1811 return setupResult;1812}1813/**1814 * 初始化props1815 * @param {*} instance 1816 * @param {*} rawProps 1817 * @param {*} isStateful 1818 * @param {*} isSSR 1819 */1820function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison1821 isSSR = false) {1822 const props = {};1823 const attrs = {};1824 def(attrs, InternalObjectKey, 1);1825 setFullProps(instance, rawProps, props, attrs);1826 // validation1827 {1828 validateProps(props, instance);1829 }1830 if (isStateful) {1831 // stateful1832 instance.props = isSSR ? props : shallowReactive(props);1833 }1834 else {1835 if (!instance.type.props) {1836 // functional w/ optional props, props === attrs1837 instance.props = attrs;1838 }1839 else {1840 // functional w/ declared props1841 instance.props = props;1842 }1843 }1844 instance.attrs = attrs;1845}1846function setFullProps(instance, rawProps, props, attrs) {1847 const [options, needCastKeys] = instance.propsOptions;1848 if (rawProps) {1849 for (const key in rawProps) {1850 const value = rawProps[key];1851 // key, ref are reserved and never passed down1852 if (isReservedProp(key)) {1853 continue;1854 }1855 // prop option names are camelized during normalization, so to support1856 // kebab -> camel conversion here we need to camelize the key.1857 let camelKey;1858 if (options && hasOwn(options, (camelKey = camelize(key)))) {1859 props[camelKey] = value;1860 }1861 else if (!isEmitListener(instance.emitsOptions, key)) {1862 // Any non-declared (either as a prop or an emitted event) props are put1863 // into a separate `attrs` object for spreading. Make sure to preserve1864 // original key casing1865 attrs[key] = value;1866 }1867 }1868 }1869 if (needCastKeys) {1870 const rawCurrentProps = toRaw(props);1871 for (let i = 0; i < needCastKeys.length; i++) {1872 const key = needCastKeys[i];1873 props[key] = resolvePropValue(options, rawCurrentProps, key, rawCurrentProps[key], instance);1874 }1875 }1876}1877function resolvePropValue(options, props, key, value, instance) {1878 const opt = options[key];1879 if (opt != null) {1880 const hasDefault = hasOwn(opt, 'default');1881 // default values1882 if (hasDefault && value === undefined) {1883 const defaultValue = opt.default;1884 if (opt.type !== Function && isFunction(defaultValue)) {1885 setCurrentInstance(instance);1886 value = defaultValue(props);1887 setCurrentInstance(null);1888 }1889 else {1890 value = defaultValue;1891 }1892 }1893 // boolean casting1894 if (opt[0 /* shouldCast */]) {1895 if (!hasOwn(props, key) && !hasDefault) {1896 value = false;1897 }1898 else if (opt[1 /* shouldCastTrue */] &&1899 (value === '' || value === hyphenate(key))) {1900 value = true;1901 }1902 }1903 }1904 return value;1905}1906function normalizePropsOptions(comp, appContext, asMixin = false) {1907 const appId = appContext.app ? appContext.app._uid : -1;1908 const cache = comp.__props || (comp.__props = {});1909 const cached = cache[appId];1910 if (cached) {1911 return cached;1912 }1913 const raw = comp.props;1914 const normalized = {};1915 const needCastKeys = [];1916 // apply mixin/extends props1917 let hasExtends = false;1918 if ( !isFunction(comp)) {1919 const extendProps = (raw) => {1920 hasExtends = true;1921 const [props, keys] = normalizePropsOptions(raw, appContext, true);1922 extend(normalized, props);1923 if (keys)1924 needCastKeys.push(...keys);1925 };1926 if (!asMixin && appContext.mixins.length) {1927 appContext.mixins.forEach(extendProps);1928 }1929 if (comp.extends) {1930 extendProps(comp.extends);1931 }1932 if (comp.mixins) {1933 comp.mixins.forEach(extendProps);1934 }1935 }1936 if (!raw && !hasExtends) {1937 return (cache[appId] = EMPTY_ARR);1938 }1939 if (isArray(raw)) {1940 for (let i = 0; i < raw.length; i++) {1941 if ( !isString(raw[i])) {1942 warn(`props must be strings when using array syntax.`, raw[i]);1943 }1944 const normalizedKey = camelize(raw[i]);1945 if (validatePropName(normalizedKey)) {1946 normalized[normalizedKey] = EMPTY_OBJ;1947 }1948 }1949 }1950 else if (raw) {1951 if ( !isObject(raw)) {1952 warn(`invalid props options`, raw);1953 }1954 for (const key in raw) {1955 const normalizedKey = camelize(key);1956 if (validatePropName(normalizedKey)) {1957 const opt = raw[key];1958 const prop = (normalized[normalizedKey] =1959 isArray(opt) || isFunction(opt) ? { type: opt } : opt);1960 if (prop) {1961 const booleanIndex = getTypeIndex(Boolean, prop.type);1962 const stringIndex = getTypeIndex(String, prop.type);1963 prop[0 /* shouldCast */] = booleanIndex > -1;1964 prop[1 /* shouldCastTrue */] =1965 stringIndex < 0 || booleanIndex < stringIndex;1966 // if the prop needs boolean casting or default value1967 if (booleanIndex > -1 || hasOwn(prop, 'default')) {1968 needCastKeys.push(normalizedKey);1969 }1970 }1971 }1972 }1973 }1974 return (cache[appId] = [normalized, needCastKeys]);1975}1976const initSlots = (instance, children) => {1977 if (instance.vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {1978 const type = children._;1979 if (type) {1980 instance.slots = children;1981 // make compiler marker non-enumerable1982 def(children, '_', type);1983 }1984 else {1985 normalizeObjectSlots(children, (instance.slots = {}));1986 }1987 }1988 else {1989 instance.slots = {};1990 if (children) {1991 normalizeVNodeSlots(instance, children);1992 }1993 }1994 def(instance.slots, InternalObjectKey, 1);1995};1996function setupStatefulComponent(instance, isSSR) {1997 const Component = instance.type;1998 {1999 if (Component.name) {2000 validateComponentName(Component.name, instance.appContext.config);2001 }2002 if (Component.components) {2003 const names = Object.keys(Component.components);2004 for (let i = 0; i < names.length; i++) {2005 validateComponentName(names[i], instance.appContext.config);2006 }2007 }2008 if (Component.directives) {2009 const names = Object.keys(Component.directives);2010 for (let i = 0; i < names.length; i++) {2011 validateDirectiveName(names[i]);2012 }2013 }2014 }2015 // 0. create render proxy property access cache2016 instance.accessCache = {};2017 // 1. create public instance / render proxy2018 // also mark it raw so it's never observed2019 instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers);2020 {2021 exposePropsOnRenderContext(instance);2022 }2023 // 2. call setup()2024 const { setup } = Component;2025 if (setup) {2026 const setupContext = (instance.setupContext =2027 setup.length > 1 ? createSetupContext(instance) : null);2028 currentInstance = instance;2029 pauseTracking();2030 const setupResult = callWithErrorHandling(setup, instance, 0 /* SETUP_FUNCTION */, [ shallowReadonly(instance.props) , setupContext]);2031 resetTracking();2032 currentInstance = null;2033 if (isPromise(setupResult)) {2034 if (isSSR) {2035 // return the promise so server-renderer can wait on it2036 return setupResult.then((resolvedResult) => {2037 handleSetupResult(instance, resolvedResult);2038 });2039 }2040 else {2041 // async setup returned Promise.2042 // bail here and wait for re-entry.2043 instance.asyncDep = setupResult;2044 }2045 }2046 else {2047 handleSetupResult(instance, setupResult);2048 }2049 }2050 else {2051 finishComponentSetup(instance);2052 }2053}2054/**2055 * 初始化slot2056 * 2057 */2058const initSlots = (instance, children) => {2059 if (instance.vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {2060 const type = children._;2061 if (type) {2062 instance.slots = children;2063 // make compiler marker non-enumerable2064 def(children, '_', type);2065 }2066 else {2067 normalizeObjectSlots(children, (instance.slots = {}));2068 }2069 }2070 else {2071 instance.slots = {};2072 if (children) {2073 normalizeVNodeSlots(instance, children);2074 }2075 }2076 def(instance.slots, InternalObjectKey, 1);2077};2078const normalizeObjectSlots = (rawSlots, slots) => {2079 const ctx = rawSlots._ctx;2080 for (const key in rawSlots) {2081 if (isInternalKey(key))2082 continue;2083 const value = rawSlots[key];2084 if (isFunction(value)) {2085 slots[key] = normalizeSlot(key, value, ctx);2086 }2087 else if (value != null) {2088 {2089 warn(`Non-function value encountered for slot "${key}". ` +2090 `Prefer function slots for better performance.`);2091 }2092 const normalized = normalizeSlotValue(value);2093 slots[key] = () => normalized;2094 }2095 }2096};2097const normalizeVNodeSlots = (instance, children) => {2098 if ( !isKeepAlive(instance.vnode)) {2099 warn(`Non-function value encountered for default slot. ` +2100 `Prefer function slots for better performance.`);2101 }2102 const normalized = normalizeSlotValue(children);2103 instance.slots.default = () => normalized;2104};2105const normalizeSlotValue = (value) => isArray(value)2106 ? value.map(normalizeVNode)2107 : [normalizeVNode(value)];2108const normalizeSlot = (key, rawSlot, ctx) => withCtx((props) => {2109 if ( currentInstance) {2110 warn(`Slot "${key}" invoked outside of the render function: ` +2111 `this will not track dependencies used in the slot. ` +2112 `Invoke the slot function inside the render function instead.`);2113 }2114 return normalizeSlotValue(rawSlot(props));2115}, ctx);2116function normalizeVNode(child) {2117 if (child == null || typeof child === 'boolean') {2118 // empty placeholder2119 return createVNode(Comment);2120 }2121 else if (isArray(child)) {2122 // fragment2123 return createVNode(Fragment, null, child);2124 }2125 else if (typeof child === 'object') {2126 // already vnode, this should be the most common since compiled templates2127 // always produce all-vnode children arrays2128 return child.el === null ? child : cloneVNode(child);2129 }2130 else {2131 // strings and numbers2132 return createVNode(Text, null, String(child));2133 }2134}2135/**2136 * setupStatefulComponent2137 */2138function setupStatefulComponent(instance, isSSR) {2139 const Component = instance.type;2140 {2141 if (Component.name) {2142 validateComponentName(Component.name, instance.appContext.config);2143 }2144 if (Component.components) {2145 const names = Object.keys(Component.components);2146 for (let i = 0; i < names.length; i++) {2147 validateComponentName(names[i], instance.appContext.config);2148 }2149 }2150 if (Component.directives) {2151 const names = Object.keys(Component.directives);2152 for (let i = 0; i < names.length; i++) {2153 validateDirectiveName(names[i]);2154 }2155 }2156 }2157 // 0. create render proxy property access cache2158 instance.accessCache = {};2159 // 1. create public instance / render proxy2160 // also mark it raw so it's never observed2161 instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers);2162 {2163 exposePropsOnRenderContext(instance);2164 }2165 // 2. call setup()2166 const { setup } = Component;2167 if (setup) {...

Full Screen

Full Screen

setup.js

Source:setup.js Github

copy

Full Screen

...150 }151 if (Component.directives) {152 const names = Object.keys(Component.directives);153 for (let i = 0; i < names.length; i++) {154 validateDirectiveName(names[i]);155 }156 }157 }158 // 0. create render proxy property access cache159 instance.accessCache = {};160 // 1. create public instance / render proxy161 // also mark it raw so it's never observed162 instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers);163 {164 exposePropsOnRenderContext(instance);165 }166 // 2. call setup()167 const { setup } = Component;168 if (setup) {...

Full Screen

Full Screen

directives.js

Source:directives.js Github

copy

Full Screen

...4 _component: rootComponent,5 _props: rootProps,6 directive(name, directive) {7 if ((process.env.NODE_ENV !== 'production')) {8 validateDirectiveName(name)9 }10 if (!directive) {11 // 没有第二个参数,则获取对应的指令对象12 return context.directives[name]13 }14 if ((process.env.NODE_ENV !== 'production') && context.directives[name]) {15 // 重复注册的警告16 warn(`Directive "${name}" has already been registered in target app.`)17 }18 context.directives[name] = directive19 return app20 }21 }22 return app...

Full Screen

Full Screen

loadDirectives.js

Source:loadDirectives.js Github

copy

Full Screen

...15 state.typeDefs.push(loadGraphqlFile(path.join(root, 'type.graphql')));16};17const insertIntoSchema = (state, root, dirent) => {18 if (dirent.name === 'type.graphql') return;19 if (dirent.isFile() && validateDirectiveName(dirent.name))20 return (state.directives[basename(dirent.name)] = path.join(21 root,22 dirent.name,23 ));24};25const validateDirectiveName = (name) =>26 isCamelCase(basename(name)) && path.extname(name) === '.js';...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const { validateDirectiveName } = require('@playwright/test/lib/server/frames');2validateDirectiveName('script-src');3validateDirectiveName('style-src');4validateDirectiveName('worker-src');5validateDirectiveName('default-src');6validateDirectiveName('img-src');7validateDirectiveName('font-src');8validateDirectiveName('connect-src');9validateDirectiveName('frame-src');10validateDirectiveName('manifest-src');11validateDirectiveName('media-src');12validateDirectiveName('object-src');13validateDirectiveName('prefetch-src');14validateDirectiveName('report-uri');15validateDirectiveName('sandbox');16validateDirectiveName('upgrade-insecure-requests');17validateDirectiveName('base-uri');18validateDirectiveName('form-action');19validateDirectiveName('frame-ancestors');20validateDirectiveName('navigate-to');21validateDirectiveName('plugin-types');22validateDirectiveName('require-sri-for');23validateDirectiveName('trusted-types');24validateDirectiveName('worker-src');25validateDirectiveName('block-all-mixed-content');26validateDirectiveName('referrer');27validateDirectiveName('report-to');28validateDirectiveName('require-trusted-types-for');29validateDirectiveName('disown-opener');30validateDirectiveName('child-src');31validateDirectiveName('worker-src');32const { validateHeaderName } = require('@playwright/test/lib/server/network');33validateHeaderName('accept');34validateHeaderName('accept-charset');35validateHeaderName('accept-encoding');36validateHeaderName('accept-language');37validateHeaderName('accept-datetime');38validateHeaderName('authorization');39validateHeaderName('cache-control');40validateHeaderName('connection');41validateHeaderName('cookie');42validateHeaderName('content-length');43validateHeaderName('content-md5');44validateHeaderName('content-type');45validateHeaderName('date');46validateHeaderName('expect');47validateHeaderName('forwarded');48validateHeaderName('from');49validateHeaderName('host');50validateHeaderName('if-match');51validateHeaderName('if-modified-since');52validateHeaderName('if-none-match');53validateHeaderName('if-range');54validateHeaderName('if-unmodified-since');55validateHeaderName('max-forwards');56validateHeaderName('origin');57validateHeaderName('pragma');58validateHeaderName('proxy-authorization');59validateHeaderName('range');60validateHeaderName('referer');61validateHeaderName('te');62validateHeaderName('user-agent');63validateHeaderName('upgrade');

Full Screen

Using AI Code Generation

copy

Full Screen

1const { validateDirectiveName } = require('playwright/lib/utils/validation');2const { expect } = require('chai');3describe('validateDirectiveName', function () {4 it('should throw error if directive name is not valid', function () {5 expect(() => validateDirectiveName('test')).to.throw();6 });7 it('should not throw error if directive name is valid', function () {8 expect(() => validateDirectiveName('playwright:browser')).to.not.throw();9 });10});11module.exports = {12 use: {13 viewport: { width: 1280, height: 720 },14 {15 },16 },17};18const { setConfig } = require('playwright/lib/utils/config');19setConfig({20 use: {21 viewport: { width: 1280, height: 720 },22 {23 },24 },25});26import { PlaywrightTestConfig } from '@playwright/test';27const config: PlaywrightTestConfig = {28 use: {29 viewport: { width: 1280, height: 720 },30 {31 },32 },33};34export default config;35import { setConfig } from '@playwright/test';36setConfig({37 use: {38 viewport: { width: 1280, height: 720 },39 {40 },41 },42});43module.exports = {44 use: {45 viewport: { width: 1280, height: 720 },46 {

Full Screen

Using AI Code Generation

copy

Full Screen

1const { validateDirectiveName } = require('@playwright/internal');2const directiveNames = ['@foo', '@bar', '@baz'];3directiveNames.forEach(name => {4 try {5 validateDirectiveName(name);6 } catch (error) {7 console.log(`Error while validating directive name ${name} : ${error}`);8 }9});

Full Screen

Using AI Code Generation

copy

Full Screen

1const { validateDirectiveName } = require('playwright/lib/utils/utils');2const directiveName = 'testDirective';3const directiveNameValidation = validateDirectiveName(directiveName);4console.log(directiveNameValidation);5const page = require('@playwright/test').page;6page.addDirective('testDirective', async function (element, value) {7 await element.fill(value);8});9module.exports = {10};11const { test } = require('@playwright/test');12const google = require('../page-objects/google');13test('test to use directive in the page object', async ({ page }) => {14 await page.testDirective(google.googleSearchBox, 'Playwright');15 await page.click(google.googleSearchButton);16});17 ✓ test to use directive in the page object (1s)18 1 passed (1s)19const { test } = require('@playwright/test');20const google = require('../page-objects/google');21test.addDirective('testDirective', async function (element, value) {22 await element.fill(value);23});24test('test to use directive in the test file', async ({ page }) => {

Full Screen

Using AI Code Generation

copy

Full Screen

1const { validateDirectiveName } = require('@playwright/test/lib/server/trace/common/traceModel');2const { validateDirectiveName } = require('@playwright/test/lib/server/trace/common/traceModel');3const { validateDirectiveName } = require('@playwright/test/lib/server/trace/common/traceModel');4const { validateDirectiveName } = require('@playwright/test/lib/server/trace/common/traceModel');5const { validateDirectiveName } = require('@playwright/test/lib/server/trace/common/traceModel');6const { validateDirectiveName } = require('@playwright/test/lib/server/trace/common/traceModel');7const { validateDirectiveName } = require('@playwright/test/lib/server/trace/common/traceModel');8const { validateDirectiveName } = require('@playwright/test/lib/server/trace/common/traceModel');9const { validateDirectiveName } = require('@playwright/test/lib/server/trace/common/traceModel');

Full Screen

Using AI Code Generation

copy

Full Screen

1const { validateDirectiveName } = require('playwright/lib/utils/validator');2validateDirectiveName('test');3 at validateDirectiveName (C:\Users\user\Documents\playwright\playwright\lib\utils\validator.js:12:11)4 at Object.<anonymous> (C:\Users\user\Documents\playwright\playwright\test.js:4:1)5 at Module._compile (internal/modules/cjs/loader.js:1137:30)6 at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)7 at Module.load (internal/modules/cjs/loader.js:985:32)8 at Function.Module._load (internal/modules/cjs/loader.js:878:14)9 at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)

Full Screen

Playwright tutorial

LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.

Chapters:

  1. What is Playwright : Playwright is comparatively new but has gained good popularity. Get to know some history of the Playwright with some interesting facts connected with it.
  2. How To Install Playwright : Learn in detail about what basic configuration and dependencies are required for installing Playwright and run a test. Get a step-by-step direction for installing the Playwright automation framework.
  3. Playwright Futuristic Features: Launched in 2020, Playwright gained huge popularity quickly because of some obliging features such as Playwright Test Generator and Inspector, Playwright Reporter, Playwright auto-waiting mechanism and etc. Read up on those features to master Playwright testing.
  4. What is Component Testing: Component testing in Playwright is a unique feature that allows a tester to test a single component of a web application without integrating them with other elements. Learn how to perform Component testing on the Playwright automation framework.
  5. Inputs And Buttons In Playwright: Every website has Input boxes and buttons; learn about testing inputs and buttons with different scenarios and examples.
  6. Functions and Selectors in Playwright: Learn how to launch the Chromium browser with Playwright. Also, gain a better understanding of some important functions like “BrowserContext,” which allows you to run multiple browser sessions, and “newPage” which interacts with a page.
  7. Handling Alerts and Dropdowns in Playwright : Playwright interact with different types of alerts and pop-ups, such as simple, confirmation, and prompt, and different types of dropdowns, such as single selector and multi-selector get your hands-on with handling alerts and dropdown in Playright testing.
  8. Playwright vs Puppeteer: Get to know about the difference between two testing frameworks and how they are different than one another, which browsers they support, and what features they provide.
  9. Run Playwright Tests on LambdaTest: Playwright testing with LambdaTest leverages test performance to the utmost. You can run multiple Playwright tests in Parallel with the LammbdaTest test cloud. Get a step-by-step guide to run your Playwright test on the LambdaTest platform.
  10. Playwright Python Tutorial: Playwright automation framework support all major languages such as Python, JavaScript, TypeScript, .NET and etc. However, there are various advantages to Python end-to-end testing with Playwright because of its versatile utility. Get the hang of Playwright python testing with this chapter.
  11. Playwright End To End Testing Tutorial: Get your hands on with Playwright end-to-end testing and learn to use some exciting features such as TraceViewer, Debugging, Networking, Component testing, Visual testing, and many more.
  12. Playwright Video Tutorial: Watch the video tutorials on Playwright testing from experts and get a consecutive in-depth explanation of Playwright automation testing.

Run Playwright Internal automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful