How to use createDevEffectOptions method in Playwright Internal

Best JavaScript code snippet using playwright-internal

runtime-test.global.js

Source:runtime-test.global.js Github

copy

Full Screen

...1860 fallback: normalizeVNode(null)1861 };1862 }1863 }1864 function createDevEffectOptions(instance) {1865 return {1866 scheduler: queueJob,1867 onTrack: instance.rtc ? e => invokeHooks(instance.rtc, e) : void 0,1868 onTrigger: instance.rtg ? e => invokeHooks(instance.rtg, e) : void 01869 };1870 }1871 function isSameType$1(n1, n2) {1872 return n1.type === n2.type && n1.key === n2.key;1873 }1874 function invokeHooks(hooks, arg) {1875 for (let i = 0; i < hooks.length; i++) {1876 hooks[i](arg);1877 }1878 }1879 function queuePostRenderEffect(fn, suspense) {1880 if (suspense !== null && !suspense.isResolved) {1881 if (isArray(fn)) {1882 suspense.effects.push(...fn);1883 }1884 else {1885 suspense.effects.push(fn);1886 }1887 }1888 else {1889 queuePostFlushCb(fn);1890 }1891 }1892 /**1893 * The createRenderer function accepts two generic arguments:1894 * HostNode and HostElement, corresponding to Node and Element types in the1895 * host environment. For example, for runtime-dom, HostNode would be the DOM1896 * `Node` interface and HostElement would be the DOM `Element` interface.1897 *1898 * Custom renderers can pass in the platform specific types like this:1899 *1900 * ``` js1901 * const { render, createApp } = createRenderer<Node, Element>({1902 * patchProp,1903 * ...nodeOps1904 * })1905 * ```1906 */1907 function createRenderer(options) {1908 const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, querySelector: hostQuerySelector } = options;1909 function patch(n1, // null means this is a mount1910 n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, optimized = false) {1911 // patching & not same type, unmount old tree1912 if (n1 != null && !isSameType$1(n1, n2)) {1913 anchor = getNextHostNode(n1);1914 unmount(n1, parentComponent, parentSuspense, true);1915 n1 = null;1916 }1917 const { type, shapeFlag } = n2;1918 switch (type) {1919 case Text:1920 processText(n1, n2, container, anchor);1921 break;1922 case Comment:1923 processCommentNode(n1, n2, container, anchor);1924 break;1925 case Fragment:1926 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1927 break;1928 case Portal:1929 processPortal(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1930 break;1931 case Suspense:1932 {1933 processSuspense(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1934 }1935 break;1936 default:1937 if (shapeFlag & 1 /* ELEMENT */) {1938 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1939 }1940 else if (shapeFlag & 6 /* COMPONENT */) {1941 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1942 }1943 else {1944 warn('Invalid HostVNode type:', n2.type, `(${typeof n2.type})`);1945 }1946 }1947 }1948 function processText(n1, n2, container, anchor) {1949 if (n1 == null) {1950 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);1951 }1952 else {1953 const el = (n2.el = n1.el);1954 if (n2.children !== n1.children) {1955 hostSetText(el, n2.children);1956 }1957 }1958 }1959 function processCommentNode(n1, n2, container, anchor) {1960 if (n1 == null) {1961 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);1962 }1963 else {1964 // there's no support for dynamic comments1965 n2.el = n1.el;1966 }1967 }1968 function processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1969 if (n1 == null) {1970 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG);1971 }1972 else {1973 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized);1974 }1975 if (n2.ref !== null && parentComponent !== null) {1976 setRef(n2.ref, n1 && n1.ref, parentComponent, n2.el);1977 }1978 }1979 function mountElement(vnode, container, anchor, parentComponent, parentSuspense, isSVG) {1980 const tag = vnode.type;1981 isSVG = isSVG || tag === 'svg';1982 const el = (vnode.el = hostCreateElement(tag, isSVG));1983 const { props, shapeFlag } = vnode;1984 if (props != null) {1985 for (const key in props) {1986 if (isReservedProp(key))1987 continue;1988 hostPatchProp(el, key, props[key], null, isSVG);1989 }1990 if (props.vnodeBeforeMount != null) {1991 invokeDirectiveHook(props.vnodeBeforeMount, parentComponent, vnode);1992 }1993 }1994 if (shapeFlag & 8 /* TEXT_CHILDREN */) {1995 hostSetElementText(el, vnode.children);1996 }1997 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1998 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG);1999 }2000 hostInsert(el, container, anchor);2001 if (props != null && props.vnodeMounted != null) {2002 queuePostRenderEffect(() => {2003 invokeDirectiveHook(props.vnodeMounted, parentComponent, vnode);2004 }, parentSuspense);2005 }2006 }2007 function mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, start = 0) {2008 for (let i = start; i < children.length; i++) {2009 const child = (children[i] = normalizeVNode(children[i]));2010 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG);2011 }2012 }2013 function patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized) {2014 const el = (n2.el = n1.el);2015 const { patchFlag, dynamicChildren } = n2;2016 const oldProps = (n1 && n1.props) || EMPTY_OBJ;2017 const newProps = n2.props || EMPTY_OBJ;2018 if (newProps.vnodeBeforeUpdate != null) {2019 invokeDirectiveHook(newProps.vnodeBeforeUpdate, parentComponent, n2, n1);2020 }2021 if (patchFlag > 0) {2022 // the presence of a patchFlag means this element's render code was2023 // generated by the compiler and can take the fast path.2024 // in this path old node and new node are guaranteed to have the same shape2025 // (i.e. at the exact same position in the source template)2026 if (patchFlag & 16 /* FULL_PROPS */) {2027 // element props contain dynamic keys, full diff needed2028 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);2029 }2030 else {2031 // class2032 // this flag is matched when the element has dynamic class bindings.2033 if (patchFlag & 2 /* CLASS */) {2034 if (oldProps.class !== newProps.class) {2035 hostPatchProp(el, 'class', newProps.class, null, isSVG);2036 }2037 }2038 // style2039 // this flag is matched when the element has dynamic style bindings2040 if (patchFlag & 4 /* STYLE */) {2041 hostPatchProp(el, 'style', newProps.style, oldProps.style, isSVG);2042 }2043 // props2044 // This flag is matched when the element has dynamic prop/attr bindings2045 // other than class and style. The keys of dynamic prop/attrs are saved for2046 // faster iteration.2047 // Note dynamic keys like :[foo]="bar" will cause this optimization to2048 // bail out and go through a full diff because we need to unset the old key2049 if (patchFlag & 8 /* PROPS */) {2050 // if the flag is present then dynamicProps must be non-null2051 const propsToUpdate = n2.dynamicProps;2052 for (let i = 0; i < propsToUpdate.length; i++) {2053 const key = propsToUpdate[i];2054 const prev = oldProps[key];2055 const next = newProps[key];2056 if (prev !== next) {2057 hostPatchProp(el, key, next, prev, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);2058 }2059 }2060 }2061 }2062 // text2063 // This flag is matched when the element has only dynamic text children.2064 // this flag is terminal (i.e. skips children diffing).2065 if (patchFlag & 1 /* TEXT */) {2066 if (n1.children !== n2.children) {2067 hostSetElementText(el, n2.children);2068 }2069 return; // terminal2070 }2071 }2072 else if (!optimized) {2073 // unoptimized, full diff2074 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);2075 }2076 if (dynamicChildren != null) {2077 // children fast path2078 const oldDynamicChildren = n1.dynamicChildren;2079 for (let i = 0; i < dynamicChildren.length; i++) {2080 patch(oldDynamicChildren[i], dynamicChildren[i], el, null, parentComponent, parentSuspense, isSVG, true);2081 }2082 }2083 else if (!optimized) {2084 // full diff2085 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, isSVG);2086 }2087 if (newProps.vnodeUpdated != null) {2088 queuePostRenderEffect(() => {2089 invokeDirectiveHook(newProps.vnodeUpdated, parentComponent, n2, n1);2090 }, parentSuspense);2091 }2092 }2093 function patchProps(el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) {2094 if (oldProps !== newProps) {2095 for (const key in newProps) {2096 if (isReservedProp(key))2097 continue;2098 const next = newProps[key];2099 const prev = oldProps[key];2100 if (next !== prev) {2101 hostPatchProp(el, key, next, prev, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);2102 }2103 }2104 if (oldProps !== EMPTY_OBJ) {2105 for (const key in oldProps) {2106 if (isReservedProp(key))2107 continue;2108 if (!(key in newProps)) {2109 hostPatchProp(el, key, null, null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);2110 }2111 }2112 }2113 }2114 }2115 function processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {2116 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateComment(''));2117 const fragmentEndAnchor = (n2.anchor = n12118 ? n1.anchor2119 : hostCreateComment(''));2120 if (n1 == null) {2121 hostInsert(fragmentStartAnchor, container, anchor);2122 hostInsert(fragmentEndAnchor, container, anchor);2123 // a fragment can only have array children2124 // since they are either generated by the compiler, or implicitly created2125 // from arrays.2126 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG);2127 }2128 else {2129 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);2130 }2131 }2132 function processPortal(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {2133 const targetSelector = n2.props && n2.props.target;2134 const { patchFlag, shapeFlag, children } = n2;2135 if (n1 == null) {2136 const target = (n2.target = isString(targetSelector)2137 ? hostQuerySelector(targetSelector)2138 : null);2139 if (target != null) {2140 if (shapeFlag & 8 /* TEXT_CHILDREN */) {2141 hostSetElementText(target, children);2142 }2143 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {2144 mountChildren(children, target, null, parentComponent, parentSuspense, isSVG);2145 }2146 }2147 else {2148 warn('Invalid Portal target on mount:', target, `(${typeof target})`);2149 }2150 }2151 else {2152 // update content2153 const target = (n2.target = n1.target);2154 if (patchFlag === 1 /* TEXT */) {2155 hostSetElementText(target, children);2156 }2157 else if (!optimized) {2158 patchChildren(n1, n2, target, null, parentComponent, parentSuspense, isSVG);2159 }2160 // target changed2161 if (targetSelector !== (n1.props && n1.props.target)) {2162 const nextTarget = (n2.target = isString(targetSelector)2163 ? hostQuerySelector(targetSelector)2164 : null);2165 if (nextTarget != null) {2166 // move content2167 if (shapeFlag & 8 /* TEXT_CHILDREN */) {2168 hostSetElementText(target, '');2169 hostSetElementText(nextTarget, children);2170 }2171 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {2172 for (let i = 0; i < children.length; i++) {2173 move(children[i], nextTarget, null);2174 }2175 }2176 }2177 else {2178 warn('Invalid Portal target on update:', target, `(${typeof target})`);2179 }2180 }2181 }2182 // insert an empty node as the placeholder for the portal2183 processCommentNode(n1, n2, container, anchor);2184 }2185 function processSuspense(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {2186 if (n1 == null) {2187 mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);2188 }2189 else {2190 patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized);2191 }2192 }2193 function mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {2194 const hiddenContainer = hostCreateElement('div');2195 const suspense = (n2.suspense = createSuspenseBoundary(n2, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, optimized));2196 const { content, fallback } = normalizeSuspenseChildren(n2);2197 suspense.subTree = content;2198 suspense.fallbackTree = fallback;2199 // start mounting the content subtree in an off-dom container2200 patch(null, content, hiddenContainer, null, parentComponent, suspense, isSVG, optimized);2201 // now check if we have encountered any async deps2202 if (suspense.deps > 0) {2203 // mount the fallback tree2204 patch(null, fallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context2205 isSVG, optimized);2206 n2.el = fallback.el;2207 }2208 else {2209 // Suspense has no async deps. Just resolve.2210 resolveSuspense(suspense);2211 }2212 }2213 function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized) {2214 const suspense = (n2.suspense = n1.suspense);2215 suspense.vnode = n2;2216 const { content, fallback } = normalizeSuspenseChildren(n2);2217 const oldSubTree = suspense.subTree;2218 const oldFallbackTree = suspense.fallbackTree;2219 if (!suspense.isResolved) {2220 patch(oldSubTree, content, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized);2221 if (suspense.deps > 0) {2222 // still pending. patch the fallback tree.2223 patch(oldFallbackTree, fallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context2224 isSVG, optimized);2225 n2.el = fallback.el;2226 }2227 // If deps somehow becomes 0 after the patch it means the patch caused an2228 // async dep component to unmount and removed its dep. It will cause the2229 // suspense to resolve and we don't need to do anything here.2230 }2231 else {2232 // just normal patch inner content as a fragment2233 patch(oldSubTree, content, container, anchor, parentComponent, suspense, isSVG, optimized);2234 n2.el = content.el;2235 }2236 suspense.subTree = content;2237 suspense.fallbackTree = fallback;2238 }2239 function resolveSuspense(suspense) {2240 {2241 if (suspense.isResolved) {2242 throw new Error(`resolveSuspense() is called on an already resolved suspense boundary.`);2243 }2244 if (suspense.isUnmounted) {2245 throw new Error(`resolveSuspense() is called on an already unmounted suspense boundary.`);2246 }2247 }2248 const { vnode, subTree, fallbackTree, effects, parentComponent, container } = suspense;2249 // this is initial anchor on mount2250 let { anchor } = suspense;2251 // unmount fallback tree2252 if (fallbackTree.el) {2253 // if the fallback tree was mounted, it may have been moved2254 // as part of a parent suspense. get the latest anchor for insertion2255 anchor = getNextHostNode(fallbackTree);2256 unmount(fallbackTree, parentComponent, suspense, true);2257 }2258 // move content from off-dom container to actual container2259 move(subTree, container, anchor);2260 const el = (vnode.el = subTree.el);2261 // suspense as the root node of a component...2262 if (parentComponent && parentComponent.subTree === vnode) {2263 parentComponent.vnode.el = el;2264 updateHOCHostEl(parentComponent, el);2265 }2266 // check if there is a pending parent suspense2267 let parent = suspense.parent;2268 let hasUnresolvedAncestor = false;2269 while (parent) {2270 if (!parent.isResolved) {2271 // found a pending parent suspense, merge buffered post jobs2272 // into that parent2273 parent.effects.push(...effects);2274 hasUnresolvedAncestor = true;2275 break;2276 }2277 parent = parent.parent;2278 }2279 // no pending parent suspense, flush all jobs2280 if (!hasUnresolvedAncestor) {2281 queuePostFlushCb(effects);2282 }2283 suspense.isResolved = true;2284 // invoke @resolve event2285 const onResolve = vnode.props && vnode.props.onResolve;2286 if (isFunction(onResolve)) {2287 onResolve();2288 }2289 }2290 function restartSuspense(suspense) {2291 suspense.isResolved = false;2292 const { vnode, subTree, fallbackTree, parentComponent, container, hiddenContainer, isSVG, optimized } = suspense;2293 // move content tree back to the off-dom container2294 const anchor = getNextHostNode(subTree);2295 move(subTree, hiddenContainer, null);2296 // remount the fallback tree2297 patch(null, fallbackTree, container, anchor, parentComponent, null, // fallback tree will not have suspense context2298 isSVG, optimized);2299 const el = (vnode.el = fallbackTree.el);2300 // suspense as the root node of a component...2301 if (parentComponent && parentComponent.subTree === vnode) {2302 parentComponent.vnode.el = el;2303 updateHOCHostEl(parentComponent, el);2304 }2305 // invoke @suspense event2306 const onSuspense = vnode.props && vnode.props.onSuspense;2307 if (isFunction(onSuspense)) {2308 onSuspense();2309 }2310 }2311 function processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {2312 if (n1 == null) {2313 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG);2314 }2315 else {2316 const instance = (n2.component = n1.component);2317 if (shouldUpdateComponent(n1, n2, optimized)) {2318 if (2319 instance.asyncDep &&2320 !instance.asyncResolved) {2321 // async & still pending - just update props and slots2322 // since the component's reactive effect for render isn't set-up yet2323 {2324 pushWarningContext(n2);2325 }2326 updateComponentPreRender(instance, n2);2327 {2328 popWarningContext();2329 }2330 return;2331 }2332 else {2333 // normal update2334 instance.next = n2;2335 // instance.update is the reactive effect runner.2336 instance.update();2337 }2338 }2339 else {2340 // no update needed. just copy over properties2341 n2.component = n1.component;2342 n2.el = n1.el;2343 }2344 }2345 if (n2.ref !== null && parentComponent !== null) {2346 setRef(n2.ref, n1 && n1.ref, parentComponent, n2.component.renderProxy);2347 }2348 }2349 function mountComponent(initialVNode, container, anchor, parentComponent, parentSuspense, isSVG) {2350 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent));2351 {2352 pushWarningContext(initialVNode);2353 }2354 // resolve props and slots for setup context2355 const propsOptions = initialVNode.type.props;2356 resolveProps(instance, initialVNode.props, propsOptions);2357 resolveSlots(instance, initialVNode.children);2358 // setup stateful logic2359 if (initialVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {2360 setupStatefulComponent(instance, parentSuspense);2361 }2362 // setup() is async. This component relies on async logic to be resolved2363 // before proceeding2364 if ( instance.asyncDep) {2365 if (!parentSuspense) {2366 // TODO handle this properly2367 throw new Error('Async component without a suspense boundary!');2368 }2369 // parent suspense already resolved, need to re-suspense2370 // use queueJob so it's handled synchronously after patching the current2371 // suspense tree2372 if (parentSuspense.isResolved) {2373 queueJob(() => {2374 restartSuspense(parentSuspense);2375 });2376 }2377 parentSuspense.deps++;2378 instance.asyncDep2379 .catch(err => {2380 handleError(err, instance, 0 /* SETUP_FUNCTION */);2381 })2382 .then(asyncSetupResult => {2383 // component may be unmounted before resolve2384 if (!instance.isUnmounted && !parentSuspense.isUnmounted) {2385 retryAsyncComponent(instance, asyncSetupResult, parentSuspense, isSVG);2386 }2387 });2388 // give it a placeholder2389 const placeholder = (instance.subTree = createVNode(Comment));2390 processCommentNode(null, placeholder, container, anchor);2391 initialVNode.el = placeholder.el;2392 return;2393 }2394 setupRenderEffect(instance, parentSuspense, initialVNode, container, anchor, isSVG);2395 {2396 popWarningContext();2397 }2398 }2399 function retryAsyncComponent(instance, asyncSetupResult, parentSuspense, isSVG) {2400 parentSuspense.deps--;2401 // retry from this component2402 instance.asyncResolved = true;2403 const { vnode } = instance;2404 {2405 pushWarningContext(vnode);2406 }2407 handleSetupResult(instance, asyncSetupResult, parentSuspense);2408 setupRenderEffect(instance, parentSuspense, vnode, 2409 // component may have been moved before resolve2410 hostParentNode(instance.subTree.el), getNextHostNode(instance.subTree), isSVG);2411 updateHOCHostEl(instance, vnode.el);2412 {2413 popWarningContext();2414 }2415 if (parentSuspense.deps === 0) {2416 resolveSuspense(parentSuspense);2417 }2418 }2419 function setupRenderEffect(instance, parentSuspense, initialVNode, container, anchor, isSVG) {2420 // create reactive effect for rendering2421 let mounted = false;2422 instance.update = effect(function componentEffect() {2423 if (!mounted) {2424 const subTree = (instance.subTree = renderComponentRoot(instance));2425 // beforeMount hook2426 if (instance.bm !== null) {2427 invokeHooks(instance.bm);2428 }2429 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);2430 initialVNode.el = subTree.el;2431 // mounted hook2432 if (instance.m !== null) {2433 queuePostRenderEffect(instance.m, parentSuspense);2434 }2435 mounted = true;2436 }2437 else {2438 // updateComponent2439 // This is triggered by mutation of component's own state (next: null)2440 // OR parent calling processComponent (next: HostVNode)2441 const { next } = instance;2442 {2443 pushWarningContext(next || instance.vnode);2444 }2445 if (next !== null) {2446 updateComponentPreRender(instance, next);2447 }2448 const prevTree = instance.subTree;2449 const nextTree = (instance.subTree = renderComponentRoot(instance));2450 // beforeUpdate hook2451 if (instance.bu !== null) {2452 invokeHooks(instance.bu);2453 }2454 // reset refs2455 // only needed if previous patch had refs2456 if (instance.refs !== EMPTY_OBJ) {2457 instance.refs = {};2458 }2459 patch(prevTree, nextTree, 2460 // parent may have changed if it's in a portal2461 hostParentNode(prevTree.el), 2462 // anchor may have changed if it's in a fragment2463 getNextHostNode(prevTree), instance, parentSuspense, isSVG);2464 instance.vnode.el = nextTree.el;2465 if (next === null) {2466 // self-triggered update. In case of HOC, update parent component2467 // vnode el. HOC is indicated by parent instance's subTree pointing2468 // to child component's vnode2469 updateHOCHostEl(instance, nextTree.el);2470 }2471 // updated hook2472 if (instance.u !== null) {2473 queuePostRenderEffect(instance.u, parentSuspense);2474 }2475 {2476 popWarningContext();2477 }2478 }2479 }, createDevEffectOptions(instance) );2480 }2481 function updateComponentPreRender(instance, nextVNode) {2482 nextVNode.component = instance;2483 instance.vnode = nextVNode;2484 instance.next = null;2485 resolveProps(instance, nextVNode.props, nextVNode.type.props);2486 resolveSlots(instance, nextVNode.children);2487 }2488 function updateHOCHostEl({ vnode, parent }, el) {2489 while (parent && parent.subTree === vnode) {2490 (vnode = parent.vnode).el = el;2491 parent = parent.parent;2492 }2493 } ...

Full Screen

Full Screen

runtime-dom.global.js

Source:runtime-dom.global.js Github

copy

Full Screen

...1860 fallback: normalizeVNode(null)1861 };1862 }1863 }1864 function createDevEffectOptions(instance) {1865 return {1866 scheduler: queueJob,1867 onTrack: instance.rtc ? e => invokeHooks(instance.rtc, e) : void 0,1868 onTrigger: instance.rtg ? e => invokeHooks(instance.rtg, e) : void 01869 };1870 }1871 function isSameType$1(n1, n2) {1872 return n1.type === n2.type && n1.key === n2.key;1873 }1874 function invokeHooks(hooks, arg) {1875 for (let i = 0; i < hooks.length; i++) {1876 hooks[i](arg);1877 }1878 }1879 function queuePostRenderEffect(fn, suspense) {1880 if (suspense !== null && !suspense.isResolved) {1881 if (isArray(fn)) {1882 suspense.effects.push(...fn);1883 }1884 else {1885 suspense.effects.push(fn);1886 }1887 }1888 else {1889 queuePostFlushCb(fn);1890 }1891 }1892 /**1893 * The createRenderer function accepts two generic arguments:1894 * HostNode and HostElement, corresponding to Node and Element types in the1895 * host environment. For example, for runtime-dom, HostNode would be the DOM1896 * `Node` interface and HostElement would be the DOM `Element` interface.1897 *1898 * Custom renderers can pass in the platform specific types like this:1899 *1900 * ``` js1901 * const { render, createApp } = createRenderer<Node, Element>({1902 * patchProp,1903 * ...nodeOps1904 * })1905 * ```1906 */1907 function createRenderer(options) {1908 const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, querySelector: hostQuerySelector } = options;1909 function patch(n1, // null means this is a mount1910 n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, optimized = false) {1911 // patching & not same type, unmount old tree1912 if (n1 != null && !isSameType$1(n1, n2)) {1913 anchor = getNextHostNode(n1);1914 unmount(n1, parentComponent, parentSuspense, true);1915 n1 = null;1916 }1917 const { type, shapeFlag } = n2;1918 switch (type) {1919 case Text:1920 processText(n1, n2, container, anchor);1921 break;1922 case Comment:1923 processCommentNode(n1, n2, container, anchor);1924 break;1925 case Fragment:1926 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1927 break;1928 case Portal:1929 processPortal(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1930 break;1931 case Suspense:1932 {1933 processSuspense(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1934 }1935 break;1936 default:1937 if (shapeFlag & 1 /* ELEMENT */) {1938 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1939 }1940 else if (shapeFlag & 6 /* COMPONENT */) {1941 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1942 }1943 else {1944 warn('Invalid HostVNode type:', n2.type, `(${typeof n2.type})`);1945 }1946 }1947 }1948 function processText(n1, n2, container, anchor) {1949 if (n1 == null) {1950 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);1951 }1952 else {1953 const el = (n2.el = n1.el);1954 if (n2.children !== n1.children) {1955 hostSetText(el, n2.children);1956 }1957 }1958 }1959 function processCommentNode(n1, n2, container, anchor) {1960 if (n1 == null) {1961 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);1962 }1963 else {1964 // there's no support for dynamic comments1965 n2.el = n1.el;1966 }1967 }1968 function processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1969 if (n1 == null) {1970 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG);1971 }1972 else {1973 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized);1974 }1975 if (n2.ref !== null && parentComponent !== null) {1976 setRef(n2.ref, n1 && n1.ref, parentComponent, n2.el);1977 }1978 }1979 function mountElement(vnode, container, anchor, parentComponent, parentSuspense, isSVG) {1980 const tag = vnode.type;1981 isSVG = isSVG || tag === 'svg';1982 const el = (vnode.el = hostCreateElement(tag, isSVG));1983 const { props, shapeFlag } = vnode;1984 if (props != null) {1985 for (const key in props) {1986 if (isReservedProp(key))1987 continue;1988 hostPatchProp(el, key, props[key], null, isSVG);1989 }1990 if (props.vnodeBeforeMount != null) {1991 invokeDirectiveHook(props.vnodeBeforeMount, parentComponent, vnode);1992 }1993 }1994 if (shapeFlag & 8 /* TEXT_CHILDREN */) {1995 hostSetElementText(el, vnode.children);1996 }1997 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1998 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG);1999 }2000 hostInsert(el, container, anchor);2001 if (props != null && props.vnodeMounted != null) {2002 queuePostRenderEffect(() => {2003 invokeDirectiveHook(props.vnodeMounted, parentComponent, vnode);2004 }, parentSuspense);2005 }2006 }2007 function mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, start = 0) {2008 for (let i = start; i < children.length; i++) {2009 const child = (children[i] = normalizeVNode(children[i]));2010 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG);2011 }2012 }2013 function patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized) {2014 const el = (n2.el = n1.el);2015 const { patchFlag, dynamicChildren } = n2;2016 const oldProps = (n1 && n1.props) || EMPTY_OBJ;2017 const newProps = n2.props || EMPTY_OBJ;2018 if (newProps.vnodeBeforeUpdate != null) {2019 invokeDirectiveHook(newProps.vnodeBeforeUpdate, parentComponent, n2, n1);2020 }2021 if (patchFlag > 0) {2022 // the presence of a patchFlag means this element's render code was2023 // generated by the compiler and can take the fast path.2024 // in this path old node and new node are guaranteed to have the same shape2025 // (i.e. at the exact same position in the source template)2026 if (patchFlag & 16 /* FULL_PROPS */) {2027 // element props contain dynamic keys, full diff needed2028 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);2029 }2030 else {2031 // class2032 // this flag is matched when the element has dynamic class bindings.2033 if (patchFlag & 2 /* CLASS */) {2034 if (oldProps.class !== newProps.class) {2035 hostPatchProp(el, 'class', newProps.class, null, isSVG);2036 }2037 }2038 // style2039 // this flag is matched when the element has dynamic style bindings2040 if (patchFlag & 4 /* STYLE */) {2041 hostPatchProp(el, 'style', newProps.style, oldProps.style, isSVG);2042 }2043 // props2044 // This flag is matched when the element has dynamic prop/attr bindings2045 // other than class and style. The keys of dynamic prop/attrs are saved for2046 // faster iteration.2047 // Note dynamic keys like :[foo]="bar" will cause this optimization to2048 // bail out and go through a full diff because we need to unset the old key2049 if (patchFlag & 8 /* PROPS */) {2050 // if the flag is present then dynamicProps must be non-null2051 const propsToUpdate = n2.dynamicProps;2052 for (let i = 0; i < propsToUpdate.length; i++) {2053 const key = propsToUpdate[i];2054 const prev = oldProps[key];2055 const next = newProps[key];2056 if (prev !== next) {2057 hostPatchProp(el, key, next, prev, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);2058 }2059 }2060 }2061 }2062 // text2063 // This flag is matched when the element has only dynamic text children.2064 // this flag is terminal (i.e. skips children diffing).2065 if (patchFlag & 1 /* TEXT */) {2066 if (n1.children !== n2.children) {2067 hostSetElementText(el, n2.children);2068 }2069 return; // terminal2070 }2071 }2072 else if (!optimized) {2073 // unoptimized, full diff2074 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);2075 }2076 if (dynamicChildren != null) {2077 // children fast path2078 const oldDynamicChildren = n1.dynamicChildren;2079 for (let i = 0; i < dynamicChildren.length; i++) {2080 patch(oldDynamicChildren[i], dynamicChildren[i], el, null, parentComponent, parentSuspense, isSVG, true);2081 }2082 }2083 else if (!optimized) {2084 // full diff2085 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, isSVG);2086 }2087 if (newProps.vnodeUpdated != null) {2088 queuePostRenderEffect(() => {2089 invokeDirectiveHook(newProps.vnodeUpdated, parentComponent, n2, n1);2090 }, parentSuspense);2091 }2092 }2093 function patchProps(el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) {2094 if (oldProps !== newProps) {2095 for (const key in newProps) {2096 if (isReservedProp(key))2097 continue;2098 const next = newProps[key];2099 const prev = oldProps[key];2100 if (next !== prev) {2101 hostPatchProp(el, key, next, prev, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);2102 }2103 }2104 if (oldProps !== EMPTY_OBJ) {2105 for (const key in oldProps) {2106 if (isReservedProp(key))2107 continue;2108 if (!(key in newProps)) {2109 hostPatchProp(el, key, null, null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);2110 }2111 }2112 }2113 }2114 }2115 function processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {2116 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateComment(''));2117 const fragmentEndAnchor = (n2.anchor = n12118 ? n1.anchor2119 : hostCreateComment(''));2120 if (n1 == null) {2121 hostInsert(fragmentStartAnchor, container, anchor);2122 hostInsert(fragmentEndAnchor, container, anchor);2123 // a fragment can only have array children2124 // since they are either generated by the compiler, or implicitly created2125 // from arrays.2126 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG);2127 }2128 else {2129 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);2130 }2131 }2132 function processPortal(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {2133 const targetSelector = n2.props && n2.props.target;2134 const { patchFlag, shapeFlag, children } = n2;2135 if (n1 == null) {2136 const target = (n2.target = isString(targetSelector)2137 ? hostQuerySelector(targetSelector)2138 : null);2139 if (target != null) {2140 if (shapeFlag & 8 /* TEXT_CHILDREN */) {2141 hostSetElementText(target, children);2142 }2143 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {2144 mountChildren(children, target, null, parentComponent, parentSuspense, isSVG);2145 }2146 }2147 else {2148 warn('Invalid Portal target on mount:', target, `(${typeof target})`);2149 }2150 }2151 else {2152 // update content2153 const target = (n2.target = n1.target);2154 if (patchFlag === 1 /* TEXT */) {2155 hostSetElementText(target, children);2156 }2157 else if (!optimized) {2158 patchChildren(n1, n2, target, null, parentComponent, parentSuspense, isSVG);2159 }2160 // target changed2161 if (targetSelector !== (n1.props && n1.props.target)) {2162 const nextTarget = (n2.target = isString(targetSelector)2163 ? hostQuerySelector(targetSelector)2164 : null);2165 if (nextTarget != null) {2166 // move content2167 if (shapeFlag & 8 /* TEXT_CHILDREN */) {2168 hostSetElementText(target, '');2169 hostSetElementText(nextTarget, children);2170 }2171 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {2172 for (let i = 0; i < children.length; i++) {2173 move(children[i], nextTarget, null);2174 }2175 }2176 }2177 else {2178 warn('Invalid Portal target on update:', target, `(${typeof target})`);2179 }2180 }2181 }2182 // insert an empty node as the placeholder for the portal2183 processCommentNode(n1, n2, container, anchor);2184 }2185 function processSuspense(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {2186 if (n1 == null) {2187 mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);2188 }2189 else {2190 patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized);2191 }2192 }2193 function mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {2194 const hiddenContainer = hostCreateElement('div');2195 const suspense = (n2.suspense = createSuspenseBoundary(n2, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, optimized));2196 const { content, fallback } = normalizeSuspenseChildren(n2);2197 suspense.subTree = content;2198 suspense.fallbackTree = fallback;2199 // start mounting the content subtree in an off-dom container2200 patch(null, content, hiddenContainer, null, parentComponent, suspense, isSVG, optimized);2201 // now check if we have encountered any async deps2202 if (suspense.deps > 0) {2203 // mount the fallback tree2204 patch(null, fallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context2205 isSVG, optimized);2206 n2.el = fallback.el;2207 }2208 else {2209 // Suspense has no async deps. Just resolve.2210 resolveSuspense(suspense);2211 }2212 }2213 function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized) {2214 const suspense = (n2.suspense = n1.suspense);2215 suspense.vnode = n2;2216 const { content, fallback } = normalizeSuspenseChildren(n2);2217 const oldSubTree = suspense.subTree;2218 const oldFallbackTree = suspense.fallbackTree;2219 if (!suspense.isResolved) {2220 patch(oldSubTree, content, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized);2221 if (suspense.deps > 0) {2222 // still pending. patch the fallback tree.2223 patch(oldFallbackTree, fallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context2224 isSVG, optimized);2225 n2.el = fallback.el;2226 }2227 // If deps somehow becomes 0 after the patch it means the patch caused an2228 // async dep component to unmount and removed its dep. It will cause the2229 // suspense to resolve and we don't need to do anything here.2230 }2231 else {2232 // just normal patch inner content as a fragment2233 patch(oldSubTree, content, container, anchor, parentComponent, suspense, isSVG, optimized);2234 n2.el = content.el;2235 }2236 suspense.subTree = content;2237 suspense.fallbackTree = fallback;2238 }2239 function resolveSuspense(suspense) {2240 {2241 if (suspense.isResolved) {2242 throw new Error(`resolveSuspense() is called on an already resolved suspense boundary.`);2243 }2244 if (suspense.isUnmounted) {2245 throw new Error(`resolveSuspense() is called on an already unmounted suspense boundary.`);2246 }2247 }2248 const { vnode, subTree, fallbackTree, effects, parentComponent, container } = suspense;2249 // this is initial anchor on mount2250 let { anchor } = suspense;2251 // unmount fallback tree2252 if (fallbackTree.el) {2253 // if the fallback tree was mounted, it may have been moved2254 // as part of a parent suspense. get the latest anchor for insertion2255 anchor = getNextHostNode(fallbackTree);2256 unmount(fallbackTree, parentComponent, suspense, true);2257 }2258 // move content from off-dom container to actual container2259 move(subTree, container, anchor);2260 const el = (vnode.el = subTree.el);2261 // suspense as the root node of a component...2262 if (parentComponent && parentComponent.subTree === vnode) {2263 parentComponent.vnode.el = el;2264 updateHOCHostEl(parentComponent, el);2265 }2266 // check if there is a pending parent suspense2267 let parent = suspense.parent;2268 let hasUnresolvedAncestor = false;2269 while (parent) {2270 if (!parent.isResolved) {2271 // found a pending parent suspense, merge buffered post jobs2272 // into that parent2273 parent.effects.push(...effects);2274 hasUnresolvedAncestor = true;2275 break;2276 }2277 parent = parent.parent;2278 }2279 // no pending parent suspense, flush all jobs2280 if (!hasUnresolvedAncestor) {2281 queuePostFlushCb(effects);2282 }2283 suspense.isResolved = true;2284 // invoke @resolve event2285 const onResolve = vnode.props && vnode.props.onResolve;2286 if (isFunction(onResolve)) {2287 onResolve();2288 }2289 }2290 function restartSuspense(suspense) {2291 suspense.isResolved = false;2292 const { vnode, subTree, fallbackTree, parentComponent, container, hiddenContainer, isSVG, optimized } = suspense;2293 // move content tree back to the off-dom container2294 const anchor = getNextHostNode(subTree);2295 move(subTree, hiddenContainer, null);2296 // remount the fallback tree2297 patch(null, fallbackTree, container, anchor, parentComponent, null, // fallback tree will not have suspense context2298 isSVG, optimized);2299 const el = (vnode.el = fallbackTree.el);2300 // suspense as the root node of a component...2301 if (parentComponent && parentComponent.subTree === vnode) {2302 parentComponent.vnode.el = el;2303 updateHOCHostEl(parentComponent, el);2304 }2305 // invoke @suspense event2306 const onSuspense = vnode.props && vnode.props.onSuspense;2307 if (isFunction(onSuspense)) {2308 onSuspense();2309 }2310 }2311 function processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {2312 if (n1 == null) {2313 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG);2314 }2315 else {2316 const instance = (n2.component = n1.component);2317 if (shouldUpdateComponent(n1, n2, optimized)) {2318 if (2319 instance.asyncDep &&2320 !instance.asyncResolved) {2321 // async & still pending - just update props and slots2322 // since the component's reactive effect for render isn't set-up yet2323 {2324 pushWarningContext(n2);2325 }2326 updateComponentPreRender(instance, n2);2327 {2328 popWarningContext();2329 }2330 return;2331 }2332 else {2333 // normal update2334 instance.next = n2;2335 // instance.update is the reactive effect runner.2336 instance.update();2337 }2338 }2339 else {2340 // no update needed. just copy over properties2341 n2.component = n1.component;2342 n2.el = n1.el;2343 }2344 }2345 if (n2.ref !== null && parentComponent !== null) {2346 setRef(n2.ref, n1 && n1.ref, parentComponent, n2.component.renderProxy);2347 }2348 }2349 function mountComponent(initialVNode, container, anchor, parentComponent, parentSuspense, isSVG) {2350 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent));2351 {2352 pushWarningContext(initialVNode);2353 }2354 // resolve props and slots for setup context2355 const propsOptions = initialVNode.type.props;2356 resolveProps(instance, initialVNode.props, propsOptions);2357 resolveSlots(instance, initialVNode.children);2358 // setup stateful logic2359 if (initialVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {2360 setupStatefulComponent(instance, parentSuspense);2361 }2362 // setup() is async. This component relies on async logic to be resolved2363 // before proceeding2364 if ( instance.asyncDep) {2365 if (!parentSuspense) {2366 // TODO handle this properly2367 throw new Error('Async component without a suspense boundary!');2368 }2369 // parent suspense already resolved, need to re-suspense2370 // use queueJob so it's handled synchronously after patching the current2371 // suspense tree2372 if (parentSuspense.isResolved) {2373 queueJob(() => {2374 restartSuspense(parentSuspense);2375 });2376 }2377 parentSuspense.deps++;2378 instance.asyncDep2379 .catch(err => {2380 handleError(err, instance, 0 /* SETUP_FUNCTION */);2381 })2382 .then(asyncSetupResult => {2383 // component may be unmounted before resolve2384 if (!instance.isUnmounted && !parentSuspense.isUnmounted) {2385 retryAsyncComponent(instance, asyncSetupResult, parentSuspense, isSVG);2386 }2387 });2388 // give it a placeholder2389 const placeholder = (instance.subTree = createVNode(Comment));2390 processCommentNode(null, placeholder, container, anchor);2391 initialVNode.el = placeholder.el;2392 return;2393 }2394 setupRenderEffect(instance, parentSuspense, initialVNode, container, anchor, isSVG);2395 {2396 popWarningContext();2397 }2398 }2399 function retryAsyncComponent(instance, asyncSetupResult, parentSuspense, isSVG) {2400 parentSuspense.deps--;2401 // retry from this component2402 instance.asyncResolved = true;2403 const { vnode } = instance;2404 {2405 pushWarningContext(vnode);2406 }2407 handleSetupResult(instance, asyncSetupResult, parentSuspense);2408 setupRenderEffect(instance, parentSuspense, vnode, 2409 // component may have been moved before resolve2410 hostParentNode(instance.subTree.el), getNextHostNode(instance.subTree), isSVG);2411 updateHOCHostEl(instance, vnode.el);2412 {2413 popWarningContext();2414 }2415 if (parentSuspense.deps === 0) {2416 resolveSuspense(parentSuspense);2417 }2418 }2419 function setupRenderEffect(instance, parentSuspense, initialVNode, container, anchor, isSVG) {2420 // create reactive effect for rendering2421 let mounted = false;2422 instance.update = effect(function componentEffect() {2423 if (!mounted) {2424 const subTree = (instance.subTree = renderComponentRoot(instance));2425 // beforeMount hook2426 if (instance.bm !== null) {2427 invokeHooks(instance.bm);2428 }2429 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);2430 initialVNode.el = subTree.el;2431 // mounted hook2432 if (instance.m !== null) {2433 queuePostRenderEffect(instance.m, parentSuspense);2434 }2435 mounted = true;2436 }2437 else {2438 // updateComponent2439 // This is triggered by mutation of component's own state (next: null)2440 // OR parent calling processComponent (next: HostVNode)2441 const { next } = instance;2442 {2443 pushWarningContext(next || instance.vnode);2444 }2445 if (next !== null) {2446 updateComponentPreRender(instance, next);2447 }2448 const prevTree = instance.subTree;2449 const nextTree = (instance.subTree = renderComponentRoot(instance));2450 // beforeUpdate hook2451 if (instance.bu !== null) {2452 invokeHooks(instance.bu);2453 }2454 // reset refs2455 // only needed if previous patch had refs2456 if (instance.refs !== EMPTY_OBJ) {2457 instance.refs = {};2458 }2459 patch(prevTree, nextTree, 2460 // parent may have changed if it's in a portal2461 hostParentNode(prevTree.el), 2462 // anchor may have changed if it's in a fragment2463 getNextHostNode(prevTree), instance, parentSuspense, isSVG);2464 instance.vnode.el = nextTree.el;2465 if (next === null) {2466 // self-triggered update. In case of HOC, update parent component2467 // vnode el. HOC is indicated by parent instance's subTree pointing2468 // to child component's vnode2469 updateHOCHostEl(instance, nextTree.el);2470 }2471 // updated hook2472 if (instance.u !== null) {2473 queuePostRenderEffect(instance.u, parentSuspense);2474 }2475 {2476 popWarningContext();2477 }2478 }2479 }, createDevEffectOptions(instance) );2480 }2481 function updateComponentPreRender(instance, nextVNode) {2482 nextVNode.component = instance;2483 instance.vnode = nextVNode;2484 instance.next = null;2485 resolveProps(instance, nextVNode.props, nextVNode.type.props);2486 resolveSlots(instance, nextVNode.children);2487 }2488 function updateHOCHostEl({ vnode, parent }, el) {2489 while (parent && parent.subTree === vnode) {2490 (vnode = parent.vnode).el = el;2491 parent = parent.parent;2492 }2493 } ...

Full Screen

Full Screen

runtime-dom.esm-browser.js

Source:runtime-dom.esm-browser.js Github

copy

Full Screen

...1848 };1849 }1850}18511852function createDevEffectOptions(instance) {1853 return {1854 scheduler: queueJob,1855 onTrack: instance.rtc ? e => invokeHooks(instance.rtc, e) : void 0,1856 onTrigger: instance.rtg ? e => invokeHooks(instance.rtg, e) : void 01857 };1858}1859function isSameType$1(n1, n2) {1860 return n1.type === n2.type && n1.key === n2.key;1861}1862function invokeHooks(hooks, arg) {1863 for (let i = 0; i < hooks.length; i++) {1864 hooks[i](arg);1865 }1866}1867function queuePostRenderEffect(fn, suspense) {1868 if (suspense !== null && !suspense.isResolved) {1869 if (isArray(fn)) {1870 suspense.effects.push(...fn);1871 }1872 else {1873 suspense.effects.push(fn);1874 }1875 }1876 else {1877 queuePostFlushCb(fn);1878 }1879}1880/**1881 * The createRenderer function accepts two generic arguments:1882 * HostNode and HostElement, corresponding to Node and Element types in the1883 * host environment. For example, for runtime-dom, HostNode would be the DOM1884 * `Node` interface and HostElement would be the DOM `Element` interface.1885 *1886 * Custom renderers can pass in the platform specific types like this:1887 *1888 * ``` js1889 * const { render, createApp } = createRenderer<Node, Element>({1890 * patchProp,1891 * ...nodeOps1892 * })1893 * ```1894 */1895function createRenderer(options) {1896 const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, querySelector: hostQuerySelector } = options;1897 function patch(n1, // null means this is a mount1898 n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, optimized = false) {1899 // patching & not same type, unmount old tree1900 if (n1 != null && !isSameType$1(n1, n2)) {1901 anchor = getNextHostNode(n1);1902 unmount(n1, parentComponent, parentSuspense, true);1903 n1 = null;1904 }1905 const { type, shapeFlag } = n2;1906 switch (type) {1907 case Text:1908 processText(n1, n2, container, anchor);1909 break;1910 case Comment:1911 processCommentNode(n1, n2, container, anchor);1912 break;1913 case Fragment:1914 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1915 break;1916 case Portal:1917 processPortal(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1918 break;1919 case Suspense:1920 {1921 processSuspense(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1922 }1923 break;1924 default:1925 if (shapeFlag & 1 /* ELEMENT */) {1926 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1927 }1928 else if (shapeFlag & 6 /* COMPONENT */) {1929 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1930 }1931 else {1932 warn('Invalid HostVNode type:', n2.type, `(${typeof n2.type})`);1933 }1934 }1935 }1936 function processText(n1, n2, container, anchor) {1937 if (n1 == null) {1938 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);1939 }1940 else {1941 const el = (n2.el = n1.el);1942 if (n2.children !== n1.children) {1943 hostSetText(el, n2.children);1944 }1945 }1946 }1947 function processCommentNode(n1, n2, container, anchor) {1948 if (n1 == null) {1949 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);1950 }1951 else {1952 // there's no support for dynamic comments1953 n2.el = n1.el;1954 }1955 }1956 function processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1957 if (n1 == null) {1958 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG);1959 }1960 else {1961 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized);1962 }1963 if (n2.ref !== null && parentComponent !== null) {1964 setRef(n2.ref, n1 && n1.ref, parentComponent, n2.el);1965 }1966 }1967 function mountElement(vnode, container, anchor, parentComponent, parentSuspense, isSVG) {1968 const tag = vnode.type;1969 isSVG = isSVG || tag === 'svg';1970 const el = (vnode.el = hostCreateElement(tag, isSVG));1971 const { props, shapeFlag } = vnode;1972 if (props != null) {1973 for (const key in props) {1974 if (isReservedProp(key))1975 continue;1976 hostPatchProp(el, key, props[key], null, isSVG);1977 }1978 if (props.vnodeBeforeMount != null) {1979 invokeDirectiveHook(props.vnodeBeforeMount, parentComponent, vnode);1980 }1981 }1982 if (shapeFlag & 8 /* TEXT_CHILDREN */) {1983 hostSetElementText(el, vnode.children);1984 }1985 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1986 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG);1987 }1988 hostInsert(el, container, anchor);1989 if (props != null && props.vnodeMounted != null) {1990 queuePostRenderEffect(() => {1991 invokeDirectiveHook(props.vnodeMounted, parentComponent, vnode);1992 }, parentSuspense);1993 }1994 }1995 function mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, start = 0) {1996 for (let i = start; i < children.length; i++) {1997 const child = (children[i] = normalizeVNode(children[i]));1998 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG);1999 }2000 }2001 function patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized) {2002 const el = (n2.el = n1.el);2003 const { patchFlag, dynamicChildren } = n2;2004 const oldProps = (n1 && n1.props) || EMPTY_OBJ;2005 const newProps = n2.props || EMPTY_OBJ;2006 if (newProps.vnodeBeforeUpdate != null) {2007 invokeDirectiveHook(newProps.vnodeBeforeUpdate, parentComponent, n2, n1);2008 }2009 if (patchFlag > 0) {2010 // the presence of a patchFlag means this element's render code was2011 // generated by the compiler and can take the fast path.2012 // in this path old node and new node are guaranteed to have the same shape2013 // (i.e. at the exact same position in the source template)2014 if (patchFlag & 16 /* FULL_PROPS */) {2015 // element props contain dynamic keys, full diff needed2016 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);2017 }2018 else {2019 // class2020 // this flag is matched when the element has dynamic class bindings.2021 if (patchFlag & 2 /* CLASS */) {2022 if (oldProps.class !== newProps.class) {2023 hostPatchProp(el, 'class', newProps.class, null, isSVG);2024 }2025 }2026 // style2027 // this flag is matched when the element has dynamic style bindings2028 if (patchFlag & 4 /* STYLE */) {2029 hostPatchProp(el, 'style', newProps.style, oldProps.style, isSVG);2030 }2031 // props2032 // This flag is matched when the element has dynamic prop/attr bindings2033 // other than class and style. The keys of dynamic prop/attrs are saved for2034 // faster iteration.2035 // Note dynamic keys like :[foo]="bar" will cause this optimization to2036 // bail out and go through a full diff because we need to unset the old key2037 if (patchFlag & 8 /* PROPS */) {2038 // if the flag is present then dynamicProps must be non-null2039 const propsToUpdate = n2.dynamicProps;2040 for (let i = 0; i < propsToUpdate.length; i++) {2041 const key = propsToUpdate[i];2042 const prev = oldProps[key];2043 const next = newProps[key];2044 if (prev !== next) {2045 hostPatchProp(el, key, next, prev, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);2046 }2047 }2048 }2049 }2050 // text2051 // This flag is matched when the element has only dynamic text children.2052 // this flag is terminal (i.e. skips children diffing).2053 if (patchFlag & 1 /* TEXT */) {2054 if (n1.children !== n2.children) {2055 hostSetElementText(el, n2.children);2056 }2057 return; // terminal2058 }2059 }2060 else if (!optimized) {2061 // unoptimized, full diff2062 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);2063 }2064 if (dynamicChildren != null) {2065 // children fast path2066 const oldDynamicChildren = n1.dynamicChildren;2067 for (let i = 0; i < dynamicChildren.length; i++) {2068 patch(oldDynamicChildren[i], dynamicChildren[i], el, null, parentComponent, parentSuspense, isSVG, true);2069 }2070 }2071 else if (!optimized) {2072 // full diff2073 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, isSVG);2074 }2075 if (newProps.vnodeUpdated != null) {2076 queuePostRenderEffect(() => {2077 invokeDirectiveHook(newProps.vnodeUpdated, parentComponent, n2, n1);2078 }, parentSuspense);2079 }2080 }2081 function patchProps(el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) {2082 if (oldProps !== newProps) {2083 for (const key in newProps) {2084 if (isReservedProp(key))2085 continue;2086 const next = newProps[key];2087 const prev = oldProps[key];2088 if (next !== prev) {2089 hostPatchProp(el, key, next, prev, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);2090 }2091 }2092 if (oldProps !== EMPTY_OBJ) {2093 for (const key in oldProps) {2094 if (isReservedProp(key))2095 continue;2096 if (!(key in newProps)) {2097 hostPatchProp(el, key, null, null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);2098 }2099 }2100 }2101 }2102 }2103 function processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {2104 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateComment(''));2105 const fragmentEndAnchor = (n2.anchor = n12106 ? n1.anchor2107 : hostCreateComment(''));2108 if (n1 == null) {2109 hostInsert(fragmentStartAnchor, container, anchor);2110 hostInsert(fragmentEndAnchor, container, anchor);2111 // a fragment can only have array children2112 // since they are either generated by the compiler, or implicitly created2113 // from arrays.2114 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG);2115 }2116 else {2117 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);2118 }2119 }2120 function processPortal(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {2121 const targetSelector = n2.props && n2.props.target;2122 const { patchFlag, shapeFlag, children } = n2;2123 if (n1 == null) {2124 const target = (n2.target = isString(targetSelector)2125 ? hostQuerySelector(targetSelector)2126 : null);2127 if (target != null) {2128 if (shapeFlag & 8 /* TEXT_CHILDREN */) {2129 hostSetElementText(target, children);2130 }2131 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {2132 mountChildren(children, target, null, parentComponent, parentSuspense, isSVG);2133 }2134 }2135 else {2136 warn('Invalid Portal target on mount:', target, `(${typeof target})`);2137 }2138 }2139 else {2140 // update content2141 const target = (n2.target = n1.target);2142 if (patchFlag === 1 /* TEXT */) {2143 hostSetElementText(target, children);2144 }2145 else if (!optimized) {2146 patchChildren(n1, n2, target, null, parentComponent, parentSuspense, isSVG);2147 }2148 // target changed2149 if (targetSelector !== (n1.props && n1.props.target)) {2150 const nextTarget = (n2.target = isString(targetSelector)2151 ? hostQuerySelector(targetSelector)2152 : null);2153 if (nextTarget != null) {2154 // move content2155 if (shapeFlag & 8 /* TEXT_CHILDREN */) {2156 hostSetElementText(target, '');2157 hostSetElementText(nextTarget, children);2158 }2159 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {2160 for (let i = 0; i < children.length; i++) {2161 move(children[i], nextTarget, null);2162 }2163 }2164 }2165 else {2166 warn('Invalid Portal target on update:', target, `(${typeof target})`);2167 }2168 }2169 }2170 // insert an empty node as the placeholder for the portal2171 processCommentNode(n1, n2, container, anchor);2172 }2173 function processSuspense(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {2174 if (n1 == null) {2175 mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);2176 }2177 else {2178 patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized);2179 }2180 }2181 function mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {2182 const hiddenContainer = hostCreateElement('div');2183 const suspense = (n2.suspense = createSuspenseBoundary(n2, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, optimized));2184 const { content, fallback } = normalizeSuspenseChildren(n2);2185 suspense.subTree = content;2186 suspense.fallbackTree = fallback;2187 // start mounting the content subtree in an off-dom container2188 patch(null, content, hiddenContainer, null, parentComponent, suspense, isSVG, optimized);2189 // now check if we have encountered any async deps2190 if (suspense.deps > 0) {2191 // mount the fallback tree2192 patch(null, fallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context2193 isSVG, optimized);2194 n2.el = fallback.el;2195 }2196 else {2197 // Suspense has no async deps. Just resolve.2198 resolveSuspense(suspense);2199 }2200 }2201 function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized) {2202 const suspense = (n2.suspense = n1.suspense);2203 suspense.vnode = n2;2204 const { content, fallback } = normalizeSuspenseChildren(n2);2205 const oldSubTree = suspense.subTree;2206 const oldFallbackTree = suspense.fallbackTree;2207 if (!suspense.isResolved) {2208 patch(oldSubTree, content, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized);2209 if (suspense.deps > 0) {2210 // still pending. patch the fallback tree.2211 patch(oldFallbackTree, fallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context2212 isSVG, optimized);2213 n2.el = fallback.el;2214 }2215 // If deps somehow becomes 0 after the patch it means the patch caused an2216 // async dep component to unmount and removed its dep. It will cause the2217 // suspense to resolve and we don't need to do anything here.2218 }2219 else {2220 // just normal patch inner content as a fragment2221 patch(oldSubTree, content, container, anchor, parentComponent, suspense, isSVG, optimized);2222 n2.el = content.el;2223 }2224 suspense.subTree = content;2225 suspense.fallbackTree = fallback;2226 }2227 function resolveSuspense(suspense) {2228 {2229 if (suspense.isResolved) {2230 throw new Error(`resolveSuspense() is called on an already resolved suspense boundary.`);2231 }2232 if (suspense.isUnmounted) {2233 throw new Error(`resolveSuspense() is called on an already unmounted suspense boundary.`);2234 }2235 }2236 const { vnode, subTree, fallbackTree, effects, parentComponent, container } = suspense;2237 // this is initial anchor on mount2238 let { anchor } = suspense;2239 // unmount fallback tree2240 if (fallbackTree.el) {2241 // if the fallback tree was mounted, it may have been moved2242 // as part of a parent suspense. get the latest anchor for insertion2243 anchor = getNextHostNode(fallbackTree);2244 unmount(fallbackTree, parentComponent, suspense, true);2245 }2246 // move content from off-dom container to actual container2247 move(subTree, container, anchor);2248 const el = (vnode.el = subTree.el);2249 // suspense as the root node of a component...2250 if (parentComponent && parentComponent.subTree === vnode) {2251 parentComponent.vnode.el = el;2252 updateHOCHostEl(parentComponent, el);2253 }2254 // check if there is a pending parent suspense2255 let parent = suspense.parent;2256 let hasUnresolvedAncestor = false;2257 while (parent) {2258 if (!parent.isResolved) {2259 // found a pending parent suspense, merge buffered post jobs2260 // into that parent2261 parent.effects.push(...effects);2262 hasUnresolvedAncestor = true;2263 break;2264 }2265 parent = parent.parent;2266 }2267 // no pending parent suspense, flush all jobs2268 if (!hasUnresolvedAncestor) {2269 queuePostFlushCb(effects);2270 }2271 suspense.isResolved = true;2272 // invoke @resolve event2273 const onResolve = vnode.props && vnode.props.onResolve;2274 if (isFunction(onResolve)) {2275 onResolve();2276 }2277 }2278 function restartSuspense(suspense) {2279 suspense.isResolved = false;2280 const { vnode, subTree, fallbackTree, parentComponent, container, hiddenContainer, isSVG, optimized } = suspense;2281 // move content tree back to the off-dom container2282 const anchor = getNextHostNode(subTree);2283 move(subTree, hiddenContainer, null);2284 // remount the fallback tree2285 patch(null, fallbackTree, container, anchor, parentComponent, null, // fallback tree will not have suspense context2286 isSVG, optimized);2287 const el = (vnode.el = fallbackTree.el);2288 // suspense as the root node of a component...2289 if (parentComponent && parentComponent.subTree === vnode) {2290 parentComponent.vnode.el = el;2291 updateHOCHostEl(parentComponent, el);2292 }2293 // invoke @suspense event2294 const onSuspense = vnode.props && vnode.props.onSuspense;2295 if (isFunction(onSuspense)) {2296 onSuspense();2297 }2298 }2299 function processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {2300 if (n1 == null) {2301 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG);2302 }2303 else {2304 const instance = (n2.component = n1.component);2305 if (shouldUpdateComponent(n1, n2, optimized)) {2306 if (2307 instance.asyncDep &&2308 !instance.asyncResolved) {2309 // async & still pending - just update props and slots2310 // since the component's reactive effect for render isn't set-up yet2311 {2312 pushWarningContext(n2);2313 }2314 updateComponentPreRender(instance, n2);2315 {2316 popWarningContext();2317 }2318 return;2319 }2320 else {2321 // normal update2322 instance.next = n2;2323 // instance.update is the reactive effect runner.2324 instance.update();2325 }2326 }2327 else {2328 // no update needed. just copy over properties2329 n2.component = n1.component;2330 n2.el = n1.el;2331 }2332 }2333 if (n2.ref !== null && parentComponent !== null) {2334 setRef(n2.ref, n1 && n1.ref, parentComponent, n2.component.renderProxy);2335 }2336 }2337 function mountComponent(initialVNode, container, anchor, parentComponent, parentSuspense, isSVG) {2338 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent));2339 {2340 pushWarningContext(initialVNode);2341 }2342 // resolve props and slots for setup context2343 const propsOptions = initialVNode.type.props;2344 resolveProps(instance, initialVNode.props, propsOptions);2345 resolveSlots(instance, initialVNode.children);2346 // setup stateful logic2347 if (initialVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {2348 setupStatefulComponent(instance, parentSuspense);2349 }2350 // setup() is async. This component relies on async logic to be resolved2351 // before proceeding2352 if ( instance.asyncDep) {2353 if (!parentSuspense) {2354 // TODO handle this properly2355 throw new Error('Async component without a suspense boundary!');2356 }2357 // parent suspense already resolved, need to re-suspense2358 // use queueJob so it's handled synchronously after patching the current2359 // suspense tree2360 if (parentSuspense.isResolved) {2361 queueJob(() => {2362 restartSuspense(parentSuspense);2363 });2364 }2365 parentSuspense.deps++;2366 instance.asyncDep2367 .catch(err => {2368 handleError(err, instance, 0 /* SETUP_FUNCTION */);2369 })2370 .then(asyncSetupResult => {2371 // component may be unmounted before resolve2372 if (!instance.isUnmounted && !parentSuspense.isUnmounted) {2373 retryAsyncComponent(instance, asyncSetupResult, parentSuspense, isSVG);2374 }2375 });2376 // give it a placeholder2377 const placeholder = (instance.subTree = createVNode(Comment));2378 processCommentNode(null, placeholder, container, anchor);2379 initialVNode.el = placeholder.el;2380 return;2381 }2382 setupRenderEffect(instance, parentSuspense, initialVNode, container, anchor, isSVG);2383 {2384 popWarningContext();2385 }2386 }2387 function retryAsyncComponent(instance, asyncSetupResult, parentSuspense, isSVG) {2388 parentSuspense.deps--;2389 // retry from this component2390 instance.asyncResolved = true;2391 const { vnode } = instance;2392 {2393 pushWarningContext(vnode);2394 }2395 handleSetupResult(instance, asyncSetupResult, parentSuspense);2396 setupRenderEffect(instance, parentSuspense, vnode,2397 // component may have been moved before resolve2398 hostParentNode(instance.subTree.el), getNextHostNode(instance.subTree), isSVG);2399 updateHOCHostEl(instance, vnode.el);2400 {2401 popWarningContext();2402 }2403 if (parentSuspense.deps === 0) {2404 resolveSuspense(parentSuspense);2405 }2406 }2407 function setupRenderEffect(instance, parentSuspense, initialVNode, container, anchor, isSVG) {2408 // create reactive effect for rendering2409 let mounted = false;2410 instance.update = effect(function componentEffect() {2411 if (!mounted) {2412 const subTree = (instance.subTree = renderComponentRoot(instance));2413 // beforeMount hook2414 if (instance.bm !== null) {2415 invokeHooks(instance.bm);2416 }2417 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);2418 initialVNode.el = subTree.el;2419 // mounted hook2420 if (instance.m !== null) {2421 queuePostRenderEffect(instance.m, parentSuspense);2422 }2423 mounted = true;2424 }2425 else {2426 // updateComponent2427 // This is triggered by mutation of component's own state (next: null)2428 // OR parent calling processComponent (next: HostVNode)2429 const { next } = instance;2430 {2431 pushWarningContext(next || instance.vnode);2432 }2433 if (next !== null) {2434 updateComponentPreRender(instance, next);2435 }2436 const prevTree = instance.subTree;2437 const nextTree = (instance.subTree = renderComponentRoot(instance));2438 // beforeUpdate hook2439 if (instance.bu !== null) {2440 invokeHooks(instance.bu);2441 }2442 // reset refs2443 // only needed if previous patch had refs2444 if (instance.refs !== EMPTY_OBJ) {2445 instance.refs = {};2446 }2447 patch(prevTree, nextTree,2448 // parent may have changed if it's in a portal2449 hostParentNode(prevTree.el),2450 // anchor may have changed if it's in a fragment2451 getNextHostNode(prevTree), instance, parentSuspense, isSVG);2452 instance.vnode.el = nextTree.el;2453 if (next === null) {2454 // self-triggered update. In case of HOC, update parent component2455 // vnode el. HOC is indicated by parent instance's subTree pointing2456 // to child component's vnode2457 updateHOCHostEl(instance, nextTree.el);2458 }2459 // updated hook2460 if (instance.u !== null) {2461 queuePostRenderEffect(instance.u, parentSuspense);2462 }2463 {2464 popWarningContext();2465 }2466 }2467 }, createDevEffectOptions(instance) );2468 }2469 function updateComponentPreRender(instance, nextVNode) {2470 nextVNode.component = instance;2471 instance.vnode = nextVNode;2472 instance.next = null;2473 resolveProps(instance, nextVNode.props, nextVNode.type.props);2474 resolveSlots(instance, nextVNode.children);2475 }2476 function updateHOCHostEl({ vnode, parent }, el) {2477 while (parent && parent.subTree === vnode) {2478 (vnode = parent.vnode).el = el;2479 parent = parent.parent;2480 }2481 } ...

Full Screen

Full Screen

vue.runtime.esm.js

Source:vue.runtime.esm.js Github

copy

Full Screen

...3364}3365const prodEffectOptions = {3366 scheduler: queueJob3367};3368function createDevEffectOptions(instance) {3369 return {3370 scheduler: queueJob,3371 onTrack: instance.rtc ? e => invokeArrayFns(instance.rtc, e) : void 0,3372 onTrigger: instance.rtg ? e => invokeArrayFns(instance.rtg, e) : void 03373 };3374}3375function setupRenderEffect(instance) {3376 // create reactive effect for rendering3377 instance.update = effect(function componentEffect() {3378 if (!instance.isMounted) {3379 instance.render && instance.render.call(instance.proxy);3380 patch(instance);3381 }3382 else {3383 instance.render && instance.render.call(instance.proxy);3384 // updateComponent3385 const { bu, u } = instance;3386 // beforeUpdate hook3387 if (bu) {3388 invokeArrayFns(bu);3389 }3390 patch(instance);3391 // updated hook3392 if (u) {3393 queuePostRenderEffect$1(u);3394 }3395 }3396 }, (process.env.NODE_ENV !== 'production') ? createDevEffectOptions(instance) : prodEffectOptions);3397}3398function unmountComponent(instance) {3399 const { bum, effects, update, um } = instance;3400 // beforeUnmount hook3401 if (bum) {3402 invokeArrayFns(bum);3403 }3404 if (effects) {3405 for (let i = 0; i < effects.length; i++) {3406 stop(effects[i]);3407 }3408 }3409 // update may be null if a component is unmounted before its async3410 // setup has resolved. ...

Full Screen

Full Screen

runtime-core.cjs.js

Source:runtime-core.cjs.js Github

copy

Full Screen

...1223 fallback: normalizeVNode(null)1224 };1225 }1226}1227function createDevEffectOptions(instance) {1228 return {1229 scheduler: queueJob,1230 onTrack: instance.rtc ? e => invokeHooks(instance.rtc, e) : void 0,1231 onTrigger: instance.rtg ? e => invokeHooks(instance.rtg, e) : void 01232 };1233}1234function isSameType$1(n1, n2) {1235 return n1.type === n2.type && n1.key === n2.key;1236}1237function invokeHooks(hooks, arg) {1238 for (let i = 0; i < hooks.length; i++) {1239 hooks[i](arg);1240 }1241}1242function queuePostRenderEffect(fn, suspense) {1243 if (suspense !== null && !suspense.isResolved) {1244 if (isArray(fn)) {1245 suspense.effects.push(...fn);1246 }1247 else {1248 suspense.effects.push(fn);1249 }1250 }1251 else {1252 queuePostFlushCb(fn);1253 }1254}1255/**1256 * The createRenderer function accepts two generic arguments:1257 * HostNode and HostElement, corresponding to Node and Element types in the1258 * host environment. For example, for runtime-dom, HostNode would be the DOM1259 * `Node` interface and HostElement would be the DOM `Element` interface.1260 *1261 * Custom renderers can pass in the platform specific types like this:1262 *1263 * ``` js1264 * const { render, createApp } = createRenderer<Node, Element>({1265 * patchProp,1266 * ...nodeOps1267 * })1268 * ```1269 */1270function createRenderer(options) {1271 const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, querySelector: hostQuerySelector } = options;1272 function patch(n1, // null means this is a mount1273 n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, optimized = false) {1274 // patching & not same type, unmount old tree1275 if (n1 != null && !isSameType$1(n1, n2)) {1276 anchor = getNextHostNode(n1);1277 unmount(n1, parentComponent, parentSuspense, true);1278 n1 = null;1279 }1280 const { type, shapeFlag } = n2;1281 switch (type) {1282 case Text:1283 processText(n1, n2, container, anchor);1284 break;1285 case Comment:1286 processCommentNode(n1, n2, container, anchor);1287 break;1288 case Fragment:1289 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1290 break;1291 case Portal:1292 processPortal(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1293 break;1294 case Suspense:1295 {1296 processSuspense(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1297 }1298 break;1299 default:1300 if (shapeFlag & 1 /* ELEMENT */) {1301 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1302 }1303 else if (shapeFlag & 6 /* COMPONENT */) {1304 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1305 }1306 else {1307 warn('Invalid HostVNode type:', n2.type, `(${typeof n2.type})`);1308 }1309 }1310 }1311 function processText(n1, n2, container, anchor) {1312 if (n1 == null) {1313 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);1314 }1315 else {1316 const el = (n2.el = n1.el);1317 if (n2.children !== n1.children) {1318 hostSetText(el, n2.children);1319 }1320 }1321 }1322 function processCommentNode(n1, n2, container, anchor) {1323 if (n1 == null) {1324 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);1325 }1326 else {1327 // there's no support for dynamic comments1328 n2.el = n1.el;1329 }1330 }1331 function processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1332 if (n1 == null) {1333 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG);1334 }1335 else {1336 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized);1337 }1338 if (n2.ref !== null && parentComponent !== null) {1339 setRef(n2.ref, n1 && n1.ref, parentComponent, n2.el);1340 }1341 }1342 function mountElement(vnode, container, anchor, parentComponent, parentSuspense, isSVG) {1343 const tag = vnode.type;1344 isSVG = isSVG || tag === 'svg';1345 const el = (vnode.el = hostCreateElement(tag, isSVG));1346 const { props, shapeFlag } = vnode;1347 if (props != null) {1348 for (const key in props) {1349 if (isReservedProp(key))1350 continue;1351 hostPatchProp(el, key, props[key], null, isSVG);1352 }1353 if (props.vnodeBeforeMount != null) {1354 invokeDirectiveHook(props.vnodeBeforeMount, parentComponent, vnode);1355 }1356 }1357 if (shapeFlag & 8 /* TEXT_CHILDREN */) {1358 hostSetElementText(el, vnode.children);1359 }1360 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1361 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG);1362 }1363 hostInsert(el, container, anchor);1364 if (props != null && props.vnodeMounted != null) {1365 queuePostRenderEffect(() => {1366 invokeDirectiveHook(props.vnodeMounted, parentComponent, vnode);1367 }, parentSuspense);1368 }1369 }1370 function mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, start = 0) {1371 for (let i = start; i < children.length; i++) {1372 const child = (children[i] = normalizeVNode(children[i]));1373 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG);1374 }1375 }1376 function patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized) {1377 const el = (n2.el = n1.el);1378 const { patchFlag, dynamicChildren } = n2;1379 const oldProps = (n1 && n1.props) || EMPTY_OBJ;1380 const newProps = n2.props || EMPTY_OBJ;1381 if (newProps.vnodeBeforeUpdate != null) {1382 invokeDirectiveHook(newProps.vnodeBeforeUpdate, parentComponent, n2, n1);1383 }1384 if (patchFlag > 0) {1385 // the presence of a patchFlag means this element's render code was1386 // generated by the compiler and can take the fast path.1387 // in this path old node and new node are guaranteed to have the same shape1388 // (i.e. at the exact same position in the source template)1389 if (patchFlag & 16 /* FULL_PROPS */) {1390 // element props contain dynamic keys, full diff needed1391 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);1392 }1393 else {1394 // class1395 // this flag is matched when the element has dynamic class bindings.1396 if (patchFlag & 2 /* CLASS */) {1397 if (oldProps.class !== newProps.class) {1398 hostPatchProp(el, 'class', newProps.class, null, isSVG);1399 }1400 }1401 // style1402 // this flag is matched when the element has dynamic style bindings1403 if (patchFlag & 4 /* STYLE */) {1404 hostPatchProp(el, 'style', newProps.style, oldProps.style, isSVG);1405 }1406 // props1407 // This flag is matched when the element has dynamic prop/attr bindings1408 // other than class and style. The keys of dynamic prop/attrs are saved for1409 // faster iteration.1410 // Note dynamic keys like :[foo]="bar" will cause this optimization to1411 // bail out and go through a full diff because we need to unset the old key1412 if (patchFlag & 8 /* PROPS */) {1413 // if the flag is present then dynamicProps must be non-null1414 const propsToUpdate = n2.dynamicProps;1415 for (let i = 0; i < propsToUpdate.length; i++) {1416 const key = propsToUpdate[i];1417 const prev = oldProps[key];1418 const next = newProps[key];1419 if (prev !== next) {1420 hostPatchProp(el, key, next, prev, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);1421 }1422 }1423 }1424 }1425 // text1426 // This flag is matched when the element has only dynamic text children.1427 // this flag is terminal (i.e. skips children diffing).1428 if (patchFlag & 1 /* TEXT */) {1429 if (n1.children !== n2.children) {1430 hostSetElementText(el, n2.children);1431 }1432 return; // terminal1433 }1434 }1435 else if (!optimized) {1436 // unoptimized, full diff1437 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);1438 }1439 if (dynamicChildren != null) {1440 // children fast path1441 const oldDynamicChildren = n1.dynamicChildren;1442 for (let i = 0; i < dynamicChildren.length; i++) {1443 patch(oldDynamicChildren[i], dynamicChildren[i], el, null, parentComponent, parentSuspense, isSVG, true);1444 }1445 }1446 else if (!optimized) {1447 // full diff1448 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, isSVG);1449 }1450 if (newProps.vnodeUpdated != null) {1451 queuePostRenderEffect(() => {1452 invokeDirectiveHook(newProps.vnodeUpdated, parentComponent, n2, n1);1453 }, parentSuspense);1454 }1455 }1456 function patchProps(el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) {1457 if (oldProps !== newProps) {1458 for (const key in newProps) {1459 if (isReservedProp(key))1460 continue;1461 const next = newProps[key];1462 const prev = oldProps[key];1463 if (next !== prev) {1464 hostPatchProp(el, key, next, prev, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);1465 }1466 }1467 if (oldProps !== EMPTY_OBJ) {1468 for (const key in oldProps) {1469 if (isReservedProp(key))1470 continue;1471 if (!(key in newProps)) {1472 hostPatchProp(el, key, null, null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);1473 }1474 }1475 }1476 }1477 }1478 function processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1479 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateComment(''));1480 const fragmentEndAnchor = (n2.anchor = n11481 ? n1.anchor1482 : hostCreateComment(''));1483 if (n1 == null) {1484 hostInsert(fragmentStartAnchor, container, anchor);1485 hostInsert(fragmentEndAnchor, container, anchor);1486 // a fragment can only have array children1487 // since they are either generated by the compiler, or implicitly created1488 // from arrays.1489 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG);1490 }1491 else {1492 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);1493 }1494 }1495 function processPortal(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1496 const targetSelector = n2.props && n2.props.target;1497 const { patchFlag, shapeFlag, children } = n2;1498 if (n1 == null) {1499 const target = (n2.target = isString(targetSelector)1500 ? hostQuerySelector(targetSelector)1501 : null);1502 if (target != null) {1503 if (shapeFlag & 8 /* TEXT_CHILDREN */) {1504 hostSetElementText(target, children);1505 }1506 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1507 mountChildren(children, target, null, parentComponent, parentSuspense, isSVG);1508 }1509 }1510 else {1511 warn('Invalid Portal target on mount:', target, `(${typeof target})`);1512 }1513 }1514 else {1515 // update content1516 const target = (n2.target = n1.target);1517 if (patchFlag === 1 /* TEXT */) {1518 hostSetElementText(target, children);1519 }1520 else if (!optimized) {1521 patchChildren(n1, n2, target, null, parentComponent, parentSuspense, isSVG);1522 }1523 // target changed1524 if (targetSelector !== (n1.props && n1.props.target)) {1525 const nextTarget = (n2.target = isString(targetSelector)1526 ? hostQuerySelector(targetSelector)1527 : null);1528 if (nextTarget != null) {1529 // move content1530 if (shapeFlag & 8 /* TEXT_CHILDREN */) {1531 hostSetElementText(target, '');1532 hostSetElementText(nextTarget, children);1533 }1534 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1535 for (let i = 0; i < children.length; i++) {1536 move(children[i], nextTarget, null);1537 }1538 }1539 }1540 else {1541 warn('Invalid Portal target on update:', target, `(${typeof target})`);1542 }1543 }1544 }1545 // insert an empty node as the placeholder for the portal1546 processCommentNode(n1, n2, container, anchor);1547 }1548 function processSuspense(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1549 if (n1 == null) {1550 mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1551 }1552 else {1553 patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized);1554 }1555 }1556 function mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1557 const hiddenContainer = hostCreateElement('div');1558 const suspense = (n2.suspense = createSuspenseBoundary(n2, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, optimized));1559 const { content, fallback } = normalizeSuspenseChildren(n2);1560 suspense.subTree = content;1561 suspense.fallbackTree = fallback;1562 // start mounting the content subtree in an off-dom container1563 patch(null, content, hiddenContainer, null, parentComponent, suspense, isSVG, optimized);1564 // now check if we have encountered any async deps1565 if (suspense.deps > 0) {1566 // mount the fallback tree1567 patch(null, fallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context1568 isSVG, optimized);1569 n2.el = fallback.el;1570 }1571 else {1572 // Suspense has no async deps. Just resolve.1573 resolveSuspense(suspense);1574 }1575 }1576 function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized) {1577 const suspense = (n2.suspense = n1.suspense);1578 suspense.vnode = n2;1579 const { content, fallback } = normalizeSuspenseChildren(n2);1580 const oldSubTree = suspense.subTree;1581 const oldFallbackTree = suspense.fallbackTree;1582 if (!suspense.isResolved) {1583 patch(oldSubTree, content, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized);1584 if (suspense.deps > 0) {1585 // still pending. patch the fallback tree.1586 patch(oldFallbackTree, fallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context1587 isSVG, optimized);1588 n2.el = fallback.el;1589 }1590 // If deps somehow becomes 0 after the patch it means the patch caused an1591 // async dep component to unmount and removed its dep. It will cause the1592 // suspense to resolve and we don't need to do anything here.1593 }1594 else {1595 // just normal patch inner content as a fragment1596 patch(oldSubTree, content, container, anchor, parentComponent, suspense, isSVG, optimized);1597 n2.el = content.el;1598 }1599 suspense.subTree = content;1600 suspense.fallbackTree = fallback;1601 }1602 function resolveSuspense(suspense) {1603 {1604 if (suspense.isResolved) {1605 throw new Error(`resolveSuspense() is called on an already resolved suspense boundary.`);1606 }1607 if (suspense.isUnmounted) {1608 throw new Error(`resolveSuspense() is called on an already unmounted suspense boundary.`);1609 }1610 }1611 const { vnode, subTree, fallbackTree, effects, parentComponent, container } = suspense;1612 // this is initial anchor on mount1613 let { anchor } = suspense;1614 // unmount fallback tree1615 if (fallbackTree.el) {1616 // if the fallback tree was mounted, it may have been moved1617 // as part of a parent suspense. get the latest anchor for insertion1618 anchor = getNextHostNode(fallbackTree);1619 unmount(fallbackTree, parentComponent, suspense, true);1620 }1621 // move content from off-dom container to actual container1622 move(subTree, container, anchor);1623 const el = (vnode.el = subTree.el);1624 // suspense as the root node of a component...1625 if (parentComponent && parentComponent.subTree === vnode) {1626 parentComponent.vnode.el = el;1627 updateHOCHostEl(parentComponent, el);1628 }1629 // check if there is a pending parent suspense1630 let parent = suspense.parent;1631 let hasUnresolvedAncestor = false;1632 while (parent) {1633 if (!parent.isResolved) {1634 // found a pending parent suspense, merge buffered post jobs1635 // into that parent1636 parent.effects.push(...effects);1637 hasUnresolvedAncestor = true;1638 break;1639 }1640 parent = parent.parent;1641 }1642 // no pending parent suspense, flush all jobs1643 if (!hasUnresolvedAncestor) {1644 queuePostFlushCb(effects);1645 }1646 suspense.isResolved = true;1647 // invoke @resolve event1648 const onResolve = vnode.props && vnode.props.onResolve;1649 if (isFunction(onResolve)) {1650 onResolve();1651 }1652 }1653 function restartSuspense(suspense) {1654 suspense.isResolved = false;1655 const { vnode, subTree, fallbackTree, parentComponent, container, hiddenContainer, isSVG, optimized } = suspense;1656 // move content tree back to the off-dom container1657 const anchor = getNextHostNode(subTree);1658 move(subTree, hiddenContainer, null);1659 // remount the fallback tree1660 patch(null, fallbackTree, container, anchor, parentComponent, null, // fallback tree will not have suspense context1661 isSVG, optimized);1662 const el = (vnode.el = fallbackTree.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 // invoke @suspense event1669 const onSuspense = vnode.props && vnode.props.onSuspense;1670 if (isFunction(onSuspense)) {1671 onSuspense();1672 }1673 }1674 function processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1675 if (n1 == null) {1676 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG);1677 }1678 else {1679 const instance = (n2.component = n1.component);1680 if (shouldUpdateComponent(n1, n2, optimized)) {1681 if (1682 instance.asyncDep &&1683 !instance.asyncResolved) {1684 // async & still pending - just update props and slots1685 // since the component's reactive effect for render isn't set-up yet1686 {1687 pushWarningContext(n2);1688 }1689 updateComponentPreRender(instance, n2);1690 {1691 popWarningContext();1692 }1693 return;1694 }1695 else {1696 // normal update1697 instance.next = n2;1698 // instance.update is the reactive effect runner.1699 instance.update();1700 }1701 }1702 else {1703 // no update needed. just copy over properties1704 n2.component = n1.component;1705 n2.el = n1.el;1706 }1707 }1708 if (n2.ref !== null && parentComponent !== null) {1709 setRef(n2.ref, n1 && n1.ref, parentComponent, n2.component.renderProxy);1710 }1711 }1712 function mountComponent(initialVNode, container, anchor, parentComponent, parentSuspense, isSVG) {1713 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent));1714 {1715 pushWarningContext(initialVNode);1716 }1717 // resolve props and slots for setup context1718 const propsOptions = initialVNode.type.props;1719 resolveProps(instance, initialVNode.props, propsOptions);1720 resolveSlots(instance, initialVNode.children);1721 // setup stateful logic1722 if (initialVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {1723 setupStatefulComponent(instance, parentSuspense);1724 }1725 // setup() is async. This component relies on async logic to be resolved1726 // before proceeding1727 if ( instance.asyncDep) {1728 if (!parentSuspense) {1729 // TODO handle this properly1730 throw new Error('Async component without a suspense boundary!');1731 }1732 // parent suspense already resolved, need to re-suspense1733 // use queueJob so it's handled synchronously after patching the current1734 // suspense tree1735 if (parentSuspense.isResolved) {1736 queueJob(() => {1737 restartSuspense(parentSuspense);1738 });1739 }1740 parentSuspense.deps++;1741 instance.asyncDep1742 .catch(err => {1743 handleError(err, instance, 0 /* SETUP_FUNCTION */);1744 })1745 .then(asyncSetupResult => {1746 // component may be unmounted before resolve1747 if (!instance.isUnmounted && !parentSuspense.isUnmounted) {1748 retryAsyncComponent(instance, asyncSetupResult, parentSuspense, isSVG);1749 }1750 });1751 // give it a placeholder1752 const placeholder = (instance.subTree = createVNode(Comment));1753 processCommentNode(null, placeholder, container, anchor);1754 initialVNode.el = placeholder.el;1755 return;1756 }1757 setupRenderEffect(instance, parentSuspense, initialVNode, container, anchor, isSVG);1758 {1759 popWarningContext();1760 }1761 }1762 function retryAsyncComponent(instance, asyncSetupResult, parentSuspense, isSVG) {1763 parentSuspense.deps--;1764 // retry from this component1765 instance.asyncResolved = true;1766 const { vnode } = instance;1767 {1768 pushWarningContext(vnode);1769 }1770 handleSetupResult(instance, asyncSetupResult, parentSuspense);1771 setupRenderEffect(instance, parentSuspense, vnode, 1772 // component may have been moved before resolve1773 hostParentNode(instance.subTree.el), getNextHostNode(instance.subTree), isSVG);1774 updateHOCHostEl(instance, vnode.el);1775 {1776 popWarningContext();1777 }1778 if (parentSuspense.deps === 0) {1779 resolveSuspense(parentSuspense);1780 }1781 }1782 function setupRenderEffect(instance, parentSuspense, initialVNode, container, anchor, isSVG) {1783 // create reactive effect for rendering1784 let mounted = false;1785 instance.update = reactivity.effect(function componentEffect() {1786 if (!mounted) {1787 const subTree = (instance.subTree = renderComponentRoot(instance));1788 // beforeMount hook1789 if (instance.bm !== null) {1790 invokeHooks(instance.bm);1791 }1792 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);1793 initialVNode.el = subTree.el;1794 // mounted hook1795 if (instance.m !== null) {1796 queuePostRenderEffect(instance.m, parentSuspense);1797 }1798 mounted = true;1799 }1800 else {1801 // updateComponent1802 // This is triggered by mutation of component's own state (next: null)1803 // OR parent calling processComponent (next: HostVNode)1804 const { next } = instance;1805 {1806 pushWarningContext(next || instance.vnode);1807 }1808 if (next !== null) {1809 updateComponentPreRender(instance, next);1810 }1811 const prevTree = instance.subTree;1812 const nextTree = (instance.subTree = renderComponentRoot(instance));1813 // beforeUpdate hook1814 if (instance.bu !== null) {1815 invokeHooks(instance.bu);1816 }1817 // reset refs1818 // only needed if previous patch had refs1819 if (instance.refs !== EMPTY_OBJ) {1820 instance.refs = {};1821 }1822 patch(prevTree, nextTree, 1823 // parent may have changed if it's in a portal1824 hostParentNode(prevTree.el), 1825 // anchor may have changed if it's in a fragment1826 getNextHostNode(prevTree), instance, parentSuspense, isSVG);1827 instance.vnode.el = nextTree.el;1828 if (next === null) {1829 // self-triggered update. In case of HOC, update parent component1830 // vnode el. HOC is indicated by parent instance's subTree pointing1831 // to child component's vnode1832 updateHOCHostEl(instance, nextTree.el);1833 }1834 // updated hook1835 if (instance.u !== null) {1836 queuePostRenderEffect(instance.u, parentSuspense);1837 }1838 {1839 popWarningContext();1840 }1841 }1842 }, createDevEffectOptions(instance) );1843 }1844 function updateComponentPreRender(instance, nextVNode) {1845 nextVNode.component = instance;1846 instance.vnode = nextVNode;1847 instance.next = null;1848 resolveProps(instance, nextVNode.props, nextVNode.type.props);1849 resolveSlots(instance, nextVNode.children);1850 }1851 function updateHOCHostEl({ vnode, parent }, el) {1852 while (parent && parent.subTree === vnode) {1853 (vnode = parent.vnode).el = el;1854 parent = parent.parent;1855 }1856 } ...

Full Screen

Full Screen

runtime-core.esm-bundler.js

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

copy

Full Screen

...1222 fallback: normalizeVNode(null)1223 };1224 }1225}1226function createDevEffectOptions(instance) {1227 return {1228 scheduler: queueJob,1229 onTrack: instance.rtc ? e => invokeHooks(instance.rtc, e) : void 0,1230 onTrigger: instance.rtg ? e => invokeHooks(instance.rtg, e) : void 01231 };1232}1233function isSameType$1(n1, n2) {1234 return n1.type === n2.type && n1.key === n2.key;1235}1236function invokeHooks(hooks, arg) {1237 for (let i = 0; i < hooks.length; i++) {1238 hooks[i](arg);1239 }1240}1241function queuePostRenderEffect(fn, suspense) {1242 if (suspense !== null && !suspense.isResolved) {1243 if (isArray(fn)) {1244 suspense.effects.push(...fn);1245 }1246 else {1247 suspense.effects.push(fn);1248 }1249 }1250 else {1251 queuePostFlushCb(fn);1252 }1253}1254/**1255 * The createRenderer function accepts two generic arguments:1256 * HostNode and HostElement, corresponding to Node and Element types in the1257 * host environment. For example, for runtime-dom, HostNode would be the DOM1258 * `Node` interface and HostElement would be the DOM `Element` interface.1259 *1260 * Custom renderers can pass in the platform specific types like this:1261 *1262 * ``` js1263 * const { render, createApp } = createRenderer<Node, Element>({1264 * patchProp,1265 * ...nodeOps1266 * })1267 * ```1268 */1269function createRenderer(options) {1270 const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, querySelector: hostQuerySelector } = options;1271 function patch(n1, // null means this is a mount1272 n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, optimized = false) {1273 // patching & not same type, unmount old tree1274 if (n1 != null && !isSameType$1(n1, n2)) {1275 anchor = getNextHostNode(n1);1276 unmount(n1, parentComponent, parentSuspense, true);1277 n1 = null;1278 }1279 const { type, shapeFlag } = n2;1280 switch (type) {1281 case Text:1282 processText(n1, n2, container, anchor);1283 break;1284 case Comment:1285 processCommentNode(n1, n2, container, anchor);1286 break;1287 case Fragment:1288 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1289 break;1290 case Portal:1291 processPortal(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1292 break;1293 case Suspense:1294 {1295 processSuspense(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1296 }1297 break;1298 default:1299 if (shapeFlag & 1 /* ELEMENT */) {1300 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1301 }1302 else if (shapeFlag & 6 /* COMPONENT */) {1303 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1304 }1305 else {1306 warn('Invalid HostVNode type:', n2.type, `(${typeof n2.type})`);1307 }1308 }1309 }1310 function processText(n1, n2, container, anchor) {1311 if (n1 == null) {1312 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);1313 }1314 else {1315 const el = (n2.el = n1.el);1316 if (n2.children !== n1.children) {1317 hostSetText(el, n2.children);1318 }1319 }1320 }1321 function processCommentNode(n1, n2, container, anchor) {1322 if (n1 == null) {1323 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);1324 }1325 else {1326 // there's no support for dynamic comments1327 n2.el = n1.el;1328 }1329 }1330 function processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1331 if (n1 == null) {1332 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG);1333 }1334 else {1335 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized);1336 }1337 if (n2.ref !== null && parentComponent !== null) {1338 setRef(n2.ref, n1 && n1.ref, parentComponent, n2.el);1339 }1340 }1341 function mountElement(vnode, container, anchor, parentComponent, parentSuspense, isSVG) {1342 const tag = vnode.type;1343 isSVG = isSVG || tag === 'svg';1344 const el = (vnode.el = hostCreateElement(tag, isSVG));1345 const { props, shapeFlag } = vnode;1346 if (props != null) {1347 for (const key in props) {1348 if (isReservedProp(key))1349 continue;1350 hostPatchProp(el, key, props[key], null, isSVG);1351 }1352 if (props.vnodeBeforeMount != null) {1353 invokeDirectiveHook(props.vnodeBeforeMount, parentComponent, vnode);1354 }1355 }1356 if (shapeFlag & 8 /* TEXT_CHILDREN */) {1357 hostSetElementText(el, vnode.children);1358 }1359 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1360 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG);1361 }1362 hostInsert(el, container, anchor);1363 if (props != null && props.vnodeMounted != null) {1364 queuePostRenderEffect(() => {1365 invokeDirectiveHook(props.vnodeMounted, parentComponent, vnode);1366 }, parentSuspense);1367 }1368 }1369 function mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, start = 0) {1370 for (let i = start; i < children.length; i++) {1371 const child = (children[i] = normalizeVNode(children[i]));1372 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG);1373 }1374 }1375 function patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized) {1376 const el = (n2.el = n1.el);1377 const { patchFlag, dynamicChildren } = n2;1378 const oldProps = (n1 && n1.props) || EMPTY_OBJ;1379 const newProps = n2.props || EMPTY_OBJ;1380 if (newProps.vnodeBeforeUpdate != null) {1381 invokeDirectiveHook(newProps.vnodeBeforeUpdate, parentComponent, n2, n1);1382 }1383 if (patchFlag > 0) {1384 // the presence of a patchFlag means this element's render code was1385 // generated by the compiler and can take the fast path.1386 // in this path old node and new node are guaranteed to have the same shape1387 // (i.e. at the exact same position in the source template)1388 if (patchFlag & 16 /* FULL_PROPS */) {1389 // element props contain dynamic keys, full diff needed1390 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);1391 }1392 else {1393 // class1394 // this flag is matched when the element has dynamic class bindings.1395 if (patchFlag & 2 /* CLASS */) {1396 if (oldProps.class !== newProps.class) {1397 hostPatchProp(el, 'class', newProps.class, null, isSVG);1398 }1399 }1400 // style1401 // this flag is matched when the element has dynamic style bindings1402 if (patchFlag & 4 /* STYLE */) {1403 hostPatchProp(el, 'style', newProps.style, oldProps.style, isSVG);1404 }1405 // props1406 // This flag is matched when the element has dynamic prop/attr bindings1407 // other than class and style. The keys of dynamic prop/attrs are saved for1408 // faster iteration.1409 // Note dynamic keys like :[foo]="bar" will cause this optimization to1410 // bail out and go through a full diff because we need to unset the old key1411 if (patchFlag & 8 /* PROPS */) {1412 // if the flag is present then dynamicProps must be non-null1413 const propsToUpdate = n2.dynamicProps;1414 for (let i = 0; i < propsToUpdate.length; i++) {1415 const key = propsToUpdate[i];1416 const prev = oldProps[key];1417 const next = newProps[key];1418 if (prev !== next) {1419 hostPatchProp(el, key, next, prev, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);1420 }1421 }1422 }1423 }1424 // text1425 // This flag is matched when the element has only dynamic text children.1426 // this flag is terminal (i.e. skips children diffing).1427 if (patchFlag & 1 /* TEXT */) {1428 if (n1.children !== n2.children) {1429 hostSetElementText(el, n2.children);1430 }1431 return; // terminal1432 }1433 }1434 else if (!optimized) {1435 // unoptimized, full diff1436 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);1437 }1438 if (dynamicChildren != null) {1439 // children fast path1440 const oldDynamicChildren = n1.dynamicChildren;1441 for (let i = 0; i < dynamicChildren.length; i++) {1442 patch(oldDynamicChildren[i], dynamicChildren[i], el, null, parentComponent, parentSuspense, isSVG, true);1443 }1444 }1445 else if (!optimized) {1446 // full diff1447 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, isSVG);1448 }1449 if (newProps.vnodeUpdated != null) {1450 queuePostRenderEffect(() => {1451 invokeDirectiveHook(newProps.vnodeUpdated, parentComponent, n2, n1);1452 }, parentSuspense);1453 }1454 }1455 function patchProps(el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) {1456 if (oldProps !== newProps) {1457 for (const key in newProps) {1458 if (isReservedProp(key))1459 continue;1460 const next = newProps[key];1461 const prev = oldProps[key];1462 if (next !== prev) {1463 hostPatchProp(el, key, next, prev, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);1464 }1465 }1466 if (oldProps !== EMPTY_OBJ) {1467 for (const key in oldProps) {1468 if (isReservedProp(key))1469 continue;1470 if (!(key in newProps)) {1471 hostPatchProp(el, key, null, null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);1472 }1473 }1474 }1475 }1476 }1477 function processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1478 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateComment(''));1479 const fragmentEndAnchor = (n2.anchor = n11480 ? n1.anchor1481 : hostCreateComment(''));1482 if (n1 == null) {1483 hostInsert(fragmentStartAnchor, container, anchor);1484 hostInsert(fragmentEndAnchor, container, anchor);1485 // a fragment can only have array children1486 // since they are either generated by the compiler, or implicitly created1487 // from arrays.1488 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG);1489 }1490 else {1491 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);1492 }1493 }1494 function processPortal(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1495 const targetSelector = n2.props && n2.props.target;1496 const { patchFlag, shapeFlag, children } = n2;1497 if (n1 == null) {1498 const target = (n2.target = isString(targetSelector)1499 ? hostQuerySelector(targetSelector)1500 : null);1501 if (target != null) {1502 if (shapeFlag & 8 /* TEXT_CHILDREN */) {1503 hostSetElementText(target, children);1504 }1505 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1506 mountChildren(children, target, null, parentComponent, parentSuspense, isSVG);1507 }1508 }1509 else {1510 warn('Invalid Portal target on mount:', target, `(${typeof target})`);1511 }1512 }1513 else {1514 // update content1515 const target = (n2.target = n1.target);1516 if (patchFlag === 1 /* TEXT */) {1517 hostSetElementText(target, children);1518 }1519 else if (!optimized) {1520 patchChildren(n1, n2, target, null, parentComponent, parentSuspense, isSVG);1521 }1522 // target changed1523 if (targetSelector !== (n1.props && n1.props.target)) {1524 const nextTarget = (n2.target = isString(targetSelector)1525 ? hostQuerySelector(targetSelector)1526 : null);1527 if (nextTarget != null) {1528 // move content1529 if (shapeFlag & 8 /* TEXT_CHILDREN */) {1530 hostSetElementText(target, '');1531 hostSetElementText(nextTarget, children);1532 }1533 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1534 for (let i = 0; i < children.length; i++) {1535 move(children[i], nextTarget, null);1536 }1537 }1538 }1539 else {1540 warn('Invalid Portal target on update:', target, `(${typeof target})`);1541 }1542 }1543 }1544 // insert an empty node as the placeholder for the portal1545 processCommentNode(n1, n2, container, anchor);1546 }1547 function processSuspense(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1548 if (n1 == null) {1549 mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1550 }1551 else {1552 patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized);1553 }1554 }1555 function mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1556 const hiddenContainer = hostCreateElement('div');1557 const suspense = (n2.suspense = createSuspenseBoundary(n2, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, optimized));1558 const { content, fallback } = normalizeSuspenseChildren(n2);1559 suspense.subTree = content;1560 suspense.fallbackTree = fallback;1561 // start mounting the content subtree in an off-dom container1562 patch(null, content, hiddenContainer, null, parentComponent, suspense, isSVG, optimized);1563 // now check if we have encountered any async deps1564 if (suspense.deps > 0) {1565 // mount the fallback tree1566 patch(null, fallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context1567 isSVG, optimized);1568 n2.el = fallback.el;1569 }1570 else {1571 // Suspense has no async deps. Just resolve.1572 resolveSuspense(suspense);1573 }1574 }1575 function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized) {1576 const suspense = (n2.suspense = n1.suspense);1577 suspense.vnode = n2;1578 const { content, fallback } = normalizeSuspenseChildren(n2);1579 const oldSubTree = suspense.subTree;1580 const oldFallbackTree = suspense.fallbackTree;1581 if (!suspense.isResolved) {1582 patch(oldSubTree, content, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized);1583 if (suspense.deps > 0) {1584 // still pending. patch the fallback tree.1585 patch(oldFallbackTree, fallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context1586 isSVG, optimized);1587 n2.el = fallback.el;1588 }1589 // If deps somehow becomes 0 after the patch it means the patch caused an1590 // async dep component to unmount and removed its dep. It will cause the1591 // suspense to resolve and we don't need to do anything here.1592 }1593 else {1594 // just normal patch inner content as a fragment1595 patch(oldSubTree, content, container, anchor, parentComponent, suspense, isSVG, optimized);1596 n2.el = content.el;1597 }1598 suspense.subTree = content;1599 suspense.fallbackTree = fallback;1600 }1601 function resolveSuspense(suspense) {1602 {1603 if (suspense.isResolved) {1604 throw new Error(`resolveSuspense() is called on an already resolved suspense boundary.`);1605 }1606 if (suspense.isUnmounted) {1607 throw new Error(`resolveSuspense() is called on an already unmounted suspense boundary.`);1608 }1609 }1610 const { vnode, subTree, fallbackTree, effects, parentComponent, container } = suspense;1611 // this is initial anchor on mount1612 let { anchor } = suspense;1613 // unmount fallback tree1614 if (fallbackTree.el) {1615 // if the fallback tree was mounted, it may have been moved1616 // as part of a parent suspense. get the latest anchor for insertion1617 anchor = getNextHostNode(fallbackTree);1618 unmount(fallbackTree, parentComponent, suspense, true);1619 }1620 // move content from off-dom container to actual container1621 move(subTree, container, anchor);1622 const el = (vnode.el = subTree.el);1623 // suspense as the root node of a component...1624 if (parentComponent && parentComponent.subTree === vnode) {1625 parentComponent.vnode.el = el;1626 updateHOCHostEl(parentComponent, el);1627 }1628 // check if there is a pending parent suspense1629 let parent = suspense.parent;1630 let hasUnresolvedAncestor = false;1631 while (parent) {1632 if (!parent.isResolved) {1633 // found a pending parent suspense, merge buffered post jobs1634 // into that parent1635 parent.effects.push(...effects);1636 hasUnresolvedAncestor = true;1637 break;1638 }1639 parent = parent.parent;1640 }1641 // no pending parent suspense, flush all jobs1642 if (!hasUnresolvedAncestor) {1643 queuePostFlushCb(effects);1644 }1645 suspense.isResolved = true;1646 // invoke @resolve event1647 const onResolve = vnode.props && vnode.props.onResolve;1648 if (isFunction(onResolve)) {1649 onResolve();1650 }1651 }1652 function restartSuspense(suspense) {1653 suspense.isResolved = false;1654 const { vnode, subTree, fallbackTree, parentComponent, container, hiddenContainer, isSVG, optimized } = suspense;1655 // move content tree back to the off-dom container1656 const anchor = getNextHostNode(subTree);1657 move(subTree, hiddenContainer, null);1658 // remount the fallback tree1659 patch(null, fallbackTree, container, anchor, parentComponent, null, // fallback tree will not have suspense context1660 isSVG, optimized);1661 const el = (vnode.el = fallbackTree.el);1662 // suspense as the root node of a component...1663 if (parentComponent && parentComponent.subTree === vnode) {1664 parentComponent.vnode.el = el;1665 updateHOCHostEl(parentComponent, el);1666 }1667 // invoke @suspense event1668 const onSuspense = vnode.props && vnode.props.onSuspense;1669 if (isFunction(onSuspense)) {1670 onSuspense();1671 }1672 }1673 function processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) {1674 if (n1 == null) {1675 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG);1676 }1677 else {1678 const instance = (n2.component = n1.component);1679 if (shouldUpdateComponent(n1, n2, optimized)) {1680 if (1681 instance.asyncDep &&1682 !instance.asyncResolved) {1683 // async & still pending - just update props and slots1684 // since the component's reactive effect for render isn't set-up yet1685 {1686 pushWarningContext(n2);1687 }1688 updateComponentPreRender(instance, n2);1689 {1690 popWarningContext();1691 }1692 return;1693 }1694 else {1695 // normal update1696 instance.next = n2;1697 // instance.update is the reactive effect runner.1698 instance.update();1699 }1700 }1701 else {1702 // no update needed. just copy over properties1703 n2.component = n1.component;1704 n2.el = n1.el;1705 }1706 }1707 if (n2.ref !== null && parentComponent !== null) {1708 setRef(n2.ref, n1 && n1.ref, parentComponent, n2.component.renderProxy);1709 }1710 }1711 function mountComponent(initialVNode, container, anchor, parentComponent, parentSuspense, isSVG) {1712 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent));1713 {1714 pushWarningContext(initialVNode);1715 }1716 // resolve props and slots for setup context1717 const propsOptions = initialVNode.type.props;1718 resolveProps(instance, initialVNode.props, propsOptions);1719 resolveSlots(instance, initialVNode.children);1720 // setup stateful logic1721 if (initialVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {1722 setupStatefulComponent(instance, parentSuspense);1723 }1724 // setup() is async. This component relies on async logic to be resolved1725 // before proceeding1726 if ( instance.asyncDep) {1727 if (!parentSuspense) {1728 // TODO handle this properly1729 throw new Error('Async component without a suspense boundary!');1730 }1731 // parent suspense already resolved, need to re-suspense1732 // use queueJob so it's handled synchronously after patching the current1733 // suspense tree1734 if (parentSuspense.isResolved) {1735 queueJob(() => {1736 restartSuspense(parentSuspense);1737 });1738 }1739 parentSuspense.deps++;1740 instance.asyncDep1741 .catch(err => {1742 handleError(err, instance, 0 /* SETUP_FUNCTION */);1743 })1744 .then(asyncSetupResult => {1745 // component may be unmounted before resolve1746 if (!instance.isUnmounted && !parentSuspense.isUnmounted) {1747 retryAsyncComponent(instance, asyncSetupResult, parentSuspense, isSVG);1748 }1749 });1750 // give it a placeholder1751 const placeholder = (instance.subTree = createVNode(Comment));1752 processCommentNode(null, placeholder, container, anchor);1753 initialVNode.el = placeholder.el;1754 return;1755 }1756 setupRenderEffect(instance, parentSuspense, initialVNode, container, anchor, isSVG);1757 {1758 popWarningContext();1759 }1760 }1761 function retryAsyncComponent(instance, asyncSetupResult, parentSuspense, isSVG) {1762 parentSuspense.deps--;1763 // retry from this component1764 instance.asyncResolved = true;1765 const { vnode } = instance;1766 {1767 pushWarningContext(vnode);1768 }1769 handleSetupResult(instance, asyncSetupResult, parentSuspense);1770 setupRenderEffect(instance, parentSuspense, vnode, 1771 // component may have been moved before resolve1772 hostParentNode(instance.subTree.el), getNextHostNode(instance.subTree), isSVG);1773 updateHOCHostEl(instance, vnode.el);1774 {1775 popWarningContext();1776 }1777 if (parentSuspense.deps === 0) {1778 resolveSuspense(parentSuspense);1779 }1780 }1781 function setupRenderEffect(instance, parentSuspense, initialVNode, container, anchor, isSVG) {1782 // create reactive effect for rendering1783 let mounted = false;1784 instance.update = effect(function componentEffect() {1785 if (!mounted) {1786 const subTree = (instance.subTree = renderComponentRoot(instance));1787 // beforeMount hook1788 if (instance.bm !== null) {1789 invokeHooks(instance.bm);1790 }1791 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);1792 initialVNode.el = subTree.el;1793 // mounted hook1794 if (instance.m !== null) {1795 queuePostRenderEffect(instance.m, parentSuspense);1796 }1797 mounted = true;1798 }1799 else {1800 // updateComponent1801 // This is triggered by mutation of component's own state (next: null)1802 // OR parent calling processComponent (next: HostVNode)1803 const { next } = instance;1804 {1805 pushWarningContext(next || instance.vnode);1806 }1807 if (next !== null) {1808 updateComponentPreRender(instance, next);1809 }1810 const prevTree = instance.subTree;1811 const nextTree = (instance.subTree = renderComponentRoot(instance));1812 // beforeUpdate hook1813 if (instance.bu !== null) {1814 invokeHooks(instance.bu);1815 }1816 // reset refs1817 // only needed if previous patch had refs1818 if (instance.refs !== EMPTY_OBJ) {1819 instance.refs = {};1820 }1821 patch(prevTree, nextTree, 1822 // parent may have changed if it's in a portal1823 hostParentNode(prevTree.el), 1824 // anchor may have changed if it's in a fragment1825 getNextHostNode(prevTree), instance, parentSuspense, isSVG);1826 instance.vnode.el = nextTree.el;1827 if (next === null) {1828 // self-triggered update. In case of HOC, update parent component1829 // vnode el. HOC is indicated by parent instance's subTree pointing1830 // to child component's vnode1831 updateHOCHostEl(instance, nextTree.el);1832 }1833 // updated hook1834 if (instance.u !== null) {1835 queuePostRenderEffect(instance.u, parentSuspense);1836 }1837 {1838 popWarningContext();1839 }1840 }1841 }, createDevEffectOptions(instance) );1842 }1843 function updateComponentPreRender(instance, nextVNode) {1844 nextVNode.component = instance;1845 instance.vnode = nextVNode;1846 instance.next = null;1847 resolveProps(instance, nextVNode.props, nextVNode.type.props);1848 resolveSlots(instance, nextVNode.children);1849 }1850 function updateHOCHostEl({ vnode, parent }, el) {1851 while (parent && parent.subTree === vnode) {1852 (vnode = parent.vnode).el = el;1853 parent = parent.parent;1854 }1855 } ...

Full Screen

Full Screen

createApp.js

Source:createApp.js Github

copy

Full Screen

...826 {827 popWarningContext();828 }829 }830 }, createDevEffectOptions(instance) );831 };832 const updateComponentPreRender = (instance, nextVNode, optimized) => {833 nextVNode.component = instance;834 const prevProps = instance.vnode.props;835 instance.vnode = nextVNode;836 instance.next = null;837 updateProps(instance, nextVNode.props, prevProps, optimized);838 updateSlots(instance, nextVNode.children);839 // props update may have triggered pre-flush watchers.840 // flush them before the render update.841 flushPreFlushCbs(undefined, instance.update);842 };843 const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized = false) => {844 const c1 = n1 && n1.children;...

Full Screen

Full Screen

react.js

Source:react.js Github

copy

Full Screen

...1135 {1136 popWarningContext();1137 }1138 }1139 }, createDevEffectOptions(instance) );1140};1141 function createDevEffectOptions(instance) {1142 return {1143 scheduler: queueJob,1144 allowRecurse: true,1145 onTrack: instance.rtc ? e => invokeArrayFns(instance.rtc, e) : void 0,1146 onTrigger: instance.rtg ? e => invokeArrayFns(instance.rtg, e) : void 01147 };1148 }1149/*1150* computed1151*/1152function applyOptions(instance, options, deferredData = [], deferredWatch = [], asMixin = false) {1153 // ...1154 if (computedOptions) {1155 for (const key in computedOptions) {...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const { createDevEffectOptions } = require('playwright/lib/server/playwright');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch(createDevEffectOptions());5 const context = await browser.newContext();6 const page = await context.newPage();7 await browser.close();8})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const playwright = require('playwright');2const { createDevEffectOptions } = require('playwright/lib/server/devtoolsServer');3const { chromium } = playwright;4(async () => {5 const browser = await chromium.launch();6 const context = await browser.newContext();7 const page = await context.newPage();8 const devEffectOptions = createDevEffectOptions({9 });10 await page.close();11 await context.close();12 await browser.close();13})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { createDevEffectOptions } = require('playwright/lib/server/browserType');2const { chromium } = require('playwright');3const browser = await chromium.launch(createDevEffectOptions({ slowMo: 1000 }));4const context = await browser.newContext();5const page = await context.newPage();6await page.screenshot({ path: 'example.png' });7await browser.close();

Full Screen

Using AI Code Generation

copy

Full Screen

1import { createDevEffectOptions } from "playwright-core/lib/server/supplements/recorder/recorderUtils";2const devEffectOptions = createDevEffectOptions();3const devEffectOptions = createDevEffectOptions({ isRecording: true });4const devEffectOptions = createDevEffectOptions({ isRecording: true, isEditing: true });5const devEffectOptions = createDevEffectOptions({ isRecording: true, isEditing: true, isPlaying: true });6const devEffectOptions = createDevEffectOptions({ isRecording: true, isEditing: true, isPlaying: true, isPaused: true });7import { createDevEffectOptions } from "playwright-core/lib/server/supplements/recorder/recorderUtils";8const devEffectOptions = createDevEffectOptions();9const devEffectOptions = createDevEffectOptions({ isRecording: true });10const devEffectOptions = createDevEffectOptions({ isRecording: true, isEditing: true });11const devEffectOptions = createDevEffectOptions({ isRecording: true, isEditing: true, isPlaying: true });12const devEffectOptions = createDevEffectOptions({ isRecording: true, isEditing: true, isPlaying: true, isPaused: true });13import { createDevEffectOptions } from "playwright-core/lib/server/supplements/recorder/recorderUtils";14const devEffectOptions = createDevEffectOptions();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { createDevEffectOptions } = require('playwright/lib/server/effect');2const { createPlaywright } = require('playwright');3const playwright = createPlaywright();4const browser = await playwright.chromium.launch();5const context = await browser.newContext();6const page = await context.newPage();7const devEffectOptions = createDevEffectOptions({8 viewport: { width: 100, height: 100 },9});10await page.emulate(devEffectOptions);11await page.screenshot({ path: 'example.png' });12await browser.close();13module.exports = {14 launchOptions: {15 },16 contextOptions: {17 viewport: {18 },19 },20 serverOptions: {21 },22 use: {23 },24};25{26 "scripts": {27 },28 "devDependencies": {29 }30}31I am using jest-playwright-preset to run my tests. I am trying to run tests in headless mode. I have set launchOptions: {headless: true} in jest-playwright.config.js. But it doesn't seem to be working. I am still able to see the browser window opening up. I am using the following versions of the packages:

Full Screen

Using AI Code Generation

copy

Full Screen

1const { createDevEffectOptions } = require('@playwright/test/lib/server/devServer');2const devEffectOptions = createDevEffectOptions({ port: 3000, hostname: 'localhost' });3const { createDevServer } = require('@playwright/test/lib/server/devServer');4const devServer = createDevServer(devEffectOptions);5devServer.start();6devServer.stop();7const { createDevServer } = require('@playwright/test/lib/server/devServer');8const devServer = createDevServer();9devServer.start();10const devEffectOptions = devServer.createDevEffectOptions({ port: 3000, hostname: 'localhost' });11devServer.stop();12const { createDevServer } = require('@playwright/test/lib/server/devServer');13const devServer = createDevServer();14devServer.start();15const devEffectOptions = devServer.createDevEffectOptions({ port: 3000, hostname: 'localhost' });16devServer.start();17devServer.stop();18const { createDevServer } = require('@playwright/test/lib/server/devServer');19const devServer = createDevServer();20devServer.start();21const devEffectOptions = devServer.createDevEffectOptions({ port: 3000, hostname: 'localhost' });22devServer.start();23devServer.stop();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { createDevEffectOptions } = require('playwright/lib/server/playwright');2const { chromium } = require('playwright');3const browser = await chromium.launch(createDevEffectOptions());4await browser.close();5const { createDevEffectOptions } = require('playwright/lib/server/playwright');6const { chromium } = require('playwright');7const browser = await chromium.launch(createDevEffectOptions());8await browser.close();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { createDevEffectOptions } = require('playwright-core/lib/server/browserContext');2const { chromium } = require('playwright-core');3const { launch } = require('playwright-core/lib/server/browserType');4const { createBrowserContext } = require('playwright-core/lib/server/chromium');5const { createPlaywright } = require('playwright-core/lib/server/playwright');6const { createPage } = require('playwright-core/lib/server/page');7const { createDeviceDescriptors } = require('playwright-core/lib/server/deviceDescriptors');8const { createPageProxy } = require('playwright-core/lib/server/pageProxy');9const { createSelectOption } = require('playwright-core/lib/server/page');10const { createSelectors } = require('playwright-core/lib/server/selectors');11const { createKeyboard } = require('playwright-core/lib/server/input');12const { createMouse } = require('playwright-core/lib/server/input');13const { createTouchscreen } = require('playwright-core/lib/server/input');14const { createTracing } = require('playwright-core/lib/server/tracing');15const { createCoverage } = require('playwright-core/lib/server/coverage');16const { createDialog } = require('playwright-core/lib/server/dialog');17const { createDownload } = require('playwright-core/lib/server/download');18const { createFileChooser } = require('playwright-core/lib/server/fileChooser');19const { createFrame } = require('playwright-core/lib/server/frame');20const { createFrameTree } = require('playwright-core/lib/server/frameTree');21const { createWorker } = require('playwright-core/lib/server/worker');22const { createNetworkManager } = require('playwright-core/lib/server/network');23const { createNetworkManagerInstrumentation } = require('playwright-core/lib/server/network');24const { createBrowserServer } = require('playwright-core/lib/server/browserServer');25const { createWebSocketTransport } = require('playwright-core/lib/server/webSocketTransport');26const { createHttpServer } = require('playwright-core/lib/server/httpServer');27const { createRouteHandler } = require('playwright-core/lib/server/route');28const { createSocketServer } = require('playwright-core/lib/server/socketServer');29const { createPipeTransport } = require('playwright-core/lib/server/pipeTransport');30const { createProcessLauncher } = require('playwright-core/lib/server/processLauncher');31const { createPlaywrightServer } = require('

Full Screen

Using AI Code Generation

copy

Full Screen

1const { createDevEffectOptions } = require('playwright-core/lib/server/supplements/recorder/playwrightDevtoolsProtocol');2const devEffectOptions = createDevEffectOptions();3console.log(devEffectOptions);4const { createDevEffectOptions } = require('playwright-core/lib/server/supplements/recorder/playwrightDevtoolsProtocol');5const devEffectOptions = createDevEffectOptions();6console.log(devEffectOptions);7const { createDevEffectOptions } = require('playwright-core/lib/server/supplements/recorder/playwrightDevtoolsProtocol');8const devEffectOptions = createDevEffectOptions();9console.log(devEffectOptions);10const { createDevEffectOptions } = require('playwright-core/lib/server/supplements/recorder/playwrightDevtoolsProtocol');11const devEffectOptions = createDevEffectOptions();12console.log(devEffectOptions);13const { createDevEffectOptions } = require('playwright-core/lib/server/supplements/recorder/playwrightDevtoolsProtocol');14const devEffectOptions = createDevEffectOptions();15console.log(devEffectOptions);16const { createDevEffectOptions } = require('playwright-core/lib/server/supplements/recorder/playwrightDevtoolsProtocol');17const devEffectOptions = createDevEffectOptions();18console.log(devEffectOptions);19const { createDevEffectOptions } = require('playwright-core/lib/server/supplements/recorder/playwrightDevtoolsProtocol');20const devEffectOptions = createDevEffectOptions();21console.log(devEffectOptions);22const { createDevEffectOptions } = require('playwright-core/lib/server/supplements/recorder/playwrightDevtoolsProtocol');23const devEffectOptions = createDevEffectOptions();24console.log(devEffectOptions);

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