How to use createForLoopParams method in Playwright Internal

Best JavaScript code snippet using playwright-internal

compiler-dom.global.js

Source:compiler-dom.global.js Github

copy

Full Screen

...2707 childBlock.isBlock = true;2708 helper(OPEN_BLOCK);2709 helper(CREATE_BLOCK);2710 }2711 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));2712 };2713 });2714 });2715 // target-agnostic transform used for both Client and SSR2716 function processFor(node, dir, context, processCodegen) {2717 if (!dir.exp) {2718 context.onError(createCompilerError(36 /* X_V_FOR_NO_EXPRESSION */, dir.loc));2719 return;2720 }2721 const parseResult = parseForExpression(2722 // can only be simple expression because vFor transform is applied2723 // before expression transform.2724 dir.exp);2725 if (!parseResult) {2726 context.onError(createCompilerError(37 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));2727 return;2728 }2729 const { addIdentifiers, removeIdentifiers, scopes } = context;2730 const { source, value, key, index } = parseResult;2731 const forNode = {2732 type: 11 /* FOR */,2733 loc: dir.loc,2734 source,2735 valueAlias: value,2736 keyAlias: key,2737 objectIndexAlias: index,2738 parseResult,2739 children: node.tagType === 3 /* TEMPLATE */ ? node.children : [node]2740 };2741 context.replaceNode(forNode);2742 // bookkeeping2743 scopes.vFor++;2744 const onExit = processCodegen && processCodegen(forNode);2745 return () => {2746 scopes.vFor--;2747 if (onExit)2748 onExit();2749 };2750 }2751 const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;2752 // This regex doesn't cover the case if key or index aliases have destructuring,2753 // but those do not make sense in the first place, so this works in practice.2754 const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;2755 const stripParensRE = /^\(|\)$/g;2756 function parseForExpression(input, context) {2757 const loc = input.loc;2758 const exp = input.content;2759 const inMatch = exp.match(forAliasRE);2760 if (!inMatch)2761 return;2762 const [, LHS, RHS] = inMatch;2763 const result = {2764 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),2765 value: undefined,2766 key: undefined,2767 index: undefined2768 };2769 let valueContent = LHS.trim()2770 .replace(stripParensRE, '')2771 .trim();2772 const trimmedOffset = LHS.indexOf(valueContent);2773 const iteratorMatch = valueContent.match(forIteratorRE);2774 if (iteratorMatch) {2775 valueContent = valueContent.replace(forIteratorRE, '').trim();2776 const keyContent = iteratorMatch[1].trim();2777 let keyOffset;2778 if (keyContent) {2779 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);2780 result.key = createAliasExpression(loc, keyContent, keyOffset);2781 }2782 if (iteratorMatch[2]) {2783 const indexContent = iteratorMatch[2].trim();2784 if (indexContent) {2785 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key2786 ? keyOffset + keyContent.length2787 : trimmedOffset + valueContent.length));2788 }2789 }2790 }2791 if (valueContent) {2792 result.value = createAliasExpression(loc, valueContent, trimmedOffset);2793 }2794 return result;2795 }2796 function createAliasExpression(range, content, offset) {2797 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));2798 }2799 function createForLoopParams({ value, key, index }) {2800 const params = [];2801 if (value) {2802 params.push(value);2803 }2804 if (key) {2805 if (!value) {2806 params.push(createSimpleExpression(`_`, false));2807 }2808 params.push(key);2809 }2810 if (index) {2811 if (!key) {2812 if (!value) {2813 params.push(createSimpleExpression(`_`, false));2814 }2815 params.push(createSimpleExpression(`__`, false));2816 }2817 params.push(index);2818 }2819 return params;2820 }2821 const isStaticExp = (p) => p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic;2822 const defaultFallback = createSimpleExpression(`undefined`, false);2823 // A NodeTransform that:2824 // 1. Tracks scope identifiers for scoped slots so that they don't get prefixed2825 // by transformExpression. This is only applied in non-browser builds with2826 // { prefixIdentifiers: true }.2827 // 2. Track v-slot depths so that we know a slot is inside another slot.2828 // Note the exit callback is executed before buildSlots() on the same node,2829 // so only nested slots see positive numbers.2830 const trackSlotScopes = (node, context) => {2831 if (node.type === 1 /* ELEMENT */ &&2832 (node.tagType === 1 /* COMPONENT */ ||2833 node.tagType === 3 /* TEMPLATE */)) {2834 // We are only checking non-empty v-slot here2835 // since we only care about slots that introduce scope variables.2836 const vSlot = findDir(node, 'slot');2837 if (vSlot) {2838 const slotProps = vSlot.exp;2839 context.scopes.vSlot++;2840 return () => {2841 context.scopes.vSlot--;2842 };2843 }2844 }2845 };2846 // A NodeTransform that tracks scope identifiers for scoped slots with v-for.2847 // This transform is only applied in non-browser builds with { prefixIdentifiers: true }2848 const trackVForSlotScopes = (node, context) => {2849 let vFor;2850 if (isTemplateNode(node) &&2851 node.props.some(isVSlot) &&2852 (vFor = findDir(node, 'for'))) {2853 const result = (vFor.parseResult = parseForExpression(vFor.exp));2854 if (result) {2855 const { value, key, index } = result;2856 const { addIdentifiers, removeIdentifiers } = context;2857 value && addIdentifiers(value);2858 key && addIdentifiers(key);2859 index && addIdentifiers(index);2860 return () => {2861 value && removeIdentifiers(value);2862 key && removeIdentifiers(key);2863 index && removeIdentifiers(index);2864 };2865 }2866 }2867 };2868 const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);2869 // Instead of being a DirectiveTransform, v-slot processing is called during2870 // transformElement to build the slots object for a component.2871 function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {2872 const { children, loc } = node;2873 const slotsProperties = [];2874 const dynamicSlots = [];2875 const buildDefaultSlotProperty = (props, children) => createObjectProperty(`default`, buildSlotFn(props, children, loc));2876 // If the slot is inside a v-for or another v-slot, force it to be dynamic2877 // since it likely uses a scope variable.2878 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;2879 // 1. Check for default slot with slotProps on component itself.2880 // <Comp v-slot="{ prop }"/>2881 const onComponentDefaultSlot = findDir(node, 'slot', true);2882 if (onComponentDefaultSlot) {2883 const { arg, exp, loc } = onComponentDefaultSlot;2884 if (arg) {2885 context.onError(createCompilerError(41 /* X_V_SLOT_NAMED_SLOT_ON_COMPONENT */, loc));2886 }2887 slotsProperties.push(buildDefaultSlotProperty(exp, children));2888 }2889 // 2. Iterate through children and check for template slots2890 // <template v-slot:foo="{ prop }">2891 let hasTemplateSlots = false;2892 let hasNamedDefaultSlot = false;2893 const implicitDefaultChildren = [];2894 const seenSlotNames = new Set();2895 for (let i = 0; i < children.length; i++) {2896 const slotElement = children[i];2897 let slotDir;2898 if (!isTemplateNode(slotElement) ||2899 !(slotDir = findDir(slotElement, 'slot', true))) {2900 // not a <template v-slot>, skip.2901 if (slotElement.type !== 3 /* COMMENT */) {2902 implicitDefaultChildren.push(slotElement);2903 }2904 continue;2905 }2906 if (onComponentDefaultSlot) {2907 // already has on-component default slot - this is incorrect usage.2908 context.onError(createCompilerError(42 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));2909 break;2910 }2911 hasTemplateSlots = true;2912 const { children: slotChildren, loc: slotLoc } = slotElement;2913 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;2914 // check if name is dynamic.2915 let staticSlotName;2916 if (isStaticExp(slotName)) {2917 staticSlotName = slotName ? slotName.content : `default`;2918 }2919 else {2920 hasDynamicSlots = true;2921 }2922 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);2923 // check if this slot is conditional (v-if/v-for)2924 let vIf;2925 let vElse;2926 let vFor;2927 if ((vIf = findDir(slotElement, 'if'))) {2928 hasDynamicSlots = true;2929 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));2930 }2931 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {2932 // find adjacent v-if2933 let j = i;2934 let prev;2935 while (j--) {2936 prev = children[j];2937 if (prev.type !== 3 /* COMMENT */) {2938 break;2939 }2940 }2941 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {2942 // remove node2943 children.splice(i, 1);2944 i--;2945 // attach this slot to previous conditional2946 let conditional = dynamicSlots[dynamicSlots.length - 1];2947 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {2948 conditional = conditional.alternate;2949 }2950 conditional.alternate = vElse.exp2951 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)2952 : buildDynamicSlot(slotName, slotFunction);2953 }2954 else {2955 context.onError(createCompilerError(35 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));2956 }2957 }2958 else if ((vFor = findDir(slotElement, 'for'))) {2959 hasDynamicSlots = true;2960 const parseResult = vFor.parseResult ||2961 parseForExpression(vFor.exp);2962 if (parseResult) {2963 // Render the dynamic slots as an array and add it to the createSlot()2964 // args. The runtime knows how to handle it appropriately.2965 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [2966 parseResult.source,2967 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)2968 ]));2969 }2970 else {2971 context.onError(createCompilerError(37 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));2972 }2973 }2974 else {2975 // check duplicate static names2976 if (staticSlotName) {2977 if (seenSlotNames.has(staticSlotName)) {2978 context.onError(createCompilerError(43 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));2979 continue;2980 }2981 seenSlotNames.add(staticSlotName); ...

Full Screen

Full Screen

compiler-core.cjs.js

Source:compiler-core.cjs.js Github

copy

Full Screen

...2929 childBlock.isBlock = true;2930 helper(OPEN_BLOCK);2931 helper(CREATE_BLOCK);2932 }2933 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));2934 };2935 });2936});2937// target-agnostic transform used for both Client and SSR2938function processFor(node, dir, context, processCodegen) {2939 if (!dir.exp) {2940 context.onError(createCompilerError(36 /* X_V_FOR_NO_EXPRESSION */, dir.loc));2941 return;2942 }2943 const parseResult = parseForExpression(2944 // can only be simple expression because vFor transform is applied2945 // before expression transform.2946 dir.exp, context);2947 if (!parseResult) {2948 context.onError(createCompilerError(37 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));2949 return;2950 }2951 const { addIdentifiers, removeIdentifiers, scopes } = context;2952 const { source, value, key, index } = parseResult;2953 const forNode = {2954 type: 11 /* FOR */,2955 loc: dir.loc,2956 source,2957 valueAlias: value,2958 keyAlias: key,2959 objectIndexAlias: index,2960 parseResult,2961 children: node.tagType === 3 /* TEMPLATE */ ? node.children : [node]2962 };2963 context.replaceNode(forNode);2964 // bookkeeping2965 scopes.vFor++;2966 if ( context.prefixIdentifiers) {2967 // scope management2968 // inject identifiers to context2969 value && addIdentifiers(value);2970 key && addIdentifiers(key);2971 index && addIdentifiers(index);2972 }2973 const onExit = processCodegen && processCodegen(forNode);2974 return () => {2975 scopes.vFor--;2976 if ( context.prefixIdentifiers) {2977 value && removeIdentifiers(value);2978 key && removeIdentifiers(key);2979 index && removeIdentifiers(index);2980 }2981 if (onExit)2982 onExit();2983 };2984}2985const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;2986// This regex doesn't cover the case if key or index aliases have destructuring,2987// but those do not make sense in the first place, so this works in practice.2988const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;2989const stripParensRE = /^\(|\)$/g;2990function parseForExpression(input, context) {2991 const loc = input.loc;2992 const exp = input.content;2993 const inMatch = exp.match(forAliasRE);2994 if (!inMatch)2995 return;2996 const [, LHS, RHS] = inMatch;2997 const result = {2998 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),2999 value: undefined,3000 key: undefined,3001 index: undefined3002 };3003 if ( context.prefixIdentifiers) {3004 result.source = processExpression(result.source, context);3005 }3006 let valueContent = LHS.trim()3007 .replace(stripParensRE, '')3008 .trim();3009 const trimmedOffset = LHS.indexOf(valueContent);3010 const iteratorMatch = valueContent.match(forIteratorRE);3011 if (iteratorMatch) {3012 valueContent = valueContent.replace(forIteratorRE, '').trim();3013 const keyContent = iteratorMatch[1].trim();3014 let keyOffset;3015 if (keyContent) {3016 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);3017 result.key = createAliasExpression(loc, keyContent, keyOffset);3018 if ( context.prefixIdentifiers) {3019 result.key = processExpression(result.key, context, true);3020 }3021 }3022 if (iteratorMatch[2]) {3023 const indexContent = iteratorMatch[2].trim();3024 if (indexContent) {3025 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key3026 ? keyOffset + keyContent.length3027 : trimmedOffset + valueContent.length));3028 if ( context.prefixIdentifiers) {3029 result.index = processExpression(result.index, context, true);3030 }3031 }3032 }3033 }3034 if (valueContent) {3035 result.value = createAliasExpression(loc, valueContent, trimmedOffset);3036 if ( context.prefixIdentifiers) {3037 result.value = processExpression(result.value, context, true);3038 }3039 }3040 return result;3041}3042function createAliasExpression(range, content, offset) {3043 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));3044}3045function createForLoopParams({ value, key, index }) {3046 const params = [];3047 if (value) {3048 params.push(value);3049 }3050 if (key) {3051 if (!value) {3052 params.push(createSimpleExpression(`_`, false));3053 }3054 params.push(key);3055 }3056 if (index) {3057 if (!key) {3058 if (!value) {3059 params.push(createSimpleExpression(`_`, false));3060 }3061 params.push(createSimpleExpression(`__`, false));3062 }3063 params.push(index);3064 }3065 return params;3066}3067const isStaticExp = (p) => p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic;3068const defaultFallback = createSimpleExpression(`undefined`, false);3069// A NodeTransform that:3070// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed3071// by transformExpression. This is only applied in non-browser builds with3072// { prefixIdentifiers: true }.3073// 2. Track v-slot depths so that we know a slot is inside another slot.3074// Note the exit callback is executed before buildSlots() on the same node,3075// so only nested slots see positive numbers.3076const trackSlotScopes = (node, context) => {3077 if (node.type === 1 /* ELEMENT */ &&3078 (node.tagType === 1 /* COMPONENT */ ||3079 node.tagType === 3 /* TEMPLATE */)) {3080 // We are only checking non-empty v-slot here3081 // since we only care about slots that introduce scope variables.3082 const vSlot = findDir(node, 'slot');3083 if (vSlot) {3084 const slotProps = vSlot.exp;3085 if ( context.prefixIdentifiers) {3086 slotProps && context.addIdentifiers(slotProps);3087 }3088 context.scopes.vSlot++;3089 return () => {3090 if ( context.prefixIdentifiers) {3091 slotProps && context.removeIdentifiers(slotProps);3092 }3093 context.scopes.vSlot--;3094 };3095 }3096 }3097};3098// A NodeTransform that tracks scope identifiers for scoped slots with v-for.3099// This transform is only applied in non-browser builds with { prefixIdentifiers: true }3100const trackVForSlotScopes = (node, context) => {3101 let vFor;3102 if (isTemplateNode(node) &&3103 node.props.some(isVSlot) &&3104 (vFor = findDir(node, 'for'))) {3105 const result = (vFor.parseResult = parseForExpression(vFor.exp, context));3106 if (result) {3107 const { value, key, index } = result;3108 const { addIdentifiers, removeIdentifiers } = context;3109 value && addIdentifiers(value);3110 key && addIdentifiers(key);3111 index && addIdentifiers(index);3112 return () => {3113 value && removeIdentifiers(value);3114 key && removeIdentifiers(key);3115 index && removeIdentifiers(index);3116 };3117 }3118 }3119};3120const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);3121// Instead of being a DirectiveTransform, v-slot processing is called during3122// transformElement to build the slots object for a component.3123function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {3124 const { children, loc } = node;3125 const slotsProperties = [];3126 const dynamicSlots = [];3127 const buildDefaultSlotProperty = (props, children) => createObjectProperty(`default`, buildSlotFn(props, children, loc));3128 // If the slot is inside a v-for or another v-slot, force it to be dynamic3129 // since it likely uses a scope variable.3130 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;3131 // with `prefixIdentifiers: true`, this can be further optimized to make3132 // it dynamic only when the slot actually uses the scope variables.3133 if ( context.prefixIdentifiers) {3134 hasDynamicSlots = hasScopeRef(node, context.identifiers);3135 }3136 // 1. Check for default slot with slotProps on component itself.3137 // <Comp v-slot="{ prop }"/>3138 const onComponentDefaultSlot = findDir(node, 'slot', true);3139 if (onComponentDefaultSlot) {3140 const { arg, exp, loc } = onComponentDefaultSlot;3141 if (arg) {3142 context.onError(createCompilerError(41 /* X_V_SLOT_NAMED_SLOT_ON_COMPONENT */, loc));3143 }3144 slotsProperties.push(buildDefaultSlotProperty(exp, children));3145 }3146 // 2. Iterate through children and check for template slots3147 // <template v-slot:foo="{ prop }">3148 let hasTemplateSlots = false;3149 let hasNamedDefaultSlot = false;3150 const implicitDefaultChildren = [];3151 const seenSlotNames = new Set();3152 for (let i = 0; i < children.length; i++) {3153 const slotElement = children[i];3154 let slotDir;3155 if (!isTemplateNode(slotElement) ||3156 !(slotDir = findDir(slotElement, 'slot', true))) {3157 // not a <template v-slot>, skip.3158 if (slotElement.type !== 3 /* COMMENT */) {3159 implicitDefaultChildren.push(slotElement);3160 }3161 continue;3162 }3163 if (onComponentDefaultSlot) {3164 // already has on-component default slot - this is incorrect usage.3165 context.onError(createCompilerError(42 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));3166 break;3167 }3168 hasTemplateSlots = true;3169 const { children: slotChildren, loc: slotLoc } = slotElement;3170 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;3171 // check if name is dynamic.3172 let staticSlotName;3173 if (isStaticExp(slotName)) {3174 staticSlotName = slotName ? slotName.content : `default`;3175 }3176 else {3177 hasDynamicSlots = true;3178 }3179 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);3180 // check if this slot is conditional (v-if/v-for)3181 let vIf;3182 let vElse;3183 let vFor;3184 if ((vIf = findDir(slotElement, 'if'))) {3185 hasDynamicSlots = true;3186 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));3187 }3188 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {3189 // find adjacent v-if3190 let j = i;3191 let prev;3192 while (j--) {3193 prev = children[j];3194 if (prev.type !== 3 /* COMMENT */) {3195 break;3196 }3197 }3198 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {3199 // remove node3200 children.splice(i, 1);3201 i--;3202 // attach this slot to previous conditional3203 let conditional = dynamicSlots[dynamicSlots.length - 1];3204 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3205 conditional = conditional.alternate;3206 }3207 conditional.alternate = vElse.exp3208 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)3209 : buildDynamicSlot(slotName, slotFunction);3210 }3211 else {3212 context.onError(createCompilerError(35 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));3213 }3214 }3215 else if ((vFor = findDir(slotElement, 'for'))) {3216 hasDynamicSlots = true;3217 const parseResult = vFor.parseResult ||3218 parseForExpression(vFor.exp, context);3219 if (parseResult) {3220 // Render the dynamic slots as an array and add it to the createSlot()3221 // args. The runtime knows how to handle it appropriately.3222 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [3223 parseResult.source,3224 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)3225 ]));3226 }3227 else {3228 context.onError(createCompilerError(37 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));3229 }3230 }3231 else {3232 // check duplicate static names3233 if (staticSlotName) {3234 if (seenSlotNames.has(staticSlotName)) {3235 context.onError(createCompilerError(43 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));3236 continue;3237 }3238 seenSlotNames.add(staticSlotName); ...

Full Screen

Full Screen

compiler-core.cjs.prod.js

Source:compiler-core.cjs.prod.js Github

copy

Full Screen

...2889 childBlock.isBlock = true;2890 helper(OPEN_BLOCK);2891 helper(CREATE_BLOCK);2892 }2893 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));2894 };2895 });2896});2897// target-agnostic transform used for both Client and SSR2898function processFor(node, dir, context, processCodegen) {2899 if (!dir.exp) {2900 context.onError(createCompilerError(36 /* X_V_FOR_NO_EXPRESSION */, dir.loc));2901 return;2902 }2903 const parseResult = parseForExpression(2904 // can only be simple expression because vFor transform is applied2905 // before expression transform.2906 dir.exp, context);2907 if (!parseResult) {2908 context.onError(createCompilerError(37 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));2909 return;2910 }2911 const { addIdentifiers, removeIdentifiers, scopes } = context;2912 const { source, value, key, index } = parseResult;2913 const forNode = {2914 type: 11 /* FOR */,2915 loc: dir.loc,2916 source,2917 valueAlias: value,2918 keyAlias: key,2919 objectIndexAlias: index,2920 parseResult,2921 children: node.tagType === 3 /* TEMPLATE */ ? node.children : [node]2922 };2923 context.replaceNode(forNode);2924 // bookkeeping2925 scopes.vFor++;2926 if ( context.prefixIdentifiers) {2927 // scope management2928 // inject identifiers to context2929 value && addIdentifiers(value);2930 key && addIdentifiers(key);2931 index && addIdentifiers(index);2932 }2933 const onExit = processCodegen && processCodegen(forNode);2934 return () => {2935 scopes.vFor--;2936 if ( context.prefixIdentifiers) {2937 value && removeIdentifiers(value);2938 key && removeIdentifiers(key);2939 index && removeIdentifiers(index);2940 }2941 if (onExit)2942 onExit();2943 };2944}2945const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;2946// This regex doesn't cover the case if key or index aliases have destructuring,2947// but those do not make sense in the first place, so this works in practice.2948const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;2949const stripParensRE = /^\(|\)$/g;2950function parseForExpression(input, context) {2951 const loc = input.loc;2952 const exp = input.content;2953 const inMatch = exp.match(forAliasRE);2954 if (!inMatch)2955 return;2956 const [, LHS, RHS] = inMatch;2957 const result = {2958 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),2959 value: undefined,2960 key: undefined,2961 index: undefined2962 };2963 if ( context.prefixIdentifiers) {2964 result.source = processExpression(result.source, context);2965 }2966 let valueContent = LHS.trim()2967 .replace(stripParensRE, '')2968 .trim();2969 const trimmedOffset = LHS.indexOf(valueContent);2970 const iteratorMatch = valueContent.match(forIteratorRE);2971 if (iteratorMatch) {2972 valueContent = valueContent.replace(forIteratorRE, '').trim();2973 const keyContent = iteratorMatch[1].trim();2974 let keyOffset;2975 if (keyContent) {2976 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);2977 result.key = createAliasExpression(loc, keyContent, keyOffset);2978 if ( context.prefixIdentifiers) {2979 result.key = processExpression(result.key, context, true);2980 }2981 }2982 if (iteratorMatch[2]) {2983 const indexContent = iteratorMatch[2].trim();2984 if (indexContent) {2985 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key2986 ? keyOffset + keyContent.length2987 : trimmedOffset + valueContent.length));2988 if ( context.prefixIdentifiers) {2989 result.index = processExpression(result.index, context, true);2990 }2991 }2992 }2993 }2994 if (valueContent) {2995 result.value = createAliasExpression(loc, valueContent, trimmedOffset);2996 if ( context.prefixIdentifiers) {2997 result.value = processExpression(result.value, context, true);2998 }2999 }3000 return result;3001}3002function createAliasExpression(range, content, offset) {3003 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));3004}3005function createForLoopParams({ value, key, index }) {3006 const params = [];3007 if (value) {3008 params.push(value);3009 }3010 if (key) {3011 if (!value) {3012 params.push(createSimpleExpression(`_`, false));3013 }3014 params.push(key);3015 }3016 if (index) {3017 if (!key) {3018 if (!value) {3019 params.push(createSimpleExpression(`_`, false));3020 }3021 params.push(createSimpleExpression(`__`, false));3022 }3023 params.push(index);3024 }3025 return params;3026}3027const isStaticExp = (p) => p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic;3028const defaultFallback = createSimpleExpression(`undefined`, false);3029// A NodeTransform that:3030// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed3031// by transformExpression. This is only applied in non-browser builds with3032// { prefixIdentifiers: true }.3033// 2. Track v-slot depths so that we know a slot is inside another slot.3034// Note the exit callback is executed before buildSlots() on the same node,3035// so only nested slots see positive numbers.3036const trackSlotScopes = (node, context) => {3037 if (node.type === 1 /* ELEMENT */ &&3038 (node.tagType === 1 /* COMPONENT */ ||3039 node.tagType === 3 /* TEMPLATE */)) {3040 // We are only checking non-empty v-slot here3041 // since we only care about slots that introduce scope variables.3042 const vSlot = findDir(node, 'slot');3043 if (vSlot) {3044 const slotProps = vSlot.exp;3045 if ( context.prefixIdentifiers) {3046 slotProps && context.addIdentifiers(slotProps);3047 }3048 context.scopes.vSlot++;3049 return () => {3050 if ( context.prefixIdentifiers) {3051 slotProps && context.removeIdentifiers(slotProps);3052 }3053 context.scopes.vSlot--;3054 };3055 }3056 }3057};3058// A NodeTransform that tracks scope identifiers for scoped slots with v-for.3059// This transform is only applied in non-browser builds with { prefixIdentifiers: true }3060const trackVForSlotScopes = (node, context) => {3061 let vFor;3062 if (isTemplateNode(node) &&3063 node.props.some(isVSlot) &&3064 (vFor = findDir(node, 'for'))) {3065 const result = (vFor.parseResult = parseForExpression(vFor.exp, context));3066 if (result) {3067 const { value, key, index } = result;3068 const { addIdentifiers, removeIdentifiers } = context;3069 value && addIdentifiers(value);3070 key && addIdentifiers(key);3071 index && addIdentifiers(index);3072 return () => {3073 value && removeIdentifiers(value);3074 key && removeIdentifiers(key);3075 index && removeIdentifiers(index);3076 };3077 }3078 }3079};3080const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);3081// Instead of being a DirectiveTransform, v-slot processing is called during3082// transformElement to build the slots object for a component.3083function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {3084 const { children, loc } = node;3085 const slotsProperties = [];3086 const dynamicSlots = [];3087 const buildDefaultSlotProperty = (props, children) => createObjectProperty(`default`, buildSlotFn(props, children, loc));3088 // If the slot is inside a v-for or another v-slot, force it to be dynamic3089 // since it likely uses a scope variable.3090 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;3091 // with `prefixIdentifiers: true`, this can be further optimized to make3092 // it dynamic only when the slot actually uses the scope variables.3093 if ( context.prefixIdentifiers) {3094 hasDynamicSlots = hasScopeRef(node, context.identifiers);3095 }3096 // 1. Check for default slot with slotProps on component itself.3097 // <Comp v-slot="{ prop }"/>3098 const onComponentDefaultSlot = findDir(node, 'slot', true);3099 if (onComponentDefaultSlot) {3100 const { arg, exp, loc } = onComponentDefaultSlot;3101 if (arg) {3102 context.onError(createCompilerError(41 /* X_V_SLOT_NAMED_SLOT_ON_COMPONENT */, loc));3103 }3104 slotsProperties.push(buildDefaultSlotProperty(exp, children));3105 }3106 // 2. Iterate through children and check for template slots3107 // <template v-slot:foo="{ prop }">3108 let hasTemplateSlots = false;3109 let hasNamedDefaultSlot = false;3110 const implicitDefaultChildren = [];3111 const seenSlotNames = new Set();3112 for (let i = 0; i < children.length; i++) {3113 const slotElement = children[i];3114 let slotDir;3115 if (!isTemplateNode(slotElement) ||3116 !(slotDir = findDir(slotElement, 'slot', true))) {3117 // not a <template v-slot>, skip.3118 if (slotElement.type !== 3 /* COMMENT */) {3119 implicitDefaultChildren.push(slotElement);3120 }3121 continue;3122 }3123 if (onComponentDefaultSlot) {3124 // already has on-component default slot - this is incorrect usage.3125 context.onError(createCompilerError(42 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));3126 break;3127 }3128 hasTemplateSlots = true;3129 const { children: slotChildren, loc: slotLoc } = slotElement;3130 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;3131 // check if name is dynamic.3132 let staticSlotName;3133 if (isStaticExp(slotName)) {3134 staticSlotName = slotName ? slotName.content : `default`;3135 }3136 else {3137 hasDynamicSlots = true;3138 }3139 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);3140 // check if this slot is conditional (v-if/v-for)3141 let vIf;3142 let vElse;3143 let vFor;3144 if ((vIf = findDir(slotElement, 'if'))) {3145 hasDynamicSlots = true;3146 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));3147 }3148 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {3149 // find adjacent v-if3150 let j = i;3151 let prev;3152 while (j--) {3153 prev = children[j];3154 if (prev.type !== 3 /* COMMENT */) {3155 break;3156 }3157 }3158 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {3159 // remove node3160 children.splice(i, 1);3161 i--;3162 // attach this slot to previous conditional3163 let conditional = dynamicSlots[dynamicSlots.length - 1];3164 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3165 conditional = conditional.alternate;3166 }3167 conditional.alternate = vElse.exp3168 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)3169 : buildDynamicSlot(slotName, slotFunction);3170 }3171 else {3172 context.onError(createCompilerError(35 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));3173 }3174 }3175 else if ((vFor = findDir(slotElement, 'for'))) {3176 hasDynamicSlots = true;3177 const parseResult = vFor.parseResult ||3178 parseForExpression(vFor.exp, context);3179 if (parseResult) {3180 // Render the dynamic slots as an array and add it to the createSlot()3181 // args. The runtime knows how to handle it appropriately.3182 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [3183 parseResult.source,3184 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)3185 ]));3186 }3187 else {3188 context.onError(createCompilerError(37 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));3189 }3190 }3191 else {3192 // check duplicate static names3193 if (staticSlotName) {3194 if (seenSlotNames.has(staticSlotName)) {3195 context.onError(createCompilerError(43 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));3196 continue;3197 }3198 seenSlotNames.add(staticSlotName); ...

Full Screen

Full Screen

note-ast-transform.js

Source:note-ast-transform.js Github

copy

Full Screen

...229 helper(OPEN_BLOCK);230 helper(CREATE_BLOCK);231 }232 }233 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));234 };235 });236 });237 function createCallExpression(callee, args = [], loc = locStub) {238 return {239 type: 14 /* JS_CALL_EXPRESSION */,240 loc,241 callee,242 arguments: args243 };244 }245 function createObjectProperty(key, value) {246 return {247 type: 16 /* JS_PROPERTY */,248 loc: locStub,249 key: isString(key) ? createSimpleExpression(key, true) : key,250 value251 };252 }253 function createSimpleExpression(content, isStatic, loc = locStub, isConstant = false) {254 return {255 type: 4 /* SIMPLE_EXPRESSION */,256 loc,257 isConstant,258 content,259 isStatic260 };261 }262 function createFunctionExpression(params, returns = undefined, newline = false, isSlot = false, loc = locStub) {263 return {264 type: 18 /* JS_FUNCTION_EXPRESSION */,265 params,266 returns,267 newline,268 isSlot,269 loc270 };271 }272 function createForLoopParams({ value, key, index }) {273 const params = [];274 if (value) {275 params.push(value);276 }277 if (key) {278 if (!value) {279 params.push(createSimpleExpression(`_`, false));280 }281 params.push(key);282 }283 if (index) {284 if (!key) {285 if (!value) {286 params.push(createSimpleExpression(`_`, false));287 }288 params.push(createSimpleExpression(`__`, false));289 }290 params.push(index);291 }292 return params;293 }294 function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock = false, disableTracking = false, loc = locStub) {295 if (context) {296 if (isBlock) {297 context.helper(OPEN_BLOCK);298 context.helper(CREATE_BLOCK);299 }300 else {301 context.helper(CREATE_VNODE);302 }303 if (directives) {304 context.helper(WITH_DIRECTIVES);305 }306 }307 return {308 type: 13 /* VNODE_CALL */,309 tag,310 props,311 children,312 patchFlag,313 dynamicProps,314 directives,315 isBlock,316 disableTracking,317 loc318 };319 }320 // AST Utilities ---------------------------------------------------------------321 // Some expressions, e.g. sequence and conditional expressions, are never322 // associated with template nodes, so their source locations are just a stub.323 // Container types like CompoundExpression also don't need a real location.324 const locStub = {325 source: '',326 start: { line: 1, column: 1, offset: 0 },327 end: { line: 1, column: 1, offset: 0 }328 };329 330 // Patch flags are optimization hints generated by the compiler.331 // when a block with dynamicChildren is encountered during diff, the algorithm332 // enters "optimized mode". In this mode, we know that the vdom is produced by333 // a render function generated by the compiler, so the algorithm only needs to334 // handle updates explicitly marked by these patch flags.335 // dev only flag -> name mapping336 const PatchFlagNames = {337 [1 /* TEXT */]: `TEXT`,338 [2 /* CLASS */]: `CLASS`,339 [4 /* STYLE */]: `STYLE`,340 [8 /* PROPS */]: `PROPS`,341 [16 /* FULL_PROPS */]: `FULL_PROPS`,342 [32 /* HYDRATE_EVENTS */]: `HYDRATE_EVENTS`,343 [64 /* STABLE_FRAGMENT */]: `STABLE_FRAGMENT`,344 [128 /* KEYED_FRAGMENT */]: `KEYED_FRAGMENT`,345 [256 /* UNKEYED_FRAGMENT */]: `UNKEYED_FRAGMENT`,346 [512 /* NEED_PATCH */]: `NEED_PATCH`,347 [1024 /* DYNAMIC_SLOTS */]: `DYNAMIC_SLOTS`,348 [-1 /* HOISTED */]: `HOISTED`,349 [-2 /* BAIL */]: `BAIL`350 };351 function createObjectProperty(key, value) {352 return {353 type: 16 /* JS_PROPERTY */,354 loc: locStub,355 key: isString(key) ? createSimpleExpression(key, true) : key,356 value357 };358 }359 360 // target-agnostic transform used for both Client and SSR361 function processFor(node, dir, context, processCodegen) {362 if (!dir.exp) {363 context.onError(createCompilerError(30 /* X_V_FOR_NO_EXPRESSION */, dir.loc));364 return;365 }366 const parseResult = parseForExpression(367 // can only be simple expression because vFor transform is applied368 // before expression transform.369 dir.exp, context);370 if (!parseResult) {371 context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));372 return;373 }374 const { addIdentifiers, removeIdentifiers, scopes } = context;375 const { source, value, key, index } = parseResult;376 const forNode = {377 type: 11 /* FOR */,378 loc: dir.loc,379 source,380 valueAlias: value,381 keyAlias: key,382 objectIndexAlias: index,383 parseResult,384 children: isTemplateNode(node) ? node.children : [node]385 };386 context.replaceNode(forNode);387 // bookkeeping388 scopes.vFor++;389 const onExit = processCodegen && processCodegen(forNode);390 return () => {391 scopes.vFor--;392 if (onExit)393 onExit();394 };395 }396 const forNode = {397 type: 11 /* FOR */,398 loc: dir.loc,399 source,400 valueAlias: value,401 keyAlias: key,402 objectIndexAlias: index,403 parseResult,404 children: isTemplateNode(node) ? node.children : [node]405 };406 const transformExpression = (node, context) => {407 if (node.type === 5 /* INTERPOLATION */) {408 node.content = processExpression(node.content, context);409 }410 else if (node.type === 1 /* ELEMENT */) {411 // handle directives on element412 for (let i = 0; i < node.props.length; i++) {413 const dir = node.props[i];414 // do not process for v-on & v-for since they are special handled415 if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {416 const exp = dir.exp;417 const arg = dir.arg;418 // do not process exp if this is v-on:arg - we need special handling419 // for wrapping inline statements.420 if (exp &&421 exp.type === 4 /* SIMPLE_EXPRESSION */ &&422 !(dir.name === 'on' && arg)) {423 dir.exp = processExpression(exp, context, 424 // slot args must be processed as function params425 dir.name === 'slot');426 }427 if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {428 dir.arg = processExpression(arg, context);429 }430 }431 }432 }433 };434 const transformSlotOutlet = (node, context) => {435 if (isSlotOutlet(node)) {436 const { children, loc } = node;437 const { slotName, slotProps } = processSlotOutlet(node, context);438 const slotArgs = [439 context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,440 slotName441 ];442 if (slotProps) {443 slotArgs.push(slotProps);444 }445 if (children.length) {446 if (!slotProps) {447 slotArgs.push(`{}`);448 }449 slotArgs.push(createFunctionExpression([], children, false, false, loc));450 }451 node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);452 }453 };454 function isSlotOutlet(node) {455 return node.type === 1 /* ELEMENT */ && node.tagType === 2 /* SLOT */;456 }457 function processSlotOutlet(node, context) {458 let slotName = `"default"`;459 let slotProps = undefined;460 // check for <slot name="xxx" OR :name="xxx" />461 const name = findProp(node, 'name');462 if (name) {463 if (name.type === 6 /* ATTRIBUTE */ && name.value) {464 // static name465 slotName = JSON.stringify(name.value.content);466 }467 else if (name.type === 7 /* DIRECTIVE */ && name.exp) {468 // dynamic name469 slotName = name.exp;470 }471 }472 const propsWithoutName = name473 ? node.props.filter(p => p !== name)474 : node.props;475 if (propsWithoutName.length > 0) {476 const { props, directives } = buildProps(node, context, propsWithoutName);477 slotProps = props;478 if (directives.length) {479 context.onError(createCompilerError(35 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));480 }481 }482 return {483 slotName,484 slotProps485 };486 }487 function buildProps(node, context, props = node.props, ssr = false) {488 const { tag, loc: elementLoc } = node;489 const isComponent = node.tagType === 1 /* COMPONENT */;490 let properties = [];491 const mergeArgs = [];492 const runtimeDirectives = [];493 // patchFlag analysis494 let patchFlag = 0;495 let hasRef = false;496 let hasClassBinding = false;497 let hasStyleBinding = false;498 let hasHydrationEventBinding = false;499 let hasDynamicKeys = false;500 let hasVnodeHook = false;501 const dynamicPropNames = [];502 const analyzePatchFlag = ({ key, value }) => {503 // if (content.startsWith('[')) {504 // isStatic = false;505 // if (!content.endsWith(']')) {506 // emitError(context, 26 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);507 // }508 // content = content.substr(1, content.length - 2);509 // }510 if (isStaticExp(key)) { // const isStaticExp = (p) => p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic;511 const name = key.content;512 const isEventHandler = isOn(name);513 if (!isComponent &&514 isEventHandler &&515 // omit the flag for click handlers because hydration gives click516 // dedicated fast path.517 name.toLowerCase() !== 'onclick' &&518 // omit v-model handlers519 name !== 'onUpdate:modelValue' &&520 // omit onVnodeXXX hooks521 !isReservedProp(name)) {522 hasHydrationEventBinding = true;523 }524 if (isEventHandler && isReservedProp(name)) {525 hasVnodeHook = true;526 }527 if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||528 ((value.type === 4 /* SIMPLE_EXPRESSION */ ||529 value.type === 8 /* COMPOUND_EXPRESSION */) &&530 getStaticType(value) > 0)) {531 // skip if the prop is a cached handler or has constant value532 return;533 }534 if (name === 'ref') {535 hasRef = true;536 }537 else if (name === 'class' && !isComponent) {538 hasClassBinding = true;539 }540 else if (name === 'style' && !isComponent) {541 hasStyleBinding = true;542 }543 else if (name !== 'key' && !dynamicPropNames.includes(name)) {544 dynamicPropNames.push(name);545 }546 }547 else {548 hasDynamicKeys = true;549 }550 };551 for (let i = 0; i < props.length; i++) {552 // static attribute553 const prop = props[i];554 if (prop.type === 6 /* ATTRIBUTE */) {555 const { loc, name, value } = prop;556 if (name === 'ref') {557 hasRef = true;558 }559 // skip :is on <component>560 if (name === 'is' && tag === 'component') {561 continue;562 }563 properties.push(createObjectProperty(564 createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), 565 createSimpleExpression(value ? value.content : '', true, value ? value.loc : loc)566 )567 );568 }569 else {570 // directives571 const { name, arg, exp, loc } = prop;572 const isBind = name === 'bind';573 const isOn = name === 'on';574 // skip v-slot - it is handled by its dedicated transform.575 if (name === 'slot') {576 if (!isComponent) {577 context.onError(createCompilerError(39 /* X_V_SLOT_MISPLACED */, loc));578 }579 continue;580 }581 // skip v-once - it is handled by its dedicated transform.582 if (name === 'once') {583 continue;584 }585 // skip v-is and :is on <component>586 if (name === 'is' ||587 (isBind && tag === 'component' && isBindKey(arg, 'is'))) { // 参考parseAttribute588 continue;589 }590 // skip v-on in SSR compilation591 if (isOn && ssr) {592 continue;593 }594 // special case for v-bind and v-on with no argument595 if (!arg && (isBind || isOn)) { // 参考parseAttribute596 hasDynamicKeys = true;597 if (exp) {598 if (properties.length) {599 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));600 properties = [];601 }602 if (isBind) {603 mergeArgs.push(exp);604 }605 else {606 // v-on="obj" -> toHandlers(obj)607 mergeArgs.push({608 type: 14 /* JS_CALL_EXPRESSION */,609 loc,610 callee: context.helper(TO_HANDLERS),611 arguments: [exp]612 });613 }614 }615 else {616 context.onError(createCompilerError(isBind617 ? 33 /* X_V_BIND_NO_EXPRESSION */618 : 34 /* X_V_ON_NO_EXPRESSION */, loc));619 }620 continue;621 }622 const directiveTransform = context.directiveTransforms[name]; // on, bind. model623 if (directiveTransform) {624 // has built-in directive transform.625 const { props, needRuntime } = directiveTransform(prop, node, context);626 !ssr && props.forEach(analyzePatchFlag);627 properties.push(...props);628 if (needRuntime) {629 runtimeDirectives.push(prop);630 if (isSymbol(needRuntime)) {631 directiveImportMap.set(prop, needRuntime);632 }633 }634 }635 else {636 // no built-in transform, this is a user custom directive.637 runtimeDirectives.push(prop);638 }639 }640 }641 let propsExpression = undefined;642 // has v-bind="object" or v-on="object", wrap with mergeProps643 if (mergeArgs.length) {644 if (properties.length) {645 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));646 }647 if (mergeArgs.length > 1) {648 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);649 }650 else {651 // single v-bind with nothing else - no need for a mergeProps call652 propsExpression = mergeArgs[0];653 }654 }655 else if (properties.length) {656 propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);657 }658 // patchFlag analysis659 if (hasDynamicKeys) {660 patchFlag |= 16 /* FULL_PROPS */;661 }662 else {663 if (hasClassBinding) {664 patchFlag |= 2 /* CLASS */;665 }666 if (hasStyleBinding) {667 patchFlag |= 4 /* STYLE */;668 }669 if (dynamicPropNames.length) {670 patchFlag |= 8 /* PROPS */;671 }672 if (hasHydrationEventBinding) {673 patchFlag |= 32 /* HYDRATE_EVENTS */;674 }675 }676 if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&677 (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {678 patchFlag |= 512 /* NEED_PATCH */;679 }680 return {681 props: propsExpression,682 directives: runtimeDirectives,683 patchFlag,684 dynamicPropNames685 };686 }687 // Dedupe props in an object literal.688 // Literal duplicated attributes would have been warned during the parse phase,689 // however, it's possible to encounter duplicated `onXXX` handlers with different690 // modifiers. We also need to merge static and dynamic class / style attributes.691 // - onXXX handlers / style: merge into array692 // - class: merge into single expression with concatenation693 function dedupeProperties(properties) {694 const knownProps = new Map();695 const deduped = [];696 for (let i = 0; i < properties.length; i++) {697 const prop = properties[i];698 // dynamic keys are always allowed699 if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) { // onXXX700 deduped.push(prop);701 continue;702 }703 const name = prop.key.content;704 const existing = knownProps.get(name);705 if (existing) {706 if (name === 'style' || name === 'class' || name.startsWith('on')) {707 mergeAsArray(existing, prop);708 }709 // unexpected duplicate, should have emitted error during parse710 }711 else {712 knownProps.set(name, prop);713 deduped.push(prop);714 }715 }716 return deduped;717 }718 function createArrayExpression(elements, loc = locStub) {719 return {720 type: 17 /* JS_ARRAY_EXPRESSION */,721 loc,722 elements723 };724 }725 function getStaticType(node, resultCache = new Map()) {726 switch (node.type) {727 case 1 /* ELEMENT */:728 if (node.tagType !== 0 /* ELEMENT */) {729 return 0 /* NOT_STATIC */;730 }731 const cached = resultCache.get(node);732 if (cached !== undefined) {733 return cached;734 }735 const codegenNode = node.codegenNode;736 if (codegenNode.type !== 13 /* VNODE_CALL */) {737 return 0 /* NOT_STATIC */;738 }739 const flag = getPatchFlag(codegenNode);740 if (!flag && !hasNonHoistableProps(node)) {741 // element self is static. check its children.742 let returnType = 1 /* FULL_STATIC */;743 for (let i = 0; i < node.children.length; i++) {744 const childType = getStaticType(node.children[i], resultCache);745 if (childType === 0 /* NOT_STATIC */) {746 resultCache.set(node, 0 /* NOT_STATIC */);747 return 0 /* NOT_STATIC */;748 }749 else if (childType === 2 /* HAS_RUNTIME_CONSTANT */) {750 returnType = 2 /* HAS_RUNTIME_CONSTANT */;751 }752 }753 // check if any of the props contain runtime constants754 if (returnType !== 2 /* HAS_RUNTIME_CONSTANT */) {755 for (let i = 0; i < node.props.length; i++) {756 const p = node.props[i];757 if (p.type === 7 /* DIRECTIVE */ &&758 p.name === 'bind' &&759 p.exp &&760 (p.exp.type === 8 /* COMPOUND_EXPRESSION */ ||761 p.exp.isRuntimeConstant)) {762 returnType = 2 /* HAS_RUNTIME_CONSTANT */;763 }764 }765 }766 // only svg/foreignObject could be block here, however if they are767 // stati then they don't need to be blocks since there will be no768 // nested updates.769 if (codegenNode.isBlock) {770 codegenNode.isBlock = false;771 }772 resultCache.set(node, returnType);773 return returnType;774 }775 else {776 resultCache.set(node, 0 /* NOT_STATIC */);777 return 0 /* NOT_STATIC */;778 }779 case 2 /* TEXT */:780 case 3 /* COMMENT */:781 return 1 /* FULL_STATIC */;782 case 9 /* IF */:783 case 11 /* FOR */:784 case 10 /* IF_BRANCH */:785 return 0 /* NOT_STATIC */;786 case 5 /* INTERPOLATION */:787 case 12 /* TEXT_CALL */:788 return getStaticType(node.content, resultCache);789 case 4 /* SIMPLE_EXPRESSION */:790 return node.isConstant791 ? node.isRuntimeConstant792 ? 2 /* HAS_RUNTIME_CONSTANT */793 : 1 /* FULL_STATIC */794 : 0 /* NOT_STATIC */;795 case 8 /* COMPOUND_EXPRESSION */:796 let returnType = 1 /* FULL_STATIC */;797 for (let i = 0; i < node.children.length; i++) {798 const child = node.children[i];799 if (isString(child) || isSymbol(child)) {800 continue;801 }802 const childType = getStaticType(child, resultCache);803 if (childType === 0 /* NOT_STATIC */) {804 return 0 /* NOT_STATIC */;805 }806 else if (childType === 2 /* HAS_RUNTIME_CONSTANT */) {807 returnType = 2 /* HAS_RUNTIME_CONSTANT */;808 }809 }810 return returnType;811 default:812 return 0 /* NOT_STATIC */;813 }814 }815 const transformElement = (node, context) => {816 if (!(node.type === 1 /* ELEMENT */ &&817 (node.tagType === 0 /* ELEMENT */ ||818 node.tagType === 1 /* COMPONENT */))) {819 return;820 }821 // perform the work on exit, after all child expressions have been822 // processed and merged.823 return function postTransformElement() {824 const { tag, props } = node;825 const isComponent = node.tagType === 1 /* COMPONENT */;826 // The goal of the transform is to create a codegenNode implementing the827 // VNodeCall interface.828 const vnodeTag = isComponent829 ? resolveComponentType(node, context)830 : `"${tag}"`;831 const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;832 let vnodeProps;833 let vnodeChildren;834 let vnodePatchFlag;835 let patchFlag = 0;836 let vnodeDynamicProps;837 let dynamicPropNames;838 let vnodeDirectives;839 let shouldUseBlock = 840 // dynamic component may resolve to plain elements841 isDynamicComponent ||842 vnodeTag === TELEPORT ||843 vnodeTag === SUSPENSE ||844 (!isComponent &&845 // <svg> and <foreignObject> must be forced into blocks so that block846 // updates inside get proper isSVG flag at runtime. (#639, #643)847 // This is technically web-specific, but splitting the logic out of core848 // leads to too much unnecessary complexity.849 (tag === 'svg' ||850 tag === 'foreignObject' ||851 // #938: elements with dynamic keys should be forced into blocks852 findProp(node, 'key', true)));853 // props854 if (props.length > 0) {855 const propsBuildResult = buildProps(node, context);856 vnodeProps = propsBuildResult.props;857 patchFlag = propsBuildResult.patchFlag;858 dynamicPropNames = propsBuildResult.dynamicPropNames;859 const directives = propsBuildResult.directives;860 vnodeDirectives =861 directives && directives.length862 ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))863 : undefined;864 }865 // children866 if (node.children.length > 0) {867 if (vnodeTag === KEEP_ALIVE) {868 // Although a built-in component, we compile KeepAlive with raw children869 // instead of slot functions so that it can be used inside Transition870 // or other Transition-wrapping HOCs.871 // To ensure correct updates with block optimizations, we need to:872 // 1. Force keep-alive into a block. This avoids its children being873 // collected by a parent block.874 shouldUseBlock = true;875 // 2. Force keep-alive to always be updated, since it uses raw children.876 patchFlag |= 1024 /* DYNAMIC_SLOTS */;877 if ( node.children.length > 1) {878 context.onError(createCompilerError(44 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {879 start: node.children[0].loc.start,880 end: node.children[node.children.length - 1].loc.end,881 source: ''882 }));883 }884 }885 const shouldBuildAsSlots = isComponent &&886 // Teleport is not a real component and has dedicated runtime handling887 vnodeTag !== TELEPORT &&888 // explained above.889 vnodeTag !== KEEP_ALIVE;890 if (shouldBuildAsSlots) {891 const { slots, hasDynamicSlots } = buildSlots(node, context);892 vnodeChildren = slots;893 if (hasDynamicSlots) {894 patchFlag |= 1024 /* DYNAMIC_SLOTS */;895 }896 }897 else if (node.children.length === 1 && vnodeTag !== TELEPORT) {898 const child = node.children[0];899 const type = child.type;900 // check for dynamic text children901 const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||902 type === 8 /* COMPOUND_EXPRESSION */;903 if (hasDynamicTextChild && !getStaticType(child)) {904 patchFlag |= 1 /* TEXT */;905 }906 // pass directly if the only child is a text node907 // (plain / interpolation / expression)908 if (hasDynamicTextChild || type === 2 /* TEXT */) {909 vnodeChildren = child;910 }911 else {912 vnodeChildren = node.children;913 }914 }915 else {916 vnodeChildren = node.children;917 }918 }919 // patchFlag & dynamicPropNames920 if (patchFlag !== 0) {921 {922 if (patchFlag < 0) {923 // special flags (negative and mutually exclusive)924 vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;925 }926 else {927 // bitwise flags928 const flagNames = Object.keys(PatchFlagNames)929 .map(Number)930 .filter(n => n > 0 && patchFlag & n)931 .map(n => PatchFlagNames[n])932 .join(`, `);933 vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;934 }935 }936 if (dynamicPropNames && dynamicPropNames.length) {937 vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);938 }939 }940 // function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock = false, disableTracking = false, loc = locStub) 941 node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, node.loc);942 };943 };944 function stringifyDynamicPropNames(props) {945 let propsNamesString = `[`;946 for (let i = 0, l = props.length; i < l; i++) {947 propsNamesString += JSON.stringify(props[i]);948 if (i < l - 1)949 propsNamesString += ', ';950 }951 return propsNamesString + `]`;952 }953 /**954 * Even for a node with no patch flag, it is possible for it to contain955 * non-hoistable expressions that refers to scope variables, e.g. compiler956 * injected keys or cached event handlers. Therefore we need to always check the957 * codegenNode's props to be sure.958 */959 function hasNonHoistableProps(node) {960 const props = getNodeProps(node);961 if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {962 const { properties } = props;963 for (let i = 0; i < properties.length; i++) {964 const { key, value } = properties[i];965 if (key.type !== 4 /* SIMPLE_EXPRESSION */ ||966 !key.isStatic ||967 (value.type !== 4 /* SIMPLE_EXPRESSION */ ||968 (!value.isStatic && !value.isConstant))) {969 return true;970 }971 }972 }973 return false;974 }975 const vModelSelect = {976 created(el, binding, vnode) {977 addEventListener(el, 'change', () => {978 const selectedVal = Array.prototype.filter979 .call(el.options, (o) => o.selected)980 .map(getValue);981 el._assign(el.multiple ? selectedVal : selectedVal[0]);982 });983 el._assign = getModelAssigner(vnode);984 },985 // set value in mounted & updated because <select> relies on its children986 // <option>s.987 mounted(el, { value }) {988 setSelected(el, value);989 },990 beforeUpdate(el, _binding, vnode) {991 el._assign = getModelAssigner(vnode);992 },993 updated(el, { value }) {994 setSelected(el, value);995 }996 };997 /**998 * 999 * node.type:0 ROOT 1 ELEMENT 2 TEXT 3 COMMENT 4 SIMPLE_EXPRESSION 5 INTERPOLATION 8 COMPOUND_EXPRESSION 9 IF 10 IF_BRANCH IF 11 FOR 12 TEXT_CALL1000 * 1001 * static type 0 NOT_STATIC 1 FULL_STATIC 2 HAS_RUNTIME_CONSTANT1002 * tagtype: 0 element 1 template 2 slot1003 * 1004 * codegennode.patchFlag -2 BAIL -1 HOISTED 1 TEXT 2 CLASS 4 STYLE 8 PROPS 16 FULL_PROPS 32 HYDRATE_EVENTS 64 STABLE_FRAGMENT 128 KEYED_FRAGMENT 256 UNKEYED_FRAGMENT 512 NEED_PATCH 1024 DYNAMIC_SLOTS1005 * 1006 */1007 function getStaticType(node, resultCache = new Map()) { // 0 NOT_STATIC 1 FULL_STATIC 2 HAS_RUNTIME_CONSTANT1008 switch (node.type) {1009 case 1 /* ELEMENT */:1010 if (node.tagType !== 0 /* ELEMENT */) {1011 return 0 /* NOT_STATIC */;1012 }1013 const cached = resultCache.get(node);1014 if (cached !== undefined) {1015 return cached;1016 }1017 const codegenNode = node.codegenNode;1018 if (codegenNode.type !== 13 /* VNODE_CALL */) {1019 return 0 /* NOT_STATIC */;1020 }1021 const flag = getPatchFlag(codegenNode);1022 if (!flag && !hasNonHoistableProps(node)) {1023 // element self is static. check its children.1024 let returnType = 1 /* FULL_STATIC */;1025 for (let i = 0; i < node.children.length; i++) {1026 const childType = getStaticType(node.children[i], resultCache);1027 if (childType === 0 /* NOT_STATIC */) {1028 resultCache.set(node, 0 /* NOT_STATIC */);1029 return 0 /* NOT_STATIC */;1030 }1031 else if (childType === 2 /* HAS_RUNTIME_CONSTANT */) {1032 returnType = 2 /* HAS_RUNTIME_CONSTANT */;1033 }1034 }1035 // check if any of the props contain runtime constants1036 if (returnType !== 2 /* HAS_RUNTIME_CONSTANT */) {1037 for (let i = 0; i < node.props.length; i++) {1038 const p = node.props[i];1039 if (p.type === 7 /* DIRECTIVE */ &&1040 p.name === 'bind' &&1041 p.exp &&1042 (p.exp.type === 8 /* COMPOUND_EXPRESSION */ ||1043 p.exp.isRuntimeConstant)) {1044 returnType = 2 /* HAS_RUNTIME_CONSTANT */;1045 }1046 }1047 }1048 // only svg/foreignObject could be block here, however if they are1049 // stati then they don't need to be blocks since there will be no1050 // nested updates.1051 if (codegenNode.isBlock) {1052 codegenNode.isBlock = false;1053 }1054 resultCache.set(node, returnType);1055 return returnType;1056 }1057 else {1058 resultCache.set(node, 0 /* NOT_STATIC */);1059 return 0 /* NOT_STATIC */;1060 }1061 case 2 /* TEXT */:1062 case 3 /* COMMENT */:1063 return 1 /* FULL_STATIC */;1064 case 9 /* IF */:1065 case 11 /* FOR */:1066 case 10 /* IF_BRANCH */:1067 return 0 /* NOT_STATIC */;1068 case 5 /* INTERPOLATION */:1069 case 12 /* TEXT_CALL */:1070 return getStaticType(node.content, resultCache);1071 case 4 /* SIMPLE_EXPRESSION */:1072 return node.isConstant1073 ? node.isRuntimeConstant1074 ? 2 /* HAS_RUNTIME_CONSTANT */1075 : 1 /* FULL_STATIC */1076 : 0 /* NOT_STATIC */;1077 case 8 /* COMPOUND_EXPRESSION */:1078 let returnType = 1 /* FULL_STATIC */;1079 for (let i = 0; i < node.children.length; i++) {1080 const child = node.children[i];1081 if (isString(child) || isSymbol(child)) {1082 continue;1083 }1084 const childType = getStaticType(child, resultCache);1085 if (childType === 0 /* NOT_STATIC */) {1086 return 0 /* NOT_STATIC */;1087 }1088 else if (childType === 2 /* HAS_RUNTIME_CONSTANT */) {1089 returnType = 2 /* HAS_RUNTIME_CONSTANT */;1090 }1091 }1092 return returnType;1093 default:1094 return 0 /* NOT_STATIC */;1095 }1096 }1097 /**1098 * context.scopes1099 * scopes: {1100 vFor: 0,1101 vSlot: 0,1102 vPre: 0,1103 vOnce: 01104 },1105 */1106 function isCoreComponent(tag) {1107 if (isBuiltInType(tag, 'Teleport')) {1108 return TELEPORT;1109 }1110 else if (isBuiltInType(tag, 'Suspense')) {1111 return SUSPENSE;1112 }1113 else if (isBuiltInType(tag, 'KeepAlive')) {1114 return KEEP_ALIVE;1115 }1116 else if (isBuiltInType(tag, 'BaseTransition')) {1117 return BASE_TRANSITION;1118 }1119 }1120 const buildClientSlotFn = (props, children, loc) => {1121 createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);1122 }1123 function createFunctionExpression(params, returns = undefined, newline = false, isSlot = false, loc = locStub) {1124 return {1125 type: 18 /* JS_FUNCTION_EXPRESSION */,1126 params,1127 returns,1128 newline,1129 isSlot,1130 loc1131 };1132 }1133 function buildDynamicSlot(name, fn) {1134 return createObjectExpression([1135 createObjectProperty(`name`, name),1136 createObjectProperty(`fn`, fn)1137 ]);1138 }1139 function createConditionalExpression(test, consequent, alternate, newline = true) {1140 return {1141 type: 19 /* JS_CONDITIONAL_EXPRESSION */,1142 test,1143 consequent,1144 alternate,1145 newline,1146 loc: locStub1147 };1148 }1149 function createForLoopParams({ value, key, index }) {1150 const params = [];1151 if (value) {1152 params.push(value);1153 }1154 if (key) {1155 if (!value) {1156 params.push(createSimpleExpression(`_`, false));1157 }1158 params.push(key);1159 }1160 if (index) {1161 if (!key) {1162 if (!value) {1163 params.push(createSimpleExpression(`_`, false));1164 }1165 params.push(createSimpleExpression(`__`, false));1166 }1167 params.push(index);1168 }1169 return params;1170 }1171 // Instead of being a DirectiveTransform, v-slot processing is called during1172 // transformElement to build the slots object for a component.1173 function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {1174 context.helper(WITH_CTX);1175 const { children, loc } = node;1176 const slotsProperties = [];1177 const dynamicSlots = [];1178 const buildDefaultSlotProperty = (props, children) => createObjectProperty(`default`, buildSlotFn(props, children, loc));1179 // If the slot is inside a v-for or another v-slot, force it to be dynamic1180 // since it likely uses a scope variable.1181 1182 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;1183 // 1. Check for slot with slotProps on component itself.1184 // <Comp v-slot="{ prop }"/>1185 const onComponentSlot = findDir(node, 'slot', true);1186 if (onComponentSlot) {1187 const { arg, exp } = onComponentSlot;1188 if (arg && !isStaticExp(arg)) {1189 hasDynamicSlots = true;1190 }1191 slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));1192 }1193 // 2. Iterate through children and check for template slots1194 // <template v-slot:foo="{ prop }">1195 let hasTemplateSlots = false;1196 let hasNamedDefaultSlot = false;1197 const implicitDefaultChildren = [];1198 const seenSlotNames = new Set();1199 for (let i = 0; i < children.length; i++) {1200 const slotElement = children[i];1201 let slotDir;1202 if (!isTemplateNode(slotElement) ||1203 !(slotDir = findDir(slotElement, 'slot', true))) {1204 // not a <template v-slot>, skip.1205 if (slotElement.type !== 3 /* COMMENT */) {1206 implicitDefaultChildren.push(slotElement);1207 }1208 continue;1209 }1210 if (onComponentSlot) {1211 // already has on-component slot - this is incorrect usage.1212 context.onError(createCompilerError(36 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));1213 break;1214 }1215 hasTemplateSlots = true;1216 const { children: slotChildren, loc: slotLoc } = slotElement;1217 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;1218 // check if name is dynamic.1219 let staticSlotName;1220 if (isStaticExp(slotName)) {1221 staticSlotName = slotName ? slotName.content : `default`;1222 }1223 else {1224 hasDynamicSlots = true;1225 }1226 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);1227 // check if this slot is conditional (v-if/v-for)1228 let vIf;1229 let vElse;1230 let vFor;1231 if ((vIf = findDir(slotElement, 'if'))) {1232 hasDynamicSlots = true;1233 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));1234 }1235 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {1236 // find adjacent v-if1237 let j = i;1238 let prev;1239 while (j--) {1240 prev = children[j];1241 if (prev.type !== 3 /* COMMENT */) {1242 break;1243 }1244 }1245 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {1246 // remove node1247 children.splice(i, 1);1248 i--;1249 // attach this slot to previous conditional1250 let conditional = dynamicSlots[dynamicSlots.length - 1];1251 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {1252 conditional = conditional.alternate;1253 }1254 conditional.alternate = vElse.exp1255 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)1256 : buildDynamicSlot(slotName, slotFunction);1257 }1258 else {1259 context.onError(createCompilerError(29 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));1260 }1261 }1262 else if ((vFor = findDir(slotElement, 'for'))) {1263 hasDynamicSlots = true;1264 const parseResult = vFor.parseResult ||1265 parseForExpression(vFor.exp, context);1266 if (parseResult) {1267 // Render the dynamic slots as an array and add it to the createSlot()1268 // args. The runtime knows how to handle it appropriately.1269 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [1270 parseResult.source,1271 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)1272 ]));1273 }1274 else {1275 context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));1276 }1277 }1278 else {1279 // check duplicate static names1280 if (staticSlotName) {1281 if (seenSlotNames.has(staticSlotName)) {1282 context.onError(createCompilerError(37 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));1283 continue;1284 }1285 seenSlotNames.add(staticSlotName);...

Full Screen

Full Screen

stable_fragment.js

Source:stable_fragment.js Github

copy

Full Screen

...259 helper(OPEN_BLOCK);260 helper(CREATE_BLOCK);261 }262 }263 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));264 };265 });...

Full Screen

Full Screen

vFor.js

Source:vFor.js Github

copy

Full Screen

...92 codegenNode_1.callee = helper(runtimeHelpers_1.CREATE_BLOCK);93 }94 childBlock = utils_1.createBlockExpression(codegenNode_1, context);95 }96 renderExp.arguments.push(ast_1.createFunctionExpression(createForLoopParams(parseResult), childBlock, true));97 };98});99var forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;100var forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;101var stripParensRE = /^\(|\)$/g;102function parseForExpression(input, context) {103 var loc = input.loc;104 var exp = input.content;105 var inMatch = exp.match(forAliasRE);106 if (!inMatch)107 return;108 var LHS = inMatch[1], RHS = inMatch[2];109 var result = {110 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),111 value: undefined,112 key: undefined,113 index: undefined114 };115 if (!__BROWSER__ && context.prefixIdentifiers) {116 result.source = transformExpression_1.processExpression(result.source, context);117 }118 var valueContent = LHS.trim()119 .replace(stripParensRE, '')120 .trim();121 var trimmedOffset = LHS.indexOf(valueContent);122 var iteratorMatch = valueContent.match(forIteratorRE);123 if (iteratorMatch) {124 valueContent = valueContent.replace(forIteratorRE, '').trim();125 var keyContent = iteratorMatch[1].trim();126 var keyOffset = void 0;127 if (keyContent) {128 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);129 result.key = createAliasExpression(loc, keyContent, keyOffset);130 if (!__BROWSER__ && context.prefixIdentifiers) {131 result.key = transformExpression_1.processExpression(result.key, context, true);132 }133 }134 if (iteratorMatch[2]) {135 var indexContent = iteratorMatch[2].trim();136 if (indexContent) {137 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key138 ? keyOffset + keyContent.length139 : trimmedOffset + valueContent.length));140 if (!__BROWSER__ && context.prefixIdentifiers) {141 result.index = transformExpression_1.processExpression(result.index, context, true);142 }143 }144 }145 }146 if (valueContent) {147 result.value = createAliasExpression(loc, valueContent, trimmedOffset);148 if (!__BROWSER__ && context.prefixIdentifiers) {149 result.value = transformExpression_1.processExpression(result.value, context, true);150 }151 }152 return result;153}154exports.parseForExpression = parseForExpression;155function createAliasExpression(range, content, offset) {156 return ast_1.createSimpleExpression(content, false, utils_1.getInnerRange(range, offset, content.length));157}158function createForLoopParams(_a) {159 var value = _a.value, key = _a.key, index = _a.index;160 var params = [];161 if (value) {162 params.push(value);163 }164 if (key) {165 if (!value) {166 params.push(ast_1.createSimpleExpression("_", false));167 }168 params.push(key);169 }170 if (index) {171 if (!key) {172 if (!value) {...

Full Screen

Full Screen

vSlot.js

Source:vSlot.js Github

copy

Full Screen

...129 dynamicSlots.push(130 createCallExpression(context.helper(RENDER_LIST), [131 parseResult.source,132 createFunctionExpression(133 createForLoopParams(parseResult),134 buildDynamicSlot(slotName, slotFunction),135 true136 )137 ])138 )139 } else {140 }141 } else {142 if (staticSlotName) {143 if (seenSlotNames.has(staticSlotName)) {144 continue145 }146 seenSlotNames.add(staticSlotName)147 if (staticSlotName === 'default') {...

Full Screen

Full Screen

disableTracking.js

Source:disableTracking.js Github

copy

Full Screen

...99 helper(OPEN_BLOCK);100 helper(CREATE_BLOCK);101 }102 }103 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));104 };105 });...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const { createForLoopParams } = require('playwright/lib/utils/forLoopParams');2const forLoopParams = createForLoopParams({3});4console.log(forLoopParams);5const { createForLoopParams } = require('playwright');6const forLoopParams = createForLoopParams({7});8console.log(forLoopParams);9import { createForLoopParams } from 'playwright/lib/utils/forLoopParams';10const forLoopParams = createForLoopParams({11});12console.log(forLoopParams);13import { createForLoopParams } from 'playwright';14const forLoopParams = createForLoopParams({15});16console.log(forLoopParams);17const { createForLoopParams } = require('playwright/lib/utils/forLoopParams');18const forLoopParams = createForLoopParams({19});20console.log(forLoopParams);21const { createForLoopParams } = require('playwright');22const forLoopParams = createForLoopParams({23});24console.log(forLoopParams);25import { createForLoopParams } from 'playwright/lib/utils/forLoopParams';26const forLoopParams = createForLoopParams({

Full Screen

Using AI Code Generation

copy

Full Screen

1const { createForLoopParams } = require('playwright/lib/utils/forLoopParams');2const { test } = require('@playwright/test');3test('test', async ({ page }) => {4 const params = createForLoopParams(0, 10, 1);5 console.log(params);6});7test('test', async ({ page }) => {8 const params = createForLoopParams(0, 10, 1);9 for (const param of params) {10 console.log(param.value);11 }12});13test('test', async ({ page }) => {14 const params = createForLoopParams(0, 10, 1);15 for (const param of params) {16 await page.click(`button:nth-of-type(${param.value})`);17 }18});19test('test', async ({ page }) => {20 const params = createForLoopParams(0, 10, 1);21 for (const param of params) {22 await page.click(`button:nth-of-type(${param.index})`);23 }24});

Full Screen

Using AI Code Generation

copy

Full Screen

1const { createForLoopParams } = require('playwright/lib/utils/params');2const params = createForLoopParams(['a', 'b', 'c'], [1, 2, 3], [4, 5, 6]);3console.log(params);4const { createForLoopParams } = require('playwright/lib/utils/params');5const params = createForLoopParams(['a', 'b'], [1, 2, 3], [4, 5, 6]);6for (const param of params) {7 console.log(param);8}

Full Screen

Using AI Code Generation

copy

Full Screen

1const { createForLoopParams } = require('playwright/lib/internal/utils/forLoopParams');2const forLoopParams = createForLoopParams(1, 10, 2);3console.log(forLoopParams);4const { createForLoopParams } = require('playwright/lib/internal/utils/forLoopParams');5const forLoopParams = createForLoopParams(1, 10, 2);6console.log(forLoopParams);7const { createForLoopParams } = require('playwright/lib/internal/utils/forLoopParams');8const forLoopParams = createForLoopParams(1, 10, 2);9console.log(forLoopParams);10const { createForLoopParams } = require('playwright/lib/internal/utils/forLoopParams');11const forLoopParams = createForLoopParams(1, 10, 2);12console.log(forLoopParams);13const { createForLoopParams } = require('playwright/lib/internal/utils/forLoopParams');14const forLoopParams = createForLoopParams(1, 10, 2);15console.log(forLoopParams);16const { createForLoopParams } = require('playwright/lib/internal/utils/forLoopParams');17const forLoopParams = createForLoopParams(1, 10, 2);18console.log(forLoopParams);19const { createForLoopParams } = require('playwright/lib/internal/utils/forLoopParams');20const forLoopParams = createForLoopParams(1, 10, 2);21console.log(forLoopParams);22const { createForLoopParams } = require('playwright/lib/internal/utils/forLoopParams');23const forLoopParams = createForLoopParams(1, 10, 2);24console.log(forLoopParams);25const { createForLoopParams } = require('playwright/lib/internal/utils/forLoopParams');

Full Screen

Using AI Code Generation

copy

Full Screen

1const { createForLoopParams } = require('playwright/lib/utils/forLoopParams');2const forLoopParams = createForLoopParams(0, 10, 2);3console.log(forLoopParams);4const { createForLoopParams } = require('playwright/lib/utils/forLoopParams');5const forLoopParams = createForLoopParams(0, 10, 2);6console.log(forLoopParams);7const { createForLoopParams } = require('playwright/lib/utils/forLoopParams');8const forLoopParams = createForLoopParams(0, 10, 2);9console.log(forLoopParams);10const { createForLoopParams } = require('playwright/lib/utils/forLoopParams');11const forLoopParams = createForLoopParams(0, 10, 2);12console.log(forLoopParams);13const { createForLoopParams } = require('playwright/lib/utils/forLoopParams');14const forLoopParams = createForLoopParams(0, 10, 2);15console.log(forLoopParams);16const { createForLoopParams } = require('playwright/lib/utils/forLoopParams');17const forLoopParams = createForLoopParams(0, 10, 2);18console.log(forLoopParams);

Full Screen

Using AI Code Generation

copy

Full Screen

1const {createForLoopParams} = require('playwright/lib/internal/params');2const {test} = require('playwright/test');3test('test', async ({page}) => {4 const params = createForLoopParams({a: [1, 2, 3]});5 for (const {a} of params) {6 console.log(a);7 }8});9const {test} = require('@playwright/test');10test('test', async ({page}) => {11 await page.screenshot({ path: `example.png` });12});13 ✓ should display "hello world" (32ms)14 1 passing (1s)

Full Screen

Using AI Code Generation

copy

Full Screen

1const { createForLoopParams } = require('playwright/lib/params');2const { test } = require('playwright-test');3test('playwright test', async ({ page }) => {4 const params = createForLoopParams('i', 1, 5, 1);5 for (const i of params) {6 console.log(i);7 }8});

Full Screen

Using AI Code Generation

copy

Full Screen

1const { createForLoopParams } = require('playwright/lib/internal/recorder/params');2const forLoopParams = createForLoopParams('i', 0, 10, 1);3console.log(forLoopParams);4const { createForLoopParams } = require('playwright/lib/internal/recorder/params');5const forLoopParams = createForLoopParams('i', 0, 10, 1);6console.log(forLoopParams);7const { createForLoopParams } = require('playwright/lib/internal/recorder/params');8const forLoopParams = createForLoopParams('i', 0, 10, 1);9console.log(forLoopParams);10const { createForLoopParams } = require('playwright/lib/internal/recorder/params');11const forLoopParams = createForLoopParams('i', 0, 10, 1);12console.log(forLoopParams);13const { createForLoopParams } = require('playwright/lib/internal/recorder/params');14const forLoopParams = createForLoopParams('i', 0, 10, 1);15console.log(forLoopParams);16const { createForLoopParams } = require('playwright/lib/internal/recorder/params');17const forLoopParams = createForLoopParams('i', 0, 10, 1);18console.log(forLoopParams);19const { createForLoopParams } = require('playwright/lib/internal/recorder/params');20const forLoopParams = createForLoopParams('i', 0, 10, 1);21console.log(forLoopParams);22const { createForLoopParams } = require('playwright/lib/internal

Full Screen

Using AI Code Generation

copy

Full Screen

1const { createForLoopParams } = require('@playwright/test');2const testdata = require('./testdata.json');3const myParams = createForLoopParams(testdata);4module.exports = myParams;5 {6 },7 {8 }9const { test } = require('@playwright/test');10const params = require('./test.js');11test.use({ params });12test('my test', async ({ page }, params) => {13 await page.fill('input[name="q"]', params.data);14 await page.click('text=Search');15 const searchResults = page.locator('text=Results');16 await searchResults;17});

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