Best JavaScript code snippet using playwright-internal
compiler-dom.global.js
Source:compiler-dom.global.js
...267 [TO_HANDLERS]: `toHandlers`,268 [CAMELIZE]: `camelize`,269 [SET_BLOCK_TRACKING]: `setBlockTracking`270 };271 function registerRuntimeHelpers(helpers) {272 Object.getOwnPropertySymbols(helpers).forEach(s => {273 helperNameMap[s] = helpers[s];274 });275 }276 // cache node requires277 // lazy require dependencies so that they don't end up in rollup's dep graph278 // and thus can be tree-shaken in browser builds.279 let _parse;280 let _walk;281 function loadDep(name) {282 if (typeof process !== 'undefined' && isFunction(require)) {283 return require(name);284 }285 else {286 // This is only used when we are building a dev-only build of the compiler287 // which runs in the browser but also uses Node deps.288 return window._deps[name];289 }290 }291 const parseJS = (code, options) => {292 assert(!true, `Expression AST analysis can only be performed in non-browser builds.`);293 const parse = _parse || (_parse = loadDep('acorn').parse);294 return parse(code, options);295 };296 const walkJS = (ast, walker) => {297 assert(!true, `Expression AST analysis can only be performed in non-browser builds.`);298 const walk = _walk || (_walk = loadDep('estree-walker').walk);299 return walk(ast, walker);300 };301 const nonIdentifierRE = /^\d|[^\$\w]/;302 const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);303 const memberExpRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\[[^\]]+\])*$/;304 const isMemberExpression = (path) => memberExpRE.test(path);305 function getInnerRange(loc, offset, length) {306 assert(offset <= loc.source.length);307 const source = loc.source.substr(offset, length);308 const newLoc = {309 source,310 start: advancePositionWithClone(loc.start, loc.source, offset),311 end: loc.end312 };313 if (length != null) {314 assert(offset + length <= loc.source.length);315 newLoc.end = advancePositionWithClone(loc.start, loc.source, offset + length);316 }317 return newLoc;318 }319 function advancePositionWithClone(pos, source, numberOfCharacters = source.length) {320 return advancePositionWithMutation({ ...pos }, source, numberOfCharacters);321 }322 // advance by mutation without cloning (for performance reasons), since this323 // gets called a lot in the parser324 function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) {325 let linesCount = 0;326 let lastNewLinePos = -1;327 for (let i = 0; i < numberOfCharacters; i++) {328 if (source.charCodeAt(i) === 10 /* newline char code */) {329 linesCount++;330 lastNewLinePos = i;331 }332 }333 pos.offset += numberOfCharacters;334 pos.line += linesCount;335 pos.column =336 lastNewLinePos === -1337 ? pos.column + numberOfCharacters338 : Math.max(1, numberOfCharacters - lastNewLinePos);339 return pos;340 }341 function assert(condition, msg) {342 /* istanbul ignore if */343 if (!condition) {344 throw new Error(msg || `unexpected compiler condition`);345 }346 }347 function findDir(node, name, allowEmpty = false) {348 for (let i = 0; i < node.props.length; i++) {349 const p = node.props[i];350 if (p.type === 7 /* DIRECTIVE */ &&351 (allowEmpty || p.exp) &&352 (isString(name) ? p.name === name : name.test(p.name))) {353 return p;354 }355 }356 }357 function findProp(node, name, dynamicOnly = false) {358 for (let i = 0; i < node.props.length; i++) {359 const p = node.props[i];360 if (p.type === 6 /* ATTRIBUTE */) {361 if (dynamicOnly)362 continue;363 if (p.name === name && p.value) {364 return p;365 }366 }367 else if (p.name === 'bind' &&368 p.arg &&369 p.arg.type === 4 /* SIMPLE_EXPRESSION */ &&370 p.arg.isStatic &&371 p.arg.content === name &&372 p.exp) {373 return p;374 }375 }376 }377 function createBlockExpression(blockExp, context) {378 return createSequenceExpression([379 createCallExpression(context.helper(OPEN_BLOCK)),380 blockExp381 ]);382 }383 function isVSlot(p) {384 return p.type === 7 /* DIRECTIVE */ && p.name === 'slot';385 }386 function isTemplateNode(node) {387 return (node.type === 1 /* ELEMENT */ && node.tagType === 3 /* TEMPLATE */);388 }389 function isSlotOutlet(node) {390 return node.type === 1 /* ELEMENT */ && node.tagType === 2 /* SLOT */;391 }392 function injectProp(node, prop, context) {393 let propsWithInjection;394 const props = node.callee === RENDER_SLOT ? node.arguments[2] : node.arguments[1];395 if (props == null || isString(props)) {396 propsWithInjection = createObjectExpression([prop]);397 }398 else if (props.type === 13 /* JS_CALL_EXPRESSION */) {399 // merged props... add ours400 // only inject key to object literal if it's the first argument so that401 // if doesn't override user provided keys402 const first = props.arguments[0];403 if (!isString(first) && first.type === 14 /* JS_OBJECT_EXPRESSION */) {404 first.properties.unshift(prop);405 }406 else {407 props.arguments.unshift(createObjectExpression([prop]));408 }409 propsWithInjection = props;410 }411 else if (props.type === 14 /* JS_OBJECT_EXPRESSION */) {412 props.properties.unshift(prop);413 propsWithInjection = props;414 }415 else {416 // single v-bind with expression, return a merged replacement417 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [418 createObjectExpression([prop]),419 props420 ]);421 }422 if (node.callee === RENDER_SLOT) {423 node.arguments[2] = propsWithInjection;424 }425 else {426 node.arguments[1] = propsWithInjection;427 }428 }429 function toValidAssetId(name, type) {430 return `_${type}_${name.replace(/[^\w]/g, '_')}`;431 }432 // Check if a node contains expressions that reference current context scope ids433 function hasScopeRef(node, ids) {434 if (!node || Object.keys(ids).length === 0) {435 return false;436 }437 switch (node.type) {438 case 1 /* ELEMENT */:439 for (let i = 0; i < node.props.length; i++) {440 const p = node.props[i];441 if (p.type === 7 /* DIRECTIVE */ &&442 (hasScopeRef(p.arg, ids) || hasScopeRef(p.exp, ids))) {443 return true;444 }445 }446 return node.children.some(c => hasScopeRef(c, ids));447 case 11 /* FOR */:448 if (hasScopeRef(node.source, ids)) {449 return true;450 }451 return node.children.some(c => hasScopeRef(c, ids));452 case 9 /* IF */:453 return node.branches.some(b => hasScopeRef(b, ids));454 case 10 /* IF_BRANCH */:455 if (hasScopeRef(node.condition, ids)) {456 return true;457 }458 return node.children.some(c => hasScopeRef(c, ids));459 case 4 /* SIMPLE_EXPRESSION */:460 return (!node.isStatic &&461 isSimpleIdentifier(node.content) &&462 !!ids[node.content]);463 case 8 /* COMPOUND_EXPRESSION */:464 return node.children.some(c => isObject(c) && hasScopeRef(c, ids));465 case 5 /* INTERPOLATION */:466 case 12 /* TEXT_CALL */:467 return hasScopeRef(node.content, ids);468 case 2 /* TEXT */:469 case 3 /* COMMENT */:470 return false;471 default:472 return false;473 }474 }475 const defaultParserOptions = {476 delimiters: [`{{`, `}}`],477 getNamespace: () => 0 /* HTML */,478 getTextMode: () => 0 /* DATA */,479 isVoidTag: NO,480 isPreTag: NO,481 isCustomElement: NO,482 namedCharacterReferences: {483 'gt;': '>',484 'lt;': '<',485 'amp;': '&',486 'apos;': "'",487 'quot;': '"'488 },489 onError: defaultOnError490 };491 function parse(content, options = {}) {492 const context = createParserContext(content, options);493 const start = getCursor(context);494 return {495 type: 0 /* ROOT */,496 children: parseChildren(context, 0 /* DATA */, []),497 helpers: [],498 components: [],499 directives: [],500 hoists: [],501 cached: 0,502 codegenNode: undefined,503 loc: getSelection(context, start)504 };505 }506 function createParserContext(content, options) {507 return {508 options: {509 ...defaultParserOptions,510 ...options511 },512 column: 1,513 line: 1,514 offset: 0,515 originalSource: content,516 source: content,517 maxCRNameLength: Object.keys(options.namedCharacterReferences ||518 defaultParserOptions.namedCharacterReferences).reduce((max, name) => Math.max(max, name.length), 0),519 inPre: false520 };521 }522 function parseChildren(context, mode, ancestors) {523 const parent = last(ancestors);524 const ns = parent ? parent.ns : 0 /* HTML */;525 const nodes = [];526 while (!isEnd(context, mode, ancestors)) {527 assert(context.source.length > 0);528 const s = context.source;529 let node = undefined;530 if (!context.inPre && startsWith(s, context.options.delimiters[0])) {531 // '{{'532 node = parseInterpolation(context, mode);533 }534 else if (mode === 0 /* DATA */ && s[0] === '<') {535 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state536 if (s.length === 1) {537 emitError(context, 8 /* EOF_BEFORE_TAG_NAME */, 1);538 }539 else if (s[1] === '!') {540 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state541 if (startsWith(s, '<!--')) {542 node = parseComment(context);543 }544 else if (startsWith(s, '<!DOCTYPE')) {545 // Ignore DOCTYPE by a limitation.546 node = parseBogusComment(context);547 }548 else if (startsWith(s, '<![CDATA[')) {549 if (ns !== 0 /* HTML */) {550 node = parseCDATA(context, ancestors);551 }552 else {553 emitError(context, 2 /* CDATA_IN_HTML_CONTENT */);554 node = parseBogusComment(context);555 }556 }557 else {558 emitError(context, 14 /* INCORRECTLY_OPENED_COMMENT */);559 node = parseBogusComment(context);560 }561 }562 else if (s[1] === '/') {563 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state564 if (s.length === 2) {565 emitError(context, 8 /* EOF_BEFORE_TAG_NAME */, 2);566 }567 else if (s[2] === '>') {568 emitError(context, 17 /* MISSING_END_TAG_NAME */, 2);569 advanceBy(context, 3);570 continue;571 }572 else if (/[a-z]/i.test(s[2])) {573 emitError(context, 31 /* X_INVALID_END_TAG */);574 parseTag(context, 1 /* End */, parent);575 continue;576 }577 else {578 emitError(context, 15 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);579 node = parseBogusComment(context);580 }581 }582 else if (/[a-z]/i.test(s[1])) {583 node = parseElement(context, ancestors);584 }585 else if (s[1] === '?') {586 emitError(context, 28 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);587 node = parseBogusComment(context);588 }589 else {590 emitError(context, 15 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);591 }592 }593 if (!node) {594 node = parseText(context, mode);595 }596 if (Array.isArray(node)) {597 for (let i = 0; i < node.length; i++) {598 pushNode(nodes, node[i]);599 }600 }601 else {602 pushNode(nodes, node);603 }604 }605 // Whitespace management for more efficient output606 // (same as v2 whitespance: 'condense')607 let removedWhitespace = false;608 if (!parent || !context.options.isPreTag(parent.tag)) {609 for (let i = 0; i < nodes.length; i++) {610 const node = nodes[i];611 if (node.type === 2 /* TEXT */) {612 if (!node.content.trim()) {613 const prev = nodes[i - 1];614 const next = nodes[i + 1];615 // If:616 // - the whitespace is the first or last node, or:617 // - the whitespace is adjacent to a comment, or:618 // - the whitespace is between two elements AND contains newline619 // Then the whitespace is ignored.620 if (!prev ||621 !next ||622 prev.type === 3 /* COMMENT */ ||623 next.type === 3 /* COMMENT */ ||624 (prev.type === 1 /* ELEMENT */ &&625 next.type === 1 /* ELEMENT */ &&626 /[\r\n]/.test(node.content))) {627 removedWhitespace = true;628 nodes[i] = null;629 }630 else {631 // Otherwise, condensed consecutive whitespace inside the text down to632 // a single space633 node.content = ' ';634 }635 }636 else {637 node.content = node.content.replace(/\s+/g, ' ');638 }639 }640 }641 }642 return removedWhitespace ? nodes.filter(node => node !== null) : nodes;643 }644 function pushNode(nodes, node) {645 if (node.type === 2 /* TEXT */) {646 const prev = last(nodes);647 // Merge if both this and the previous node are text and those are648 // consecutive. This happens for cases like "a < b".649 if (prev &&650 prev.type === 2 /* TEXT */ &&651 prev.loc.end.offset === node.loc.start.offset) {652 prev.content += node.content;653 prev.loc.end = node.loc.end;654 prev.loc.source += node.loc.source;655 return;656 }657 }658 nodes.push(node);659 }660 function parseCDATA(context, ancestors) {661 662 assert(last(ancestors) == null || last(ancestors).ns !== 0 /* HTML */);663 assert(startsWith(context.source, '<![CDATA['));664 advanceBy(context, 9);665 const nodes = parseChildren(context, 3 /* CDATA */, ancestors);666 if (context.source.length === 0) {667 emitError(context, 9 /* EOF_IN_CDATA */);668 }669 else {670 assert(startsWith(context.source, ']]>'));671 advanceBy(context, 3);672 }673 return nodes;674 }675 function parseComment(context) {676 assert(startsWith(context.source, '<!--'));677 const start = getCursor(context);678 let content;679 // Regular comment.680 const match = /--(\!)?>/.exec(context.source);681 if (!match) {682 content = context.source.slice(4);683 advanceBy(context, context.source.length);684 emitError(context, 10 /* EOF_IN_COMMENT */);685 }686 else {687 if (match.index <= 3) {688 emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);689 }690 if (match[1]) {691 emitError(context, 13 /* INCORRECTLY_CLOSED_COMMENT */);692 }693 content = context.source.slice(4, match.index);694 // Advancing with reporting nested comments.695 const s = context.source.slice(0, match.index);696 let prevIndex = 1, nestedIndex = 0;697 while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {698 advanceBy(context, nestedIndex - prevIndex + 1);699 if (nestedIndex + 4 < s.length) {700 emitError(context, 20 /* NESTED_COMMENT */);701 }702 prevIndex = nestedIndex + 1;703 }704 advanceBy(context, match.index + match[0].length - prevIndex + 1);705 }706 return {707 type: 3 /* COMMENT */,708 content,709 loc: getSelection(context, start)710 };711 }712 function parseBogusComment(context) {713 assert(/^<(?:[\!\?]|\/[^a-z>])/i.test(context.source));714 const start = getCursor(context);715 const contentStart = context.source[1] === '?' ? 1 : 2;716 let content;717 const closeIndex = context.source.indexOf('>');718 if (closeIndex === -1) {719 content = context.source.slice(contentStart);720 advanceBy(context, context.source.length);721 }722 else {723 content = context.source.slice(contentStart, closeIndex);724 advanceBy(context, closeIndex + 1);725 }726 return {727 type: 3 /* COMMENT */,728 content,729 loc: getSelection(context, start)730 };731 }732 function parseElement(context, ancestors) {733 assert(/^<[a-z]/i.test(context.source));734 // Start tag.735 const wasInPre = context.inPre;736 const parent = last(ancestors);737 const element = parseTag(context, 0 /* Start */, parent);738 const isPreBoundary = context.inPre && !wasInPre;739 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {740 return element;741 }742 // Children.743 ancestors.push(element);744 const mode = context.options.getTextMode(element.tag, element.ns);745 const children = parseChildren(context, mode, ancestors);746 ancestors.pop();747 element.children = children;748 // End tag.749 if (startsWithEndTagOpen(context.source, element.tag)) {750 parseTag(context, 1 /* End */, parent);751 }752 else {753 emitError(context, 32 /* X_MISSING_END_TAG */);754 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {755 const first = children[0];756 if (first && startsWith(first.loc.source, '<!--')) {757 emitError(context, 11 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);758 }759 }760 }761 element.loc = getSelection(context, element.loc.start);762 if (isPreBoundary) {763 context.inPre = false;764 }765 return element;766 }767 /**768 * Parse a tag (E.g. `<div id=a>`) with that type (start tag or end tag).769 */770 function parseTag(context, type, parent) {771 assert(/^<\/?[a-z]/i.test(context.source));772 773 assert(type === (startsWith(context.source, '</') ? 1 /* End */ : 0 /* Start */));774 // Tag open.775 const start = getCursor(context);776 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);777 const tag = match[1];778 const ns = context.options.getNamespace(tag, parent);779 advanceBy(context, match[0].length);780 advanceSpaces(context);781 // save current state in case we need to re-parse attributes with v-pre782 const cursor = getCursor(context);783 const currentSource = context.source;784 // Attributes.785 let props = parseAttributes(context, type);786 // check v-pre787 if (!context.inPre &&788 props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {789 context.inPre = true;790 // reset context791 extend(context, cursor);792 context.source = currentSource;793 // re-parse attrs and filter out v-pre itself794 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');795 }796 // Tag close.797 let isSelfClosing = false;798 if (context.source.length === 0) {799 emitError(context, 12 /* EOF_IN_TAG */);800 }801 else {802 isSelfClosing = startsWith(context.source, '/>');803 if (type === 1 /* End */ && isSelfClosing) {804 emitError(context, 7 /* END_TAG_WITH_TRAILING_SOLIDUS */);805 }806 advanceBy(context, isSelfClosing ? 2 : 1);807 }808 let tagType = 0 /* ELEMENT */;809 if (!context.inPre && !context.options.isCustomElement(tag)) {810 if (context.options.isNativeTag) {811 if (!context.options.isNativeTag(tag))812 tagType = 1 /* COMPONENT */;813 }814 else {815 if (/^[A-Z]/.test(tag))816 tagType = 1 /* COMPONENT */;817 }818 if (tag === 'slot')819 tagType = 2 /* SLOT */;820 else if (tag === 'template')821 tagType = 3 /* TEMPLATE */;822 else if (tag === 'portal' || tag === 'Portal')823 tagType = 4 /* PORTAL */;824 else if (tag === 'suspense' || tag === 'Suspense')825 tagType = 5 /* SUSPENSE */;826 }827 return {828 type: 1 /* ELEMENT */,829 ns,830 tag,831 tagType,832 props,833 isSelfClosing,834 children: [],835 loc: getSelection(context, start),836 codegenNode: undefined // to be created during transform phase837 };838 }839 function parseAttributes(context, type) {840 const props = [];841 const attributeNames = new Set();842 while (context.source.length > 0 &&843 !startsWith(context.source, '>') &&844 !startsWith(context.source, '/>')) {845 if (startsWith(context.source, '/')) {846 emitError(context, 29 /* UNEXPECTED_SOLIDUS_IN_TAG */);847 advanceBy(context, 1);848 advanceSpaces(context);849 continue;850 }851 if (type === 1 /* End */) {852 emitError(context, 6 /* END_TAG_WITH_ATTRIBUTES */);853 }854 const attr = parseAttribute(context, attributeNames);855 if (type === 0 /* Start */) {856 props.push(attr);857 }858 if (/^[^\t\r\n\f />]/.test(context.source)) {859 emitError(context, 19 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);860 }861 advanceSpaces(context);862 }863 return props;864 }865 function parseAttribute(context, nameSet) {866 assert(/^[^\t\r\n\f />]/.test(context.source));867 // Name.868 const start = getCursor(context);869 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);870 const name = match[0];871 if (nameSet.has(name)) {872 emitError(context, 5 /* DUPLICATE_ATTRIBUTE */);873 }874 nameSet.add(name);875 if (name[0] === '=') {876 emitError(context, 26 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);877 }878 {879 const pattern = /["'<]/g;880 let m;881 while ((m = pattern.exec(name)) !== null) {882 emitError(context, 24 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);883 }884 }885 advanceBy(context, name.length);886 // Value887 let value = undefined;888 if (/^[\t\r\n\f ]*=/.test(context.source)) {889 advanceSpaces(context);890 advanceBy(context, 1);891 advanceSpaces(context);892 value = parseAttributeValue(context);893 if (!value) {894 emitError(context, 16 /* MISSING_ATTRIBUTE_VALUE */);895 }896 }897 const loc = getSelection(context, start);898 if (!context.inPre && /^(v-|:|@|#)/.test(name)) {899 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^@|^#)([^\.]+))?(.+)?$/i.exec(name);900 let arg;901 if (match[2]) {902 const startOffset = name.split(match[2], 2).shift().length;903 const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length));904 let content = match[2];905 let isStatic = true;906 if (content.startsWith('[')) {907 isStatic = false;908 if (!content.endsWith(']')) {909 emitError(context, 34 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);910 }911 content = content.substr(1, content.length - 2);912 }913 arg = {914 type: 4 /* SIMPLE_EXPRESSION */,915 content,916 isStatic,917 isConstant: isStatic,918 loc919 };920 }921 if (value && value.isQuoted) {922 const valueLoc = value.loc;923 valueLoc.start.offset++;924 valueLoc.start.column++;925 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);926 valueLoc.source = valueLoc.source.slice(1, -1);927 }928 return {929 type: 7 /* DIRECTIVE */,930 name: match[1] ||931 (startsWith(name, ':')932 ? 'bind'933 : startsWith(name, '@')934 ? 'on'935 : 'slot'),936 exp: value && {937 type: 4 /* SIMPLE_EXPRESSION */,938 content: value.content,939 isStatic: false,940 // Treat as non-constant by default. This can be potentially set to941 // true by `transformExpression` to make it eligible for hoisting.942 isConstant: false,943 loc: value.loc944 },945 arg,946 modifiers: match[3] ? match[3].substr(1).split('.') : [],947 loc948 };949 }950 return {951 type: 6 /* ATTRIBUTE */,952 name,953 value: value && {954 type: 2 /* TEXT */,955 content: value.content,956 loc: value.loc957 },958 loc959 };960 }961 function parseAttributeValue(context) {962 const start = getCursor(context);963 let content;964 const quote = context.source[0];965 const isQuoted = quote === `"` || quote === `'`;966 if (isQuoted) {967 // Quoted value.968 advanceBy(context, 1);969 const endIndex = context.source.indexOf(quote);970 if (endIndex === -1) {971 content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);972 }973 else {974 content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);975 advanceBy(context, 1);976 }977 }978 else {979 // Unquoted980 const match = /^[^\t\r\n\f >]+/.exec(context.source);981 if (!match) {982 return undefined;983 }984 let unexpectedChars = /["'<=`]/g;985 let m;986 while ((m = unexpectedChars.exec(match[0])) !== null) {987 emitError(context, 25 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);988 }989 content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);990 }991 return { content, isQuoted, loc: getSelection(context, start) };992 }993 function parseInterpolation(context, mode) {994 const [open, close] = context.options.delimiters;995 assert(startsWith(context.source, open));996 const closeIndex = context.source.indexOf(close, open.length);997 if (closeIndex === -1) {998 emitError(context, 33 /* X_MISSING_INTERPOLATION_END */);999 return undefined;1000 }1001 const start = getCursor(context);1002 advanceBy(context, open.length);1003 const innerStart = getCursor(context);1004 const innerEnd = getCursor(context);1005 const rawContentLength = closeIndex - open.length;1006 const rawContent = context.source.slice(0, rawContentLength);1007 const preTrimContent = parseTextData(context, rawContentLength, mode);1008 const content = preTrimContent.trim();1009 const startOffset = preTrimContent.indexOf(content);1010 if (startOffset > 0) {1011 advancePositionWithMutation(innerStart, rawContent, startOffset);1012 }1013 const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);1014 advancePositionWithMutation(innerEnd, rawContent, endOffset);1015 advanceBy(context, close.length);1016 return {1017 type: 5 /* INTERPOLATION */,1018 content: {1019 type: 4 /* SIMPLE_EXPRESSION */,1020 isStatic: false,1021 // Set `isConstant` to false by default and will decide in transformExpression1022 isConstant: false,1023 content,1024 loc: getSelection(context, innerStart, innerEnd)1025 },1026 loc: getSelection(context, start)1027 };1028 }1029 function parseText(context, mode) {1030 assert(context.source.length > 0);1031 const [open] = context.options.delimiters;1032 // TODO could probably use some perf optimization1033 const endIndex = Math.min(...[1034 context.source.indexOf('<', 1),1035 context.source.indexOf(open, 1),1036 mode === 3 /* CDATA */ ? context.source.indexOf(']]>') : -1,1037 context.source.length1038 ].filter(n => n !== -1));1039 assert(endIndex > 0);1040 const start = getCursor(context);1041 const content = parseTextData(context, endIndex, mode);1042 return {1043 type: 2 /* TEXT */,1044 content,1045 loc: getSelection(context, start)1046 };1047 }1048 /**1049 * Get text data with a given length from the current location.1050 * This translates HTML entities in the text data.1051 */1052 function parseTextData(context, length, mode) {1053 if (mode === 2 /* RAWTEXT */ || mode === 3 /* CDATA */) {1054 const text = context.source.slice(0, length);1055 advanceBy(context, length);1056 return text;1057 }1058 // DATA or RCDATA. Entity decoding required.1059 const end = context.offset + length;1060 let text = '';1061 while (context.offset < end) {1062 const head = /&(?:#x?)?/i.exec(context.source);1063 if (!head || context.offset + head.index >= end) {1064 const remaining = end - context.offset;1065 text += context.source.slice(0, remaining);1066 advanceBy(context, remaining);1067 break;1068 }1069 // Advance to the "&".1070 text += context.source.slice(0, head.index);1071 advanceBy(context, head.index);1072 if (head[0] === '&') {1073 // Named character reference.1074 let name = '', value = undefined;1075 if (/[0-9a-z]/i.test(context.source[1])) {1076 for (let length = context.maxCRNameLength; !value && length > 0; --length) {1077 name = context.source.substr(1, length);1078 value = context.options.namedCharacterReferences[name];1079 }1080 if (value) {1081 const semi = name.endsWith(';');1082 if (mode === 4 /* ATTRIBUTE_VALUE */ &&1083 !semi &&1084 /[=a-z0-9]/i.test(context.source[1 + name.length] || '')) {1085 text += '&';1086 text += name;1087 advanceBy(context, 1 + name.length);1088 }1089 else {1090 text += value;1091 advanceBy(context, 1 + name.length);1092 if (!semi) {1093 emitError(context, 18 /* MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE */);1094 }1095 }1096 }1097 else {1098 emitError(context, 30 /* UNKNOWN_NAMED_CHARACTER_REFERENCE */);1099 text += '&';1100 text += name;1101 advanceBy(context, 1 + name.length);1102 }1103 }1104 else {1105 text += '&';1106 advanceBy(context, 1);1107 }1108 }1109 else {1110 // Numeric character reference.1111 const hex = head[0] === '&#x';1112 const pattern = hex ? /^&#x([0-9a-f]+);?/i : /^&#([0-9]+);?/;1113 const body = pattern.exec(context.source);1114 if (!body) {1115 text += head[0];1116 emitError(context, 1 /* ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE */);1117 advanceBy(context, head[0].length);1118 }1119 else {1120 // https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state1121 let cp = Number.parseInt(body[1], hex ? 16 : 10);1122 if (cp === 0) {1123 emitError(context, 22 /* NULL_CHARACTER_REFERENCE */);1124 cp = 0xfffd;1125 }1126 else if (cp > 0x10ffff) {1127 emitError(context, 3 /* CHARACTER_REFERENCE_OUTSIDE_UNICODE_RANGE */);1128 cp = 0xfffd;1129 }1130 else if (cp >= 0xd800 && cp <= 0xdfff) {1131 emitError(context, 23 /* SURROGATE_CHARACTER_REFERENCE */);1132 cp = 0xfffd;1133 }1134 else if ((cp >= 0xfdd0 && cp <= 0xfdef) || (cp & 0xfffe) === 0xfffe) {1135 emitError(context, 21 /* NONCHARACTER_CHARACTER_REFERENCE */);1136 }1137 else if ((cp >= 0x01 && cp <= 0x08) ||1138 cp === 0x0b ||1139 (cp >= 0x0d && cp <= 0x1f) ||1140 (cp >= 0x7f && cp <= 0x9f)) {1141 emitError(context, 4 /* CONTROL_CHARACTER_REFERENCE */);1142 cp = CCR_REPLACEMENTS[cp] || cp;1143 }1144 text += String.fromCodePoint(cp);1145 advanceBy(context, body[0].length);1146 if (!body[0].endsWith(';')) {1147 emitError(context, 18 /* MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE */);1148 }1149 }1150 }1151 }1152 return text;1153 }1154 function getCursor(context) {1155 const { column, line, offset } = context;1156 return { column, line, offset };1157 }1158 function getSelection(context, start, end) {1159 end = end || getCursor(context);1160 return {1161 start,1162 end,1163 source: context.originalSource.slice(start.offset, end.offset)1164 };1165 }1166 function last(xs) {1167 return xs[xs.length - 1];1168 }1169 function startsWith(source, searchString) {1170 return source.startsWith(searchString);1171 }1172 function advanceBy(context, numberOfCharacters) {1173 const { source } = context;1174 assert(numberOfCharacters <= source.length);1175 advancePositionWithMutation(context, source, numberOfCharacters);1176 context.source = source.slice(numberOfCharacters);1177 }1178 function advanceSpaces(context) {1179 const match = /^[\t\r\n\f ]+/.exec(context.source);1180 if (match) {1181 advanceBy(context, match[0].length);1182 }1183 }1184 function getNewPosition(context, start, numberOfCharacters) {1185 return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);1186 }1187 function emitError(context, code, offset) {1188 const loc = getCursor(context);1189 if (offset) {1190 loc.offset += offset;1191 loc.column += offset;1192 }1193 context.options.onError(createCompilerError(code, {1194 start: loc,1195 end: loc,1196 source: ''1197 }));1198 }1199 function isEnd(context, mode, ancestors) {1200 const s = context.source;1201 switch (mode) {1202 case 0 /* DATA */:1203 if (startsWith(s, '</')) {1204 //TODO: probably bad performance1205 for (let i = ancestors.length - 1; i >= 0; --i) {1206 if (startsWithEndTagOpen(s, ancestors[i].tag)) {1207 return true;1208 }1209 }1210 }1211 break;1212 case 1 /* RCDATA */:1213 case 2 /* RAWTEXT */: {1214 const parent = last(ancestors);1215 if (parent && startsWithEndTagOpen(s, parent.tag)) {1216 return true;1217 }1218 break;1219 }1220 case 3 /* CDATA */:1221 if (startsWith(s, ']]>')) {1222 return true;1223 }1224 break;1225 }1226 return !s;1227 }1228 function startsWithEndTagOpen(source, tag) {1229 return (startsWith(source, '</') &&1230 source.substr(2, tag.length).toLowerCase() === tag.toLowerCase() &&1231 /[\t\n\f />]/.test(source[2 + tag.length] || '>'));1232 }1233 // https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state1234 const CCR_REPLACEMENTS = {1235 0x80: 0x20ac,1236 0x82: 0x201a,1237 0x83: 0x0192,1238 0x84: 0x201e,1239 0x85: 0x2026,1240 0x86: 0x2020,1241 0x87: 0x2021,1242 0x88: 0x02c6,1243 0x89: 0x2030,1244 0x8a: 0x0160,1245 0x8b: 0x2039,1246 0x8c: 0x0152,1247 0x8e: 0x017d,1248 0x91: 0x2018,1249 0x92: 0x2019,1250 0x93: 0x201c,1251 0x94: 0x201d,1252 0x95: 0x2022,1253 0x96: 0x2013,1254 0x97: 0x2014,1255 0x98: 0x02dc,1256 0x99: 0x2122,1257 0x9a: 0x0161,1258 0x9b: 0x203a,1259 0x9c: 0x0153,1260 0x9e: 0x017e,1261 0x9f: 0x01781262 };1263 function hoistStatic(root, context) {1264 walk(root.children, context, new Map(), isSingleElementRoot(root, root.children[0]));1265 }1266 function isSingleElementRoot(root, child) {1267 const { children } = root;1268 return (children.length === 1 &&1269 child.type === 1 /* ELEMENT */ &&1270 !isSlotOutlet(child));1271 }1272 function walk(children, context, resultCache, doNotHoistNode = false) {1273 for (let i = 0; i < children.length; i++) {1274 const child = children[i];1275 // only plain elements are eligible for hoisting.1276 if (child.type === 1 /* ELEMENT */ &&1277 child.tagType === 0 /* ELEMENT */) {1278 if (!doNotHoistNode && isStaticNode(child, resultCache)) {1279 // whole tree is static1280 child.codegenNode = context.hoist(child.codegenNode);1281 continue;1282 }1283 else {1284 // node may contain dynamic children, but its props may be eligible for1285 // hoisting.1286 const codegenNode = child.codegenNode;1287 if (codegenNode.type === 13 /* JS_CALL_EXPRESSION */) {1288 const flag = getPatchFlag(codegenNode);1289 if ((!flag ||1290 flag === 32 /* NEED_PATCH */ ||1291 flag === 1 /* TEXT */) &&1292 !hasDynamicKeyOrRef(child) &&1293 !hasCachedProps()) {1294 const props = getNodeProps(child);1295 if (props && props !== `null`) {1296 getVNodeCall(codegenNode).arguments[1] = context.hoist(props);1297 }1298 }1299 }1300 }1301 }1302 if (child.type === 1 /* ELEMENT */) {1303 walk(child.children, context, resultCache);1304 }1305 else if (child.type === 11 /* FOR */) {1306 // Do not hoist v-for single child because it has to be a block1307 walk(child.children, context, resultCache, child.children.length === 1);1308 }1309 else if (child.type === 9 /* IF */) {1310 for (let i = 0; i < child.branches.length; i++) {1311 const branchChildren = child.branches[i].children;1312 // Do not hoist v-if single child because it has to be a block1313 walk(branchChildren, context, resultCache, branchChildren.length === 1);1314 }1315 }1316 }1317 }1318 function isStaticNode(node, resultCache = new Map()) {1319 switch (node.type) {1320 case 1 /* ELEMENT */:1321 if (node.tagType !== 0 /* ELEMENT */) {1322 return false;1323 }1324 const cached = resultCache.get(node);1325 if (cached !== undefined) {1326 return cached;1327 }1328 const codegenNode = node.codegenNode;1329 if (codegenNode.type !== 13 /* JS_CALL_EXPRESSION */) {1330 return false;1331 }1332 const flag = getPatchFlag(codegenNode);1333 if (!flag && !hasDynamicKeyOrRef(node) && !hasCachedProps()) {1334 // element self is static. check its children.1335 for (let i = 0; i < node.children.length; i++) {1336 if (!isStaticNode(node.children[i], resultCache)) {1337 resultCache.set(node, false);1338 return false;1339 }1340 }1341 resultCache.set(node, true);1342 return true;1343 }1344 else {1345 resultCache.set(node, false);1346 return false;1347 }1348 case 2 /* TEXT */:1349 case 3 /* COMMENT */:1350 return true;1351 case 9 /* IF */:1352 case 11 /* FOR */:1353 return false;1354 case 5 /* INTERPOLATION */:1355 case 12 /* TEXT_CALL */:1356 return isStaticNode(node.content, resultCache);1357 case 4 /* SIMPLE_EXPRESSION */:1358 return node.isConstant;1359 case 8 /* COMPOUND_EXPRESSION */:1360 return node.children.every(child => {1361 return (isString(child) || isSymbol(child) || isStaticNode(child, resultCache));1362 });1363 default:1364 return false;1365 }1366 }1367 function hasDynamicKeyOrRef(node) {1368 return !!(findProp(node, 'key', true) || findProp(node, 'ref', true));1369 }1370 function hasCachedProps(node) {1371 {1372 return false;1373 }1374 }1375 function getNodeProps(node) {1376 const codegenNode = node.codegenNode;1377 if (codegenNode.type === 13 /* JS_CALL_EXPRESSION */) {1378 return getVNodeArgAt(codegenNode, 1);1379 }1380 }1381 function getVNodeArgAt(node, index) {1382 return getVNodeCall(node).arguments[index];1383 }1384 function getVNodeCall(node) {1385 return node.callee === WITH_DIRECTIVES ? node.arguments[0] : node;1386 }1387 function getPatchFlag(node) {1388 const flag = getVNodeArgAt(node, 3);1389 return flag ? parseInt(flag, 10) : undefined;1390 }1391 function createTransformContext(root, { prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, onError = defaultOnError }) {1392 const context = {1393 root,1394 helpers: new Set(),1395 components: new Set(),1396 directives: new Set(),1397 hoists: [],1398 cached: 0,1399 identifiers: {},1400 scopes: {1401 vFor: 0,1402 vSlot: 0,1403 vPre: 0,1404 vOnce: 01405 },1406 prefixIdentifiers,1407 hoistStatic,1408 cacheHandlers,1409 nodeTransforms,1410 directiveTransforms,1411 onError,1412 parent: null,1413 currentNode: root,1414 childIndex: 0,1415 helper(name) {1416 context.helpers.add(name);1417 return name;1418 },1419 helperString(name) {1420 return ((context.prefixIdentifiers ? `` : `_`) +1421 helperNameMap[context.helper(name)]);1422 },1423 replaceNode(node) {1424 /* istanbul ignore if */1425 {1426 if (!context.currentNode) {1427 throw new Error(`Node being replaced is already removed.`);1428 }1429 if (!context.parent) {1430 throw new Error(`Cannot replace root node.`);1431 }1432 }1433 context.parent.children[context.childIndex] = context.currentNode = node;1434 },1435 removeNode(node) {1436 if ( !context.parent) {1437 throw new Error(`Cannot remove root node.`);1438 }1439 const list = context.parent.children;1440 const removalIndex = node1441 ? list.indexOf(node)1442 : context.currentNode1443 ? context.childIndex1444 : -1;1445 /* istanbul ignore if */1446 if ( removalIndex < 0) {1447 throw new Error(`node being removed is not a child of current parent`);1448 }1449 if (!node || node === context.currentNode) {1450 // current node removed1451 context.currentNode = null;1452 context.onNodeRemoved();1453 }1454 else {1455 // sibling node removed1456 if (context.childIndex > removalIndex) {1457 context.childIndex--;1458 context.onNodeRemoved();1459 }1460 }1461 context.parent.children.splice(removalIndex, 1);1462 },1463 onNodeRemoved: () => { },1464 addIdentifiers(exp) {1465 },1466 removeIdentifiers(exp) {1467 },1468 hoist(exp) {1469 context.hoists.push(exp);1470 return createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, true);1471 },1472 cache(exp, isVNode = false) {1473 return createCacheExpression(++context.cached, exp, isVNode);1474 }1475 };1476 return context;1477 }1478 function transform(root, options) {1479 const context = createTransformContext(root, options);1480 traverseNode(root, context);1481 if (options.hoistStatic) {1482 hoistStatic(root, context);1483 }1484 finalizeRoot(root, context);1485 }1486 function finalizeRoot(root, context) {1487 const { helper } = context;1488 const { children } = root;1489 const child = children[0];1490 if (children.length === 1) {1491 // if the single child is an element, turn it into a block.1492 if (isSingleElementRoot(root, child) && child.codegenNode) {1493 // single element root is never hoisted so codegenNode will never be1494 // SimpleExpressionNode1495 const codegenNode = child.codegenNode;1496 if (codegenNode.type !== 20 /* JS_CACHE_EXPRESSION */) {1497 if (codegenNode.callee === WITH_DIRECTIVES) {1498 codegenNode.arguments[0].callee = helper(CREATE_BLOCK);1499 }1500 else {1501 codegenNode.callee = helper(CREATE_BLOCK);1502 }1503 root.codegenNode = createBlockExpression(codegenNode, context);1504 }1505 else {1506 root.codegenNode = codegenNode;1507 }1508 }1509 else {1510 // - single <slot/>, IfNode, ForNode: already blocks.1511 // - single text node: always patched.1512 // root codegen falls through via genNode()1513 root.codegenNode = child;1514 }1515 }1516 else if (children.length > 1) {1517 // root has multiple nodes - return a fragment block.1518 root.codegenNode = createBlockExpression(createCallExpression(helper(CREATE_BLOCK), [1519 helper(FRAGMENT),1520 `null`,1521 root.children1522 ]), context);1523 }1524 // finalize meta information1525 root.helpers = [...context.helpers];1526 root.components = [...context.components];1527 root.directives = [...context.directives];1528 root.hoists = context.hoists;1529 root.cached = context.cached;1530 }1531 function traverseChildren(parent, context) {1532 let i = 0;1533 const nodeRemoved = () => {1534 i--;1535 };1536 for (; i < parent.children.length; i++) {1537 const child = parent.children[i];1538 if (isString(child))1539 continue;1540 context.currentNode = child;1541 context.parent = parent;1542 context.childIndex = i;1543 context.onNodeRemoved = nodeRemoved;1544 traverseNode(child, context);1545 }1546 }1547 function traverseNode(node, context) {1548 // apply transform plugins1549 const { nodeTransforms } = context;1550 const exitFns = [];1551 for (let i = 0; i < nodeTransforms.length; i++) {1552 const onExit = nodeTransforms[i](node, context);1553 if (onExit) {1554 if (isArray(onExit)) {1555 exitFns.push(...onExit);1556 }1557 else {1558 exitFns.push(onExit);1559 }1560 }1561 if (!context.currentNode) {1562 // node was removed1563 return;1564 }1565 else {1566 // node may have been replaced1567 node = context.currentNode;1568 }1569 }1570 switch (node.type) {1571 case 3 /* COMMENT */:1572 // inject import for the Comment symbol, which is needed for creating1573 // comment nodes with `createVNode`1574 context.helper(CREATE_COMMENT);1575 break;1576 case 5 /* INTERPOLATION */:1577 // no need to traverse, but we need to inject toString helper1578 context.helper(TO_STRING);1579 break;1580 // for container types, further traverse downwards1581 case 9 /* IF */:1582 for (let i = 0; i < node.branches.length; i++) {1583 traverseChildren(node.branches[i], context);1584 }1585 break;1586 case 11 /* FOR */:1587 case 1 /* ELEMENT */:1588 case 0 /* ROOT */:1589 traverseChildren(node, context);1590 break;1591 }1592 // exit transforms1593 let i = exitFns.length;1594 while (i--) {1595 exitFns[i]();1596 }1597 }1598 function createStructuralDirectiveTransform(name, fn) {1599 const matches = isString(name)1600 ? (n) => n === name1601 : (n) => name.test(n);1602 return (node, context) => {1603 if (node.type === 1 /* ELEMENT */) {1604 const { props } = node;1605 // structural directive transforms are not concerned with slots1606 // as they are handled separately in vSlot.ts1607 if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {1608 return;1609 }1610 const exitFns = [];1611 for (let i = 0; i < props.length; i++) {1612 const prop = props[i];1613 if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {1614 // structural directives are removed to avoid infinite recursion1615 // also we remove them *before* applying so that it can further1616 // traverse itself in case it moves the node around1617 props.splice(i, 1);1618 i--;1619 const onExit = fn(node, prop, context);1620 if (onExit)1621 exitFns.push(onExit);1622 }1623 }1624 return exitFns;1625 }1626 };1627 }1628 function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html` }) {1629 const context = {1630 mode,1631 prefixIdentifiers,1632 sourceMap,1633 filename,1634 source: ast.loc.source,1635 code: ``,1636 column: 1,1637 line: 1,1638 offset: 0,1639 indentLevel: 0,1640 // lazy require source-map implementation, only in non-browser builds!1641 map: undefined1642 ,1643 helper(key) {1644 const name = helperNameMap[key];1645 return prefixIdentifiers ? name : `_${name}`;1646 },1647 push(code, node, openOnly) {1648 context.code += code;1649 },1650 resetMapping(loc) {1651 },1652 indent() {1653 newline(++context.indentLevel);1654 },1655 deindent(withoutNewLine = false) {1656 if (withoutNewLine) {1657 --context.indentLevel;1658 }1659 else {1660 newline(--context.indentLevel);1661 }1662 },1663 newline() {1664 newline(context.indentLevel);1665 }1666 };1667 function newline(n) {1668 context.push('\n' + ` `.repeat(n));1669 }1670 return context;1671 }1672 function generate(ast, options = {}) {1673 const context = createCodegenContext(ast, options);1674 const { mode, push, helper, prefixIdentifiers, indent, deindent, newline } = context;1675 const hasHelpers = ast.helpers.length > 0;1676 const useWithBlock = !prefixIdentifiers && mode !== 'module';1677 // preambles1678 if (mode === 'function') {1679 // Generate const declaration for helpers1680 // In prefix mode, we place the const declaration at top so it's done1681 // only once; But if we not prefixing, we place the declaration inside the1682 // with block so it doesn't incur the `in` check cost for every helper access.1683 if (hasHelpers) {1684 if (prefixIdentifiers) {1685 push(`const { ${ast.helpers.map(helper).join(', ')} } = Vue\n`);1686 }1687 else {1688 // "with" mode.1689 // save Vue in a separate variable to avoid collision1690 push(`const _Vue = Vue\n`);1691 // in "with" mode, helpers are declared inside the with block to avoid1692 // has check cost, but hoists are lifted out of the function - we need1693 // to provide the helper here.1694 if (ast.hoists.length) {1695 push(`const _${helperNameMap[CREATE_VNODE]} = Vue.${helperNameMap[CREATE_VNODE]}\n`);1696 if (ast.helpers.includes(CREATE_COMMENT)) {1697 push(`const _${helperNameMap[CREATE_COMMENT]} = Vue.${helperNameMap[CREATE_COMMENT]}\n`);1698 }1699 }1700 }1701 }1702 genHoists(ast.hoists, context);1703 newline();1704 push(`return `);1705 }1706 else {1707 // generate import statements for helpers1708 if (hasHelpers) {1709 push(`import { ${ast.helpers.map(helper).join(', ')} } from "vue"\n`);1710 }1711 genHoists(ast.hoists, context);1712 newline();1713 push(`export default `);1714 }1715 // enter render function1716 push(`function render() {`);1717 indent();1718 if (useWithBlock) {1719 push(`with (this) {`);1720 indent();1721 // function mode const declarations should be inside with block1722 // also they should be renamed to avoid collision with user properties1723 if (hasHelpers) {1724 push(`const { ${ast.helpers1725 .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)1726 .join(', ')} } = _Vue`);1727 newline();1728 if (ast.cached > 0) {1729 push(`const _cache = $cache`);1730 newline();1731 }1732 newline();1733 }1734 }1735 else {1736 push(`const _ctx = this`);1737 if (ast.cached > 0) {1738 newline();1739 push(`const _cache = _ctx.$cache`);1740 }1741 newline();1742 }1743 // generate asset resolution statements1744 if (ast.components.length) {1745 genAssets(ast.components, 'component', context);1746 }1747 if (ast.directives.length) {1748 genAssets(ast.directives, 'directive', context);1749 }1750 if (ast.components.length || ast.directives.length) {1751 newline();1752 }1753 // generate the VNode tree expression1754 push(`return `);1755 if (ast.codegenNode) {1756 genNode(ast.codegenNode, context);1757 }1758 else {1759 push(`null`);1760 }1761 if (useWithBlock) {1762 deindent();1763 push(`}`);1764 }1765 deindent();1766 push(`}`);1767 return {1768 ast,1769 code: context.code,1770 map: undefined //context.map ? context.map.toJSON() : undefined1771 };1772 }1773 function genAssets(assets, type, context) {1774 const resolver = context.helper(type === 'component' ? RESOLVE_COMPONENT : RESOLVE_DIRECTIVE);1775 for (let i = 0; i < assets.length; i++) {1776 const id = assets[i];1777 context.push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)})`);1778 context.newline();1779 }1780 }1781 function genHoists(hoists, context) {1782 if (!hoists.length) {1783 return;1784 }1785 context.newline();1786 hoists.forEach((exp, i) => {1787 context.push(`const _hoisted_${i + 1} = `);1788 genNode(exp, context);1789 context.newline();1790 });1791 }1792 function isText(n) {1793 return (isString(n) ||1794 n.type === 4 /* SIMPLE_EXPRESSION */ ||1795 n.type === 2 /* TEXT */ ||1796 n.type === 5 /* INTERPOLATION */ ||1797 n.type === 8 /* COMPOUND_EXPRESSION */);1798 }1799 function genNodeListAsArray(nodes, context) {1800 const multilines = nodes.length > 3 ||1801 ( nodes.some(n => isArray(n) || !isText(n)));1802 context.push(`[`);1803 multilines && context.indent();1804 genNodeList(nodes, context, multilines);1805 multilines && context.deindent();1806 context.push(`]`);1807 }1808 function genNodeList(nodes, context, multilines = false) {1809 const { push, newline } = context;1810 for (let i = 0; i < nodes.length; i++) {1811 const node = nodes[i];1812 if (isString(node)) {1813 push(node);1814 }1815 else if (isArray(node)) {1816 genNodeListAsArray(node, context);1817 }1818 else {1819 genNode(node, context);1820 }1821 if (i < nodes.length - 1) {1822 if (multilines) {1823 push(',');1824 newline();1825 }1826 else {1827 push(', ');1828 }1829 }1830 }1831 }1832 function genNode(node, context) {1833 if (isString(node)) {1834 context.push(node);1835 return;1836 }1837 if (isSymbol(node)) {1838 context.push(context.helper(node));1839 return;1840 }1841 switch (node.type) {1842 case 1 /* ELEMENT */:1843 case 9 /* IF */:1844 case 11 /* FOR */:1845 1846 assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +1847 `Apply appropriate transforms first.`);1848 genNode(node.codegenNode, context);1849 break;1850 case 2 /* TEXT */:1851 genText(node, context);1852 break;1853 case 4 /* SIMPLE_EXPRESSION */:1854 genExpression(node, context);1855 break;1856 case 5 /* INTERPOLATION */:1857 genInterpolation(node, context);1858 break;1859 case 12 /* TEXT_CALL */:1860 genNode(node.codegenNode, context);1861 break;1862 case 8 /* COMPOUND_EXPRESSION */:1863 genCompoundExpression(node, context);1864 break;1865 case 3 /* COMMENT */:1866 genComment(node, context);1867 break;1868 case 13 /* JS_CALL_EXPRESSION */:1869 genCallExpression(node, context);1870 break;1871 case 14 /* JS_OBJECT_EXPRESSION */:1872 genObjectExpression(node, context);1873 break;1874 case 16 /* JS_ARRAY_EXPRESSION */:1875 genArrayExpression(node, context);1876 break;1877 case 17 /* JS_FUNCTION_EXPRESSION */:1878 genFunctionExpression(node, context);1879 break;1880 case 18 /* JS_SEQUENCE_EXPRESSION */:1881 genSequenceExpression(node, context);1882 break;1883 case 19 /* JS_CONDITIONAL_EXPRESSION */:1884 genConditionalExpression(node, context);1885 break;1886 case 20 /* JS_CACHE_EXPRESSION */:1887 genCacheExpression(node, context);1888 break;1889 /* istanbul ignore next */1890 default:1891 {1892 assert(false, `unhandled codegen node type: ${node.type}`);1893 // make sure we exhaust all possible types1894 const exhaustiveCheck = node;1895 return exhaustiveCheck;1896 }1897 }1898 }1899 function genText(node, context) {1900 context.push(JSON.stringify(node.content), node);1901 }1902 function genExpression(node, context) {1903 const { content, isStatic } = node;1904 context.push(isStatic ? JSON.stringify(content) : content, node);1905 }1906 function genInterpolation(node, context) {1907 const { push, helper } = context;1908 push(`${helper(TO_STRING)}(`);1909 genNode(node.content, context);1910 push(`)`);1911 }1912 function genCompoundExpression(node, context) {1913 for (let i = 0; i < node.children.length; i++) {1914 const child = node.children[i];1915 if (isString(child)) {1916 context.push(child);1917 }1918 else {1919 genNode(child, context);1920 }1921 }1922 }1923 function genExpressionAsPropertyKey(node, context) {1924 const { push } = context;1925 if (node.type === 8 /* COMPOUND_EXPRESSION */) {1926 push(`[`);1927 genCompoundExpression(node, context);1928 push(`]`);1929 }1930 else if (node.isStatic) {1931 // only quote keys if necessary1932 const text = isSimpleIdentifier(node.content)1933 ? node.content1934 : JSON.stringify(node.content);1935 push(text, node);1936 }1937 else {1938 push(`[${node.content}]`, node);1939 }1940 }1941 function genComment(node, context) {1942 {1943 const { push, helper } = context;1944 push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);1945 }1946 }1947 // JavaScript1948 function genCallExpression(node, context) {1949 const callee = isString(node.callee)1950 ? node.callee1951 : context.helper(node.callee);1952 context.push(callee + `(`, node, true);1953 genNodeList(node.arguments, context);1954 context.push(`)`);1955 }1956 function genObjectExpression(node, context) {1957 const { push, indent, deindent, newline, resetMapping } = context;1958 const { properties } = node;1959 if (!properties.length) {1960 push(`{}`, node);1961 return;1962 }1963 const multilines = properties.length > 1 ||1964 (1965 properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));1966 push(multilines ? `{` : `{ `);1967 multilines && indent();1968 for (let i = 0; i < properties.length; i++) {1969 const { key, value, loc } = properties[i];1970 resetMapping(loc); // reset source mapping for every property.1971 // key1972 genExpressionAsPropertyKey(key, context);1973 push(`: `);1974 // value1975 genNode(value, context);1976 if (i < properties.length - 1) {1977 // will only reach this if it's multilines1978 push(`,`);1979 newline();1980 }1981 }1982 multilines && deindent();1983 const lastChar = context.code[context.code.length - 1];1984 push(multilines || /[\])}]/.test(lastChar) ? `}` : ` }`);1985 }1986 function genArrayExpression(node, context) {1987 genNodeListAsArray(node.elements, context);1988 }1989 function genFunctionExpression(node, context) {1990 const { push, indent, deindent } = context;1991 const { params, returns, newline } = node;1992 push(`(`, node);1993 if (isArray(params)) {1994 genNodeList(params, context);1995 }1996 else if (params) {1997 genNode(params, context);1998 }1999 push(`) => `);2000 if (newline) {2001 push(`{`);2002 indent();2003 push(`return `);2004 }2005 if (isArray(returns)) {2006 genNodeListAsArray(returns, context);2007 }2008 else {2009 genNode(returns, context);2010 }2011 if (newline) {2012 deindent();2013 push(`}`);2014 }2015 }2016 function genConditionalExpression(node, context) {2017 const { test, consequent, alternate } = node;2018 const { push, indent, deindent, newline } = context;2019 if (test.type === 4 /* SIMPLE_EXPRESSION */) {2020 const needsParens = !isSimpleIdentifier(test.content);2021 needsParens && push(`(`);2022 genExpression(test, context);2023 needsParens && push(`)`);2024 }2025 else {2026 push(`(`);2027 genCompoundExpression(test, context);2028 push(`)`);2029 }2030 indent();2031 context.indentLevel++;2032 push(`? `);2033 genNode(consequent, context);2034 context.indentLevel--;2035 newline();2036 push(`: `);2037 const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;2038 if (!isNested) {2039 context.indentLevel++;2040 }2041 genNode(alternate, context);2042 if (!isNested) {2043 context.indentLevel--;2044 }2045 deindent(true /* without newline */);2046 }2047 function genSequenceExpression(node, context) {2048 context.push(`(`);2049 genNodeList(node.expressions, context);2050 context.push(`)`);2051 }2052 function genCacheExpression(node, context) {2053 const { push, helper, indent, deindent, newline } = context;2054 push(`_cache[${node.index}] || (`);2055 if (node.isVNode) {2056 indent();2057 push(`${helper(SET_BLOCK_TRACKING)}(-1),`);2058 newline();2059 }2060 push(`_cache[${node.index}] = `);2061 genNode(node.value, context);2062 if (node.isVNode) {2063 push(`,`);2064 newline();2065 push(`${helper(SET_BLOCK_TRACKING)}(1),`);2066 newline();2067 push(`_cache[${node.index}]`);2068 deindent();2069 }2070 push(`)`);2071 }2072 const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {2073 if (dir.name !== 'else' &&2074 (!dir.exp || !dir.exp.content.trim())) {2075 const loc = dir.exp ? dir.exp.loc : node.loc;2076 context.onError(createCompilerError(35 /* X_V_IF_NO_EXPRESSION */, dir.loc));2077 dir.exp = createSimpleExpression(`true`, false, loc);2078 }2079 if (dir.name === 'if') {2080 const branch = createIfBranch(node, dir);2081 const codegenNode = createSequenceExpression([2082 createCallExpression(context.helper(OPEN_BLOCK))2083 ]);2084 context.replaceNode({2085 type: 9 /* IF */,2086 loc: node.loc,2087 branches: [branch],2088 codegenNode2089 });2090 // Exit callback. Complete the codegenNode when all children have been2091 // transformed.2092 return () => {2093 codegenNode.expressions.push(createCodegenNodeForBranch(branch, 0, context));2094 };2095 }2096 else {2097 // locate the adjacent v-if2098 const siblings = context.parent.children;2099 const comments = [];2100 let i = siblings.indexOf(node);2101 while (i-- >= -1) {2102 const sibling = siblings[i];2103 if ( sibling && sibling.type === 3 /* COMMENT */) {2104 context.removeNode(sibling);2105 comments.unshift(sibling);2106 continue;2107 }2108 if (sibling && sibling.type === 9 /* IF */) {2109 // move the node to the if node's branches2110 context.removeNode();2111 const branch = createIfBranch(node, dir);2112 if ( comments.length) {2113 branch.children = [...comments, ...branch.children];2114 }2115 sibling.branches.push(branch);2116 // since the branch was removed, it will not be traversed.2117 // make sure to traverse here.2118 traverseChildren(branch, context);2119 // make sure to reset currentNode after traversal to indicate this2120 // node has been removed.2121 context.currentNode = null;2122 // attach this branch's codegen node to the v-if root.2123 let parentCondition = sibling.codegenNode2124 .expressions[1];2125 while (true) {2126 if (parentCondition.alternate.type ===2127 19 /* JS_CONDITIONAL_EXPRESSION */) {2128 parentCondition = parentCondition.alternate;2129 }2130 else {2131 parentCondition.alternate = createCodegenNodeForBranch(branch, sibling.branches.length - 1, context);2132 break;2133 }2134 }2135 }2136 else {2137 context.onError(createCompilerError(36 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));2138 }2139 break;2140 }2141 }2142 });2143 function createIfBranch(node, dir) {2144 return {2145 type: 10 /* IF_BRANCH */,2146 loc: node.loc,2147 condition: dir.name === 'else' ? undefined : dir.exp,2148 children: node.tagType === 3 /* TEMPLATE */ ? node.children : [node]2149 };2150 }2151 function createCodegenNodeForBranch(branch, index, context) {2152 if (branch.condition) {2153 return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, index, context), 2154 // make sure to pass in asBlock: true so that the comment node call2155 // closes the current block.2156 createCallExpression(context.helper(CREATE_COMMENT), [2157 '"v-if"' ,2158 'true'2159 ]));2160 }2161 else {2162 return createChildrenCodegenNode(branch, index, context);2163 }2164 }2165 function createChildrenCodegenNode(branch, index, context) {2166 const { helper } = context;2167 const keyProperty = createObjectProperty(`key`, createSimpleExpression(index + '', false));2168 const { children } = branch;2169 const child = children[0];2170 const needFragmentWrapper = children.length !== 1 || child.type !== 1 /* ELEMENT */;2171 if (needFragmentWrapper) {2172 const blockArgs = [2173 helper(FRAGMENT),2174 createObjectExpression([keyProperty]),2175 children2176 ];2177 if (children.length === 1 && child.type === 11 /* FOR */) {2178 // optimize away nested fragments when child is a ForNode2179 const forBlockArgs = child.codegenNode.expressions[1].arguments;2180 // directly use the for block's children and patchFlag2181 blockArgs[2] = forBlockArgs[2];2182 blockArgs[3] = forBlockArgs[3];2183 }2184 return createCallExpression(helper(CREATE_BLOCK), blockArgs);2185 }2186 else {2187 const childCodegen = child.codegenNode;2188 let vnodeCall = childCodegen;2189 // Element with custom directives. Locate the actual createVNode() call.2190 if (vnodeCall.callee === WITH_DIRECTIVES) {2191 vnodeCall = vnodeCall.arguments[0];2192 }2193 // Change createVNode to createBlock.2194 if (vnodeCall.callee === CREATE_VNODE) {2195 vnodeCall.callee = helper(CREATE_BLOCK);2196 }2197 // inject branch key2198 injectProp(vnodeCall, keyProperty, context);2199 return childCodegen;2200 }2201 }2202 const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {2203 if (!dir.exp) {2204 context.onError(createCompilerError(37 /* X_V_FOR_NO_EXPRESSION */, dir.loc));2205 return;2206 }2207 const parseResult = parseForExpression(2208 // can only be simple expression because vFor transform is applied2209 // before expression transform.2210 dir.exp);2211 if (!parseResult) {2212 context.onError(createCompilerError(38 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));2213 return;2214 }2215 const { helper, addIdentifiers, removeIdentifiers, scopes } = context;2216 const { source, value, key, index } = parseResult;2217 // create the loop render function expression now, and add the2218 // iterator on exit after all children have been traversed2219 const renderExp = createCallExpression(helper(RENDER_LIST), [source]);2220 const keyProp = findProp(node, `key`);2221 const fragmentFlag = keyProp2222 ? 64 /* KEYED_FRAGMENT */2223 : 128 /* UNKEYED_FRAGMENT */;2224 const codegenNode = createSequenceExpression([2225 // fragment blocks disable tracking since they always diff their children2226 createCallExpression(helper(OPEN_BLOCK), [`false`]),2227 createCallExpression(helper(CREATE_BLOCK), [2228 helper(FRAGMENT),2229 `null`,2230 renderExp,2231 fragmentFlag + ( ` /* ${PatchFlagNames[fragmentFlag]} */` )2232 ])2233 ]);2234 context.replaceNode({2235 type: 11 /* FOR */,2236 loc: dir.loc,2237 source,2238 valueAlias: value,2239 keyAlias: key,2240 objectIndexAlias: index,2241 children: node.tagType === 3 /* TEMPLATE */ ? node.children : [node],2242 codegenNode2243 });2244 // bookkeeping2245 scopes.vFor++;2246 return () => {2247 scopes.vFor--;2248 // finish the codegen now that all children have been traversed2249 let childBlock;2250 const isTemplate = isTemplateNode(node);2251 const slotOutlet = isSlotOutlet(node)2252 ? node2253 : isTemplate &&2254 node.children.length === 1 &&2255 isSlotOutlet(node.children[0])2256 ? node.children[0] // api-extractor somehow fails to infer this2257 : null;2258 const keyProperty = keyProp2259 ? createObjectProperty(`key`, keyProp.type === 6 /* ATTRIBUTE */2260 ? createSimpleExpression(keyProp.value.content, true)2261 : keyProp.exp)2262 : null;2263 if (slotOutlet) {2264 // <slot v-for="..."> or <template v-for="..."><slot/></template>2265 childBlock = slotOutlet.codegenNode;2266 if (isTemplate && keyProperty) {2267 // <template v-for="..." :key="..."><slot/></template>2268 // we need to inject the key to the renderSlot() call.2269 // the props for renderSlot is passed as the 3rd argument.2270 injectProp(childBlock, keyProperty, context);2271 }2272 }2273 else if (isTemplate) {2274 // <template v-for="...">2275 // should generate a fragment block for each loop2276 childBlock = createBlockExpression(createCallExpression(helper(CREATE_BLOCK), [2277 helper(FRAGMENT),2278 keyProperty ? createObjectExpression([keyProperty]) : `null`,2279 node.children2280 ]), context);2281 }2282 else {2283 // Normal element v-for. Directly use the child's codegenNode2284 // arguments, but replace createVNode() with createBlock()2285 let codegenNode = node.codegenNode;2286 if (codegenNode.callee === WITH_DIRECTIVES) {2287 codegenNode.arguments[0].callee = helper(CREATE_BLOCK);2288 }2289 else {2290 codegenNode.callee = helper(CREATE_BLOCK);2291 }2292 childBlock = createBlockExpression(codegenNode, context);2293 }2294 renderExp.arguments.push(createFunctionExpression(createForLoopParams(parseResult), childBlock, true /* force newline */));2295 };2296 });2297 const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;2298 // This regex doesn't cover the case if key or index aliases have destructuring,2299 // but those do not make sense in the first place, so this works in practice.2300 const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;2301 const stripParensRE = /^\(|\)$/g;2302 function parseForExpression(input, context) {2303 const loc = input.loc;2304 const exp = input.content;2305 const inMatch = exp.match(forAliasRE);2306 if (!inMatch)2307 return;2308 const [, LHS, RHS] = inMatch;2309 const result = {2310 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),2311 value: undefined,2312 key: undefined,2313 index: undefined2314 };2315 let valueContent = LHS.trim()2316 .replace(stripParensRE, '')2317 .trim();2318 const trimmedOffset = LHS.indexOf(valueContent);2319 const iteratorMatch = valueContent.match(forIteratorRE);2320 if (iteratorMatch) {2321 valueContent = valueContent.replace(forIteratorRE, '').trim();2322 const keyContent = iteratorMatch[1].trim();2323 let keyOffset;2324 if (keyContent) {2325 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);2326 result.key = createAliasExpression(loc, keyContent, keyOffset);2327 }2328 if (iteratorMatch[2]) {2329 const indexContent = iteratorMatch[2].trim();2330 if (indexContent) {2331 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key2332 ? keyOffset + keyContent.length2333 : trimmedOffset + valueContent.length));2334 }2335 }2336 }2337 if (valueContent) {2338 result.value = createAliasExpression(loc, valueContent, trimmedOffset);2339 }2340 return result;2341 }2342 function createAliasExpression(range, content, offset) {2343 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));2344 }2345 function createForLoopParams({ value, key, index }) {2346 const params = [];2347 if (value) {2348 params.push(value);2349 }2350 if (key) {2351 if (!value) {2352 params.push(createSimpleExpression(`_`, false));2353 }2354 params.push(key);2355 }2356 if (index) {2357 if (!key) {2358 if (!value) {2359 params.push(createSimpleExpression(`_`, false));2360 }2361 params.push(createSimpleExpression(`__`, false));2362 }2363 params.push(index);2364 }2365 return params;2366 }2367 const isStaticExp = (p) => p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic;2368 const defaultFallback = createSimpleExpression(`undefined`, false);2369 // A NodeTransform that:2370 // 1. Tracks scope identifiers for scoped slots so that they don't get prefixed2371 // by transformExpression. This is only applied in non-browser builds with2372 // { prefixIdentifiers: true }.2373 // 2. Track v-slot depths so that we know a slot is inside another slot.2374 // Note the exit callback is executed before buildSlots() on the same node,2375 // so only nested slots see positive numbers.2376 const trackSlotScopes = (node, context) => {2377 if (node.type === 1 /* ELEMENT */ &&2378 (node.tagType === 1 /* COMPONENT */ ||2379 node.tagType === 3 /* TEMPLATE */)) {2380 // We are only checking non-empty v-slot here2381 // since we only care about slots that introduce scope variables.2382 const vSlot = findDir(node, 'slot');2383 if (vSlot) {2384 const slotProps = vSlot.exp;2385 context.scopes.vSlot++;2386 return () => {2387 context.scopes.vSlot--;2388 };2389 }2390 }2391 };2392 // Instead of being a DirectiveTransform, v-slot processing is called during2393 // transformElement to build the slots object for a component.2394 function buildSlots(node, context) {2395 const { children, loc } = node;2396 const slotsProperties = [];2397 const dynamicSlots = [];2398 // If the slot is inside a v-for or another v-slot, force it to be dynamic2399 // since it likely uses a scope variable.2400 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;2401 // 1. Check for default slot with slotProps on component itself.2402 // <Comp v-slot="{ prop }"/>2403 const explicitDefaultSlot = findDir(node, 'slot', true);2404 if (explicitDefaultSlot) {2405 const { arg, exp, loc } = explicitDefaultSlot;2406 if (arg) {2407 context.onError(createCompilerError(42 /* X_V_SLOT_NAMED_SLOT_ON_COMPONENT */, loc));2408 }2409 slotsProperties.push(buildDefaultSlot(exp, children, loc));2410 }2411 // 2. Iterate through children and check for template slots2412 // <template v-slot:foo="{ prop }">2413 let hasTemplateSlots = false;2414 let extraneousChild = undefined;2415 const seenSlotNames = new Set();2416 for (let i = 0; i < children.length; i++) {2417 const slotElement = children[i];2418 let slotDir;2419 if (!isTemplateNode(slotElement) ||2420 !(slotDir = findDir(slotElement, 'slot', true))) {2421 // not a <template v-slot>, skip.2422 if (slotElement.type !== 3 /* COMMENT */ && !extraneousChild) {2423 extraneousChild = slotElement;2424 }2425 continue;2426 }2427 if (explicitDefaultSlot) {2428 // already has on-component default slot - this is incorrect usage.2429 context.onError(createCompilerError(43 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));2430 break;2431 }2432 hasTemplateSlots = true;2433 const { children: slotChildren, loc: slotLoc } = slotElement;2434 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;2435 // check if name is dynamic.2436 let staticSlotName;2437 if (isStaticExp(slotName)) {2438 staticSlotName = slotName ? slotName.content : `default`;2439 }2440 else {2441 hasDynamicSlots = true;2442 }2443 const slotFunction = createFunctionExpression(slotProps, slotChildren, false, slotChildren.length ? slotChildren[0].loc : slotLoc);2444 // check if this slot is conditional (v-if/v-for)2445 let vIf;2446 let vElse;2447 let vFor;2448 if ((vIf = findDir(slotElement, 'if'))) {2449 hasDynamicSlots = true;2450 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));2451 }2452 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {2453 // find adjacent v-if2454 let j = i;2455 let prev;2456 while (j--) {2457 prev = children[j];2458 if (prev.type !== 3 /* COMMENT */) {2459 break;2460 }2461 }2462 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {2463 // remove node2464 children.splice(i, 1);2465 i--;2466 assert(dynamicSlots.length > 0);2467 // attach this slot to previous conditional2468 let conditional = dynamicSlots[dynamicSlots.length - 1];2469 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {2470 conditional = conditional.alternate;2471 }2472 conditional.alternate = vElse.exp2473 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)2474 : buildDynamicSlot(slotName, slotFunction);2475 }2476 else {2477 context.onError(createCompilerError(36 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));2478 }2479 }2480 else if ((vFor = findDir(slotElement, 'for'))) {2481 hasDynamicSlots = true;2482 const parseResult = vFor.parseResult ||2483 parseForExpression(vFor.exp);2484 if (parseResult) {2485 // Render the dynamic slots as an array and add it to the createSlot()2486 // args. The runtime knows how to handle it appropriately.2487 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [2488 parseResult.source,2489 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true)2490 ]));2491 }2492 else {2493 context.onError(createCompilerError(38 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));2494 }2495 }2496 else {2497 // check duplicate static names2498 if (staticSlotName) {2499 if (seenSlotNames.has(staticSlotName)) {2500 context.onError(createCompilerError(44 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));2501 continue;2502 }2503 seenSlotNames.add(staticSlotName);2504 }2505 slotsProperties.push(createObjectProperty(slotName, slotFunction));2506 }2507 }2508 if (hasTemplateSlots && extraneousChild) {2509 context.onError(createCompilerError(45 /* X_V_SLOT_EXTRANEOUS_NON_SLOT_CHILDREN */, extraneousChild.loc));2510 }2511 if (!explicitDefaultSlot && !hasTemplateSlots) {2512 // implicit default slot.2513 slotsProperties.push(buildDefaultSlot(undefined, children, loc));2514 }2515 let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_compiled`, createSimpleExpression(`true`, false))), loc);2516 if (dynamicSlots.length) {2517 slots = createCallExpression(context.helper(CREATE_SLOTS), [2518 slots,2519 createArrayExpression(dynamicSlots)2520 ]);2521 }2522 return {2523 slots,2524 hasDynamicSlots2525 };2526 }2527 function buildDefaultSlot(slotProps, children, loc) {2528 return createObjectProperty(`default`, createFunctionExpression(slotProps, children, false, children.length ? children[0].loc : loc));2529 }2530 function buildDynamicSlot(name, fn) {2531 return createObjectExpression([2532 createObjectProperty(`name`, name),2533 createObjectProperty(`fn`, fn)2534 ]);2535 }2536 // some directive transforms (e.g. v-model) may return a symbol for runtime2537 // import, which should be used instead of a resolveDirective call.2538 const directiveImportMap = new WeakMap();2539 // generate a JavaScript AST for this element's codegen2540 const transformElement = (node, context) => {2541 if (node.type !== 1 /* ELEMENT */ ||2542 // handled by transformSlotOutlet2543 node.tagType === 2 /* SLOT */ ||2544 // <template v-if/v-for> should have already been replaced2545 // <templte v-slot> is handled by buildSlots2546 (node.tagType === 3 /* TEMPLATE */ && node.props.some(isVSlot))) {2547 return;2548 }2549 // perform the work on exit, after all child expressions have been2550 // processed and merged.2551 return () => {2552 const isComponent = node.tagType === 1 /* COMPONENT */;2553 let hasProps = node.props.length > 0;2554 let patchFlag = 0;2555 let runtimeDirectives;2556 let dynamicPropNames;2557 let dynamicComponent;2558 // handle dynamic component2559 const isProp = findProp(node, 'is');2560 if (node.tag === 'component') {2561 if (isProp) {2562 // static <component is="foo" />2563 if (isProp.type === 6 /* ATTRIBUTE */) {2564 const tag = isProp.value && isProp.value.content;2565 if (tag) {2566 context.helper(RESOLVE_COMPONENT);2567 context.components.add(tag);2568 dynamicComponent = toValidAssetId(tag, `component`);2569 }2570 }2571 // dynamic <component :is="asdf" />2572 else if (isProp.exp) {2573 dynamicComponent = createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [isProp.exp]);2574 }2575 }2576 }2577 if (isComponent && !dynamicComponent) {2578 context.helper(RESOLVE_COMPONENT);2579 context.components.add(node.tag);2580 }2581 const args = [2582 dynamicComponent2583 ? dynamicComponent2584 : isComponent2585 ? toValidAssetId(node.tag, `component`)2586 : node.tagType === 4 /* PORTAL */2587 ? context.helper(PORTAL)2588 : node.tagType === 5 /* SUSPENSE */2589 ? context.helper(SUSPENSE)2590 : `"${node.tag}"`2591 ];2592 // props2593 if (hasProps) {2594 const propsBuildResult = buildProps(node, context, 2595 // skip reserved "is" prop <component is>2596 node.props.filter(p => p !== isProp));2597 patchFlag = propsBuildResult.patchFlag;2598 dynamicPropNames = propsBuildResult.dynamicPropNames;2599 runtimeDirectives = propsBuildResult.directives;2600 if (!propsBuildResult.props) {2601 hasProps = false;2602 }2603 else {2604 args.push(propsBuildResult.props);2605 }2606 }2607 // children2608 const hasChildren = node.children.length > 0;2609 if (hasChildren) {2610 if (!hasProps) {2611 args.push(`null`);2612 }2613 if (isComponent || node.tagType === 5 /* SUSPENSE */) {2614 const { slots, hasDynamicSlots } = buildSlots(node, context);2615 args.push(slots);2616 if (hasDynamicSlots) {2617 patchFlag |= 256 /* DYNAMIC_SLOTS */;2618 }2619 }2620 else if (node.children.length === 1) {2621 const child = node.children[0];2622 const type = child.type;2623 // check for dynamic text children2624 const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||2625 type === 8 /* COMPOUND_EXPRESSION */;2626 if (hasDynamicTextChild && !isStaticNode(child)) {2627 patchFlag |= 1 /* TEXT */;2628 }2629 // pass directly if the only child is a text node2630 // (plain / interpolation / expression)2631 if (hasDynamicTextChild || type === 2 /* TEXT */) {2632 args.push(child);2633 }2634 else {2635 args.push(node.children);2636 }2637 }2638 else {2639 args.push(node.children);2640 }2641 }2642 // patchFlag & dynamicPropNames2643 if (patchFlag !== 0) {2644 if (!hasChildren) {2645 if (!hasProps) {2646 args.push(`null`);2647 }2648 args.push(`null`);2649 }2650 {2651 const flagNames = Object.keys(PatchFlagNames)2652 .map(Number)2653 .filter(n => n > 0 && patchFlag & n)2654 .map(n => PatchFlagNames[n])2655 .join(`, `);2656 args.push(patchFlag + ` /* ${flagNames} */`);2657 }2658 if (dynamicPropNames && dynamicPropNames.length) {2659 args.push(`[${dynamicPropNames.map(n => JSON.stringify(n)).join(`, `)}]`);2660 }2661 }2662 const { loc } = node;2663 const vnode = createCallExpression(context.helper(CREATE_VNODE), args, loc);2664 if (runtimeDirectives && runtimeDirectives.length) {2665 node.codegenNode = createCallExpression(context.helper(WITH_DIRECTIVES), [2666 vnode,2667 createArrayExpression(runtimeDirectives.map(dir => buildDirectiveArgs(dir, context)), loc)2668 ], loc);2669 }2670 else {2671 node.codegenNode = vnode;2672 }2673 };2674 };2675 function buildProps(node, context, props = node.props) {2676 const elementLoc = node.loc;2677 const isComponent = node.tagType === 1 /* COMPONENT */;2678 let properties = [];2679 const mergeArgs = [];2680 const runtimeDirectives = [];2681 // patchFlag analysis2682 let patchFlag = 0;2683 let hasRef = false;2684 let hasClassBinding = false;2685 let hasStyleBinding = false;2686 let hasDynamicKeys = false;2687 const dynamicPropNames = [];2688 const analyzePatchFlag = ({ key, value }) => {2689 if (key.type === 4 /* SIMPLE_EXPRESSION */ && key.isStatic) {2690 if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||2691 ((value.type === 4 /* SIMPLE_EXPRESSION */ ||2692 value.type === 8 /* COMPOUND_EXPRESSION */) &&2693 isStaticNode(value))) {2694 return;2695 }2696 const name = key.content;2697 if (name === 'ref') {2698 hasRef = true;2699 }2700 else if (name === 'class') {2701 hasClassBinding = true;2702 }2703 else if (name === 'style') {2704 hasStyleBinding = true;2705 }2706 else if (name !== 'key') {2707 dynamicPropNames.push(name);2708 }2709 }2710 else {2711 hasDynamicKeys = true;2712 }2713 };2714 for (let i = 0; i < props.length; i++) {2715 // static attribute2716 const prop = props[i];2717 if (prop.type === 6 /* ATTRIBUTE */) {2718 const { loc, name, value } = prop;2719 if (name === 'ref') {2720 hasRef = true;2721 }2722 properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', true, value ? value.loc : loc)));2723 }2724 else {2725 // directives2726 const { name, arg, exp, loc } = prop;2727 // skip v-slot - it is handled by its dedicated transform.2728 if (name === 'slot') {2729 if (!isComponent) {2730 context.onError(createCompilerError(46 /* X_V_SLOT_MISPLACED */, loc));2731 }2732 continue;2733 }2734 // skip v-once - it is handled by its dedicated transform.2735 if (name === 'once') {2736 continue;2737 }2738 // special case for v-bind and v-on with no argument2739 const isBind = name === 'bind';2740 const isOn = name === 'on';2741 if (!arg && (isBind || isOn)) {2742 hasDynamicKeys = true;2743 if (exp) {2744 if (properties.length) {2745 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));2746 properties = [];2747 }2748 if (isBind) {2749 mergeArgs.push(exp);2750 }2751 else {2752 // v-on="obj" -> toHandlers(obj)2753 mergeArgs.push({2754 type: 13 /* JS_CALL_EXPRESSION */,2755 loc,2756 callee: context.helper(TO_HANDLERS),2757 arguments: [exp]2758 });2759 }2760 }2761 else {2762 context.onError(createCompilerError(isBind2763 ? 39 /* X_V_BIND_NO_EXPRESSION */2764 : 40 /* X_V_ON_NO_EXPRESSION */, loc));2765 }2766 continue;2767 }2768 const directiveTransform = context.directiveTransforms[name];2769 if (directiveTransform) {2770 // has built-in directive transform.2771 const { props, needRuntime } = directiveTransform(prop, node, context);2772 props.forEach(analyzePatchFlag);2773 properties.push(...props);2774 if (needRuntime) {2775 runtimeDirectives.push(prop);2776 if (isSymbol(needRuntime)) {2777 directiveImportMap.set(prop, needRuntime);2778 }2779 }2780 }2781 else {2782 // no built-in transform, this is a user custom directive.2783 runtimeDirectives.push(prop);2784 }2785 }2786 }2787 let propsExpression = undefined;2788 // has v-bind="object" or v-on="object", wrap with mergeProps2789 if (mergeArgs.length) {2790 if (properties.length) {2791 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));2792 }2793 if (mergeArgs.length > 1) {2794 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);2795 }2796 else {2797 // single v-bind with nothing else - no need for a mergeProps call2798 propsExpression = mergeArgs[0];2799 }2800 }2801 else if (properties.length) {2802 propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);2803 }2804 // patchFlag analysis2805 if (hasDynamicKeys) {2806 patchFlag |= 16 /* FULL_PROPS */;2807 }2808 else {2809 if (hasClassBinding) {2810 patchFlag |= 2 /* CLASS */;2811 }2812 if (hasStyleBinding) {2813 patchFlag |= 4 /* STYLE */;2814 }2815 if (dynamicPropNames.length) {2816 patchFlag |= 8 /* PROPS */;2817 }2818 }2819 if (patchFlag === 0 && (hasRef || runtimeDirectives.length > 0)) {2820 patchFlag |= 32 /* NEED_PATCH */;2821 }2822 return {2823 props: propsExpression,2824 directives: runtimeDirectives,2825 patchFlag,2826 dynamicPropNames2827 };2828 }2829 // Dedupe props in an object literal.2830 // Literal duplicated attributes would have been warned during the parse phase,2831 // however, it's possible to encounter duplicated `onXXX` handlers with different2832 // modifiers. We also need to merge static and dynamic class / style attributes.2833 // - onXXX handlers / style: merge into array2834 // - class: merge into single expression with concatenation2835 function dedupeProperties(properties) {2836 const knownProps = {};2837 const deduped = [];2838 for (let i = 0; i < properties.length; i++) {2839 const prop = properties[i];2840 // dynamic keys are always allowed2841 if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {2842 deduped.push(prop);2843 continue;2844 }2845 const name = prop.key.content;2846 const existing = knownProps[name];2847 if (existing) {2848 if (name === 'style' ||2849 name === 'class' ||2850 name.startsWith('on') ||2851 name.startsWith('vnode')) {2852 mergeAsArray(existing, prop);2853 }2854 // unexpected duplicate, should have emitted error during parse2855 }2856 else {2857 knownProps[name] = prop;2858 deduped.push(prop);2859 }2860 }2861 return deduped;2862 }2863 function mergeAsArray(existing, incoming) {2864 if (existing.value.type === 16 /* JS_ARRAY_EXPRESSION */) {2865 existing.value.elements.push(incoming.value);2866 }2867 else {2868 existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);2869 }2870 }2871 function buildDirectiveArgs(dir, context) {2872 const dirArgs = [];2873 const runtime = directiveImportMap.get(dir);2874 if (runtime) {2875 context.helper(runtime);2876 dirArgs.push(context.helperString(runtime));2877 }2878 else {2879 // inject statement for resolving directive2880 context.helper(RESOLVE_DIRECTIVE);2881 context.directives.add(dir.name);2882 dirArgs.push(toValidAssetId(dir.name, `directive`));2883 }2884 const { loc } = dir;2885 if (dir.exp)2886 dirArgs.push(dir.exp);2887 if (dir.arg) {2888 if (!dir.exp) {2889 dirArgs.push(`void 0`);2890 }2891 dirArgs.push(dir.arg);2892 }2893 if (Object.keys(dir.modifiers).length) {2894 if (!dir.arg) {2895 if (!dir.exp) {2896 dirArgs.push(`void 0`);2897 }2898 dirArgs.push(`void 0`);2899 }2900 dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, createSimpleExpression(`true`, false, loc))), loc));2901 }2902 return createArrayExpression(dirArgs, dir.loc);2903 }2904 const transformSlotOutlet = (node, context) => {2905 if (isSlotOutlet(node)) {2906 const { props, children, loc } = node;2907 const $slots = context.prefixIdentifiers ? `_ctx.$slots` : `$slots`;2908 let slotName = `"default"`;2909 // check for <slot name="xxx" OR :name="xxx" />2910 let nameIndex = -1;2911 for (let i = 0; i < props.length; i++) {2912 const prop = props[i];2913 if (prop.type === 6 /* ATTRIBUTE */) {2914 if (prop.name === `name` && prop.value) {2915 // static name="xxx"2916 slotName = JSON.stringify(prop.value.content);2917 nameIndex = i;2918 break;2919 }2920 }2921 else if (prop.name === `bind`) {2922 const { arg, exp } = prop;2923 if (arg &&2924 exp &&2925 arg.type === 4 /* SIMPLE_EXPRESSION */ &&2926 arg.isStatic &&2927 arg.content === `name`) {2928 // dynamic :name="xxx"2929 slotName = exp;2930 nameIndex = i;2931 break;2932 }2933 }2934 }2935 const slotArgs = [$slots, slotName];2936 const propsWithoutName = nameIndex > -12937 ? props.slice(0, nameIndex).concat(props.slice(nameIndex + 1))2938 : props;2939 let hasProps = propsWithoutName.length > 0;2940 if (hasProps) {2941 const { props: propsExpression, directives } = buildProps(node, context, propsWithoutName);2942 if (directives.length) {2943 context.onError(createCompilerError(41 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));2944 }2945 if (propsExpression) {2946 slotArgs.push(propsExpression);2947 }2948 else {2949 hasProps = false;2950 }2951 }2952 if (children.length) {2953 if (!hasProps) {2954 slotArgs.push(`{}`);2955 }2956 slotArgs.push(children);2957 }2958 node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);2959 }2960 };2961 const fnExpRE = /^([\w$_]+|\([^)]*?\))\s*=>|^function(?:\s+[\w$]+)?\s*\(/;2962 const transformOn = (dir, node, context, augmentor) => {2963 const { loc, modifiers, arg } = dir;2964 if (!dir.exp && !modifiers.length) {2965 context.onError(createCompilerError(40 /* X_V_ON_NO_EXPRESSION */, loc));2966 }2967 let eventName;2968 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {2969 if (arg.isStatic) {2970 eventName = createSimpleExpression(`on${capitalize(arg.content)}`, true, arg.loc);2971 }2972 else {2973 eventName = createCompoundExpression([`"on" + (`, arg, `)`]);2974 }2975 }2976 else {2977 // already a compound expression.2978 eventName = arg;2979 eventName.children.unshift(`"on" + (`);2980 eventName.children.push(`)`);2981 }2982 // handler processing2983 let exp = dir.exp;2984 let isCacheable = !exp;2985 if (exp) {2986 const isMemberExp = isMemberExpression(exp.content);2987 const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));2988 if (isInlineStatement || (isCacheable && isMemberExp)) {2989 // wrap inline statement in a function expression2990 exp = createCompoundExpression([2991 `$event => (`,2992 ...(exp.type === 4 /* SIMPLE_EXPRESSION */ ? [exp] : exp.children),2993 `)`2994 ]);2995 }2996 }2997 let ret = {2998 props: [2999 createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))3000 ],3001 needRuntime: false3002 };3003 // apply extended compiler augmentor3004 if (augmentor) {3005 ret = augmentor(ret);3006 }3007 if (isCacheable) {3008 // cache handlers so that it's always the same handler being passed down.3009 // this avoids unnecessary re-renders when users use inline handlers on3010 // components.3011 ret.props[0].value = context.cache(ret.props[0].value);3012 }3013 return ret;3014 };3015 // v-bind without arg is handled directly in ./transformElements.ts due to it affecting3016 // codegen for the entire props object. This transform here is only for v-bind3017 // *with* args.3018 const transformBind = (dir, node, context) => {3019 const { exp, modifiers, loc } = dir;3020 const arg = dir.arg;3021 if (!exp) {3022 context.onError(createCompilerError(39 /* X_V_BIND_NO_EXPRESSION */, loc));3023 }3024 // .prop is no longer necessary due to new patch behavior3025 // .sync is replaced by v-model:arg3026 if (modifiers.includes('camel')) {3027 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {3028 if (arg.isStatic) {3029 arg.content = camelize(arg.content);3030 }3031 else {3032 arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;3033 }3034 }3035 else {3036 arg.children.unshift(`${context.helperString(CAMELIZE)}(`);3037 arg.children.push(`)`);3038 }3039 }3040 return {3041 props: [3042 createObjectProperty(arg, exp || createSimpleExpression('', true, loc))3043 ],3044 needRuntime: false3045 };3046 };3047 const isText$1 = (node) => node.type === 5 /* INTERPOLATION */ || node.type === 2 /* TEXT */;3048 // Merge adjacent text nodes and expressions into a single expression3049 // e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.3050 const transformText = (node, context) => {3051 if (node.type === 0 /* ROOT */ || node.type === 1 /* ELEMENT */) {3052 // perform the transform on node exit so that all expressions have already3053 // been processed.3054 return () => {3055 const children = node.children;3056 let currentContainer = undefined;3057 let hasText = false;3058 for (let i = 0; i < children.length; i++) {3059 const child = children[i];3060 if (isText$1(child)) {3061 hasText = true;3062 for (let j = i + 1; j < children.length; j++) {3063 const next = children[j];3064 if (isText$1(next)) {3065 if (!currentContainer) {3066 currentContainer = children[i] = {3067 type: 8 /* COMPOUND_EXPRESSION */,3068 loc: child.loc,3069 children: [child]3070 };3071 }3072 // merge adjacent text node into current3073 currentContainer.children.push(` + `, next);3074 children.splice(j, 1);3075 j--;3076 }3077 else {3078 currentContainer = undefined;3079 break;3080 }3081 }3082 }3083 }3084 if (hasText && children.length > 1) {3085 // when an element has mixed text/element children, convert text nodes3086 // into createTextVNode(text) calls.3087 for (let i = 0; i < children.length; i++) {3088 const child = children[i];3089 if (isText$1(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {3090 const callArgs = [];3091 // createTextVNode defaults to single whitespace, so if it is a3092 // single space the code could be an empty call to save bytes.3093 if (child.type !== 2 /* TEXT */ || child.content !== ' ') {3094 callArgs.push(child);3095 }3096 // mark dynamic text with flag so it gets patched inside a block3097 if (child.type !== 2 /* TEXT */) {3098 callArgs.push(`${1 /* TEXT */} /* ${PatchFlagNames[1 /* TEXT */]} */`);3099 }3100 children[i] = {3101 type: 12 /* TEXT_CALL */,3102 content: child,3103 loc: child.loc,3104 codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)3105 };3106 }3107 }3108 }3109 };3110 }3111 };3112 const transformOnce = (node, context) => {3113 if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {3114 context.helper(SET_BLOCK_TRACKING);3115 return () => {3116 if (node.codegenNode) {3117 node.codegenNode = context.cache(node.codegenNode, true /* isVNode */);3118 }3119 };3120 }3121 };3122 const transformModel = (dir, node, context) => {3123 const { exp, arg } = dir;3124 if (!exp) {3125 context.onError(createCompilerError(47 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));3126 return createTransformProps();3127 }3128 const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : exp.loc.source;3129 if (!isMemberExpression(expString)) {3130 context.onError(createCompilerError(48 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));3131 return createTransformProps();3132 }3133 const propName = arg ? arg : createSimpleExpression('modelValue', true);3134 const eventName = arg3135 ? arg.type === 4 /* SIMPLE_EXPRESSION */ && arg.isStatic3136 ? createSimpleExpression('onUpdate:' + arg.content, true)3137 : createCompoundExpression([3138 createSimpleExpression('onUpdate:', true),3139 '+',3140 ...(arg.type === 4 /* SIMPLE_EXPRESSION */ ? [arg] : arg.children)3141 ])3142 : createSimpleExpression('onUpdate:modelValue', true);3143 const props = [3144 // modelValue: foo3145 createObjectProperty(propName, dir.exp),3146 // "onUpdate:modelValue": $event => (foo = $event)3147 createObjectProperty(eventName, createCompoundExpression([3148 `$event => (`,3149 ...(exp.type === 4 /* SIMPLE_EXPRESSION */ ? [exp] : exp.children),3150 ` = $event)`3151 ]))3152 ];3153 // modelModifiers: { foo: true, "bar-baz": true }3154 if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {3155 const modifiers = dir.modifiers3156 .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)3157 .join(`, `);3158 props.push(createObjectProperty(`modelModifiers`, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, true)));3159 }3160 return createTransformProps(props);3161 };3162 function createTransformProps(props = []) {3163 return { props, needRuntime: false };3164 }3165 const range = 2;3166 function generateCodeFrame(source, start = 0, end = source.length) {3167 const lines = source.split(/\r?\n/);3168 let count = 0;3169 const res = [];3170 for (let i = 0; i < lines.length; i++) {3171 count += lines[i].length + 1;3172 if (count >= start) {3173 for (let j = i - range; j <= i + range || end > count; j++) {3174 if (j < 0 || j >= lines.length)3175 continue;3176 res.push(`${j + 1}${' '.repeat(3 - String(j + 1).length)}| ${lines[j]}`);3177 const lineLength = lines[j].length;3178 if (j === i) {3179 // push underline3180 const pad = start - (count - lineLength) + 1;3181 const length = end > count ? lineLength - pad : end - start;3182 res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length));3183 }3184 else if (j > i) {3185 if (end > count) {3186 const length = Math.min(end - count, lineLength);3187 res.push(` | ` + '^'.repeat(length));3188 }3189 count += lineLength + 1;3190 }3191 }3192 break;3193 }3194 }3195 return res.join('\n');3196 }3197 // we name it `baseCompile` so that higher order compilers like @vue/compiler-dom3198 // can export `compile` while re-exporting everything else.3199 function baseCompile(template, options = {}) {3200 /* istanbul ignore if */3201 {3202 const onError = options.onError || defaultOnError;3203 if (options.prefixIdentifiers === true) {3204 onError(createCompilerError(51 /* X_PREFIX_ID_NOT_SUPPORTED */));3205 }3206 else if (options.mode === 'module') {3207 onError(createCompilerError(52 /* X_MODULE_MODE_NOT_SUPPORTED */));3208 }3209 }3210 const ast = isString(template) ? parse(template, options) : template;3211 const prefixIdentifiers = !true &&3212 (options.prefixIdentifiers === true || options.mode === 'module');3213 transform(ast, {3214 ...options,3215 prefixIdentifiers,3216 nodeTransforms: [3217 transformOnce,3218 transformIf,3219 transformFor,3220 ...( []),3221 transformSlotOutlet,3222 transformElement,3223 trackSlotScopes,3224 transformText,3225 ...(options.nodeTransforms || []) // user transforms3226 ],3227 directiveTransforms: {3228 on: transformOn,3229 bind: transformBind,3230 model: transformModel,3231 ...(options.directiveTransforms || {}) // user transforms3232 }3233 });3234 return generate(ast, {3235 ...options,3236 prefixIdentifiers3237 });3238 }3239 // https://developer.mozilla.org/en-US/docs/Web/HTML/Element3240 const HTML_TAGS = 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' +3241 'header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,div,dd,dl,dt,figcaption,' +3242 'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' +3243 'data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,' +3244 'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' +3245 'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' +3246 'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' +3247 'option,output,progress,select,textarea,details,dialog,menu,menuitem,' +3248 'summary,content,element,shadow,template,blockquote,iframe,tfoot';3249 // https://developer.mozilla.org/en-US/docs/Web/SVG/Element3250 const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' +3251 'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' +3252 'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' +3253 'feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' +3254 'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' +3255 'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' +3256 'foreignObject,g,hatch,hatchpath,image,line,lineGradient,marker,mask,' +3257 'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' +3258 'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' +3259 'text,textPath,title,tspan,unknown,use,view';3260 const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr';3261 const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS);3262 const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS);3263 const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS);3264 const isRawTextContainer = /*#__PURE__*/ makeMap('style,iframe,script,noscript', true);3265 const parserOptionsMinimal = {3266 isVoidTag,3267 isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag),3268 isPreTag: tag => tag === 'pre',3269 // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher3270 getNamespace(tag, parent) {3271 let ns = parent ? parent.ns : 0 /* HTML */;3272 if (parent && ns === 2 /* MATH_ML */) {3273 if (parent.tag === 'annotation-xml') {3274 if (tag === 'svg') {3275 return 1 /* SVG */;3276 }3277 if (parent.props.some(a => a.type === 6 /* ATTRIBUTE */ &&3278 a.name === 'encoding' &&3279 a.value != null &&3280 (a.value.content === 'text/html' ||3281 a.value.content === 'application/xhtml+xml'))) {3282 ns = 0 /* HTML */;3283 }3284 }3285 else if (/^m(?:[ions]|text)$/.test(parent.tag) &&3286 tag !== 'mglyph' &&3287 tag !== 'malignmark') {3288 ns = 0 /* HTML */;3289 }3290 }3291 else if (parent && ns === 1 /* SVG */) {3292 if (parent.tag === 'foreignObject' ||3293 parent.tag === 'desc' ||3294 parent.tag === 'title') {3295 ns = 0 /* HTML */;3296 }3297 }3298 if (ns === 0 /* HTML */) {3299 if (tag === 'svg') {3300 return 1 /* SVG */;3301 }3302 if (tag === 'math') {3303 return 2 /* MATH_ML */;3304 }3305 }3306 return ns;3307 },3308 // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments3309 getTextMode(tag, ns) {3310 if (ns === 0 /* HTML */) {3311 if (tag === 'textarea' || tag === 'title') {3312 return 1 /* RCDATA */;3313 }3314 if (isRawTextContainer(tag)) {3315 return 2 /* RAWTEXT */;3316 }3317 }3318 return 0 /* DATA */;3319 }3320 };3321 // Parse inline CSS strings for static style attributes into an object.3322 // This is a NodeTransform since it works on the static `style` attribute and3323 // converts it into a dynamic equivalent:3324 // style="color: red" -> :style='{ "color": "red" }'3325 // It is then processed by `transformElement` and included in the generated3326 // props.3327 const transformStyle = (node, context) => {3328 if (node.type === 1 /* ELEMENT */) {3329 node.props.forEach((p, i) => {3330 if (p.type === 6 /* ATTRIBUTE */ && p.name === 'style' && p.value) {3331 // replace p with an expression node3332 const parsed = JSON.stringify(parseInlineCSS(p.value.content));3333 const exp = context.hoist(createSimpleExpression(parsed, false, p.loc));3334 node.props[i] = {3335 type: 7 /* DIRECTIVE */,3336 name: `bind`,3337 arg: createSimpleExpression(`style`, true, p.loc),3338 exp,3339 modifiers: [],3340 loc: p.loc3341 };3342 }3343 });3344 }3345 };3346 const listDelimiterRE = /;(?![^(]*\))/g;3347 const propertyDelimiterRE = /:(.+)/;3348 function parseInlineCSS(cssText) {3349 const res = {};3350 cssText.split(listDelimiterRE).forEach(function (item) {3351 if (item) {3352 const tmp = item.split(propertyDelimiterRE);3353 tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim());3354 }3355 });3356 return res;3357 }3358 const transformCloak = (node, context) => {3359 return { props: [], needRuntime: false };3360 };3361 function createDOMCompilerError(code, loc) {3362 return createCompilerError(code, loc, DOMErrorMessages );3363 }3364 const DOMErrorMessages = {3365 [53 /* X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`,3366 [54 /* X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`,3367 [55 /* X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`,3368 [56 /* X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`,3369 [57 /* X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`,3370 [58 /* X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`,3371 [59 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */]: `v-model cannot used on file inputs since they are read-only. Use a v-on:change listener instead.`3372 };3373 const transformVHtml = (dir, node, context) => {3374 const { exp, loc } = dir;3375 if (!exp) {3376 context.onError(createDOMCompilerError(53 /* X_V_HTML_NO_EXPRESSION */, loc));3377 }3378 if (node.children.length) {3379 context.onError(createDOMCompilerError(54 /* X_V_HTML_WITH_CHILDREN */, loc));3380 node.children.length = 0;3381 }3382 return {3383 props: [3384 createObjectProperty(createSimpleExpression(`innerHTML`, true, loc), exp || createSimpleExpression('', true))3385 ],3386 needRuntime: false3387 };3388 };3389 const transformVText = (dir, node, context) => {3390 const { exp, loc } = dir;3391 if (!exp) {3392 context.onError(createDOMCompilerError(55 /* X_V_TEXT_NO_EXPRESSION */, loc));3393 }3394 if (node.children.length) {3395 context.onError(createDOMCompilerError(56 /* X_V_TEXT_WITH_CHILDREN */, loc));3396 node.children.length = 0;3397 }3398 return {3399 props: [3400 createObjectProperty(createSimpleExpression(`textContent`, true, loc), exp || createSimpleExpression('', true))3401 ],3402 needRuntime: false3403 };3404 };3405 const V_MODEL_RADIO = Symbol( `vModelRadio` );3406 const V_MODEL_CHECKBOX = Symbol( `vModelCheckbox` );3407 const V_MODEL_TEXT = Symbol( `vModelText` );3408 const V_MODEL_SELECT = Symbol( `vModelSelect` );3409 const V_MODEL_DYNAMIC = Symbol( `vModelDynamic` );3410 const V_ON_WITH_MODIFIERS = Symbol( `vOnModifiersGuard` );3411 const V_ON_WITH_KEYS = Symbol( `vOnKeysGuard` );3412 registerRuntimeHelpers({3413 [V_MODEL_RADIO]: `vModelRadio`,3414 [V_MODEL_CHECKBOX]: `vModelCheckbox`,3415 [V_MODEL_TEXT]: `vModelText`,3416 [V_MODEL_SELECT]: `vModelSelect`,3417 [V_MODEL_DYNAMIC]: `vModelDynamic`,3418 [V_ON_WITH_MODIFIERS]: `withModifiers`,3419 [V_ON_WITH_KEYS]: `withKeys`3420 });3421 const transformModel$1 = (dir, node, context) => {3422 const baseResult = transformModel(dir, node, context);3423 // base transform has errors3424 if (!baseResult.props.length) {3425 return baseResult;3426 }...
compiler-ssr.cjs.js
Source:compiler-ssr.cjs.js
...35 [SSR_RENDER_SUSPENSE]: `ssrRenderSuspense`36};37// Note: these are helpers imported from @vue/server-renderer38// make sure the names match!39compilerDom.registerRuntimeHelpers(ssrHelpers);40// Plugin for the first transform pass, which simply constructs the AST node41const ssrTransformIf = compilerDom.createStructuralDirectiveTransform(/^(if|else|else-if)$/, compilerDom.processIf);42// This is called during the 2nd transform pass to construct the SSR-sepcific43// codegen nodes.44function ssrProcessIf(node, context) {45 const [rootBranch] = node.branches;46 const ifStatement = compilerDom.createIfStatement(rootBranch.condition, processIfBranch(rootBranch, context));47 context.pushStatement(ifStatement);48 let currentIf = ifStatement;49 for (let i = 1; i < node.branches.length; i++) {50 const branch = node.branches[i];51 const branchBlockStatement = processIfBranch(branch, context);52 if (branch.condition) {53 // else-if
...
compiler-dom.esm-bundler.js
Source:compiler-dom.esm-bundler.js
...10const V_ON_WITH_KEYS = Symbol((process.env.NODE_ENV !== 'production') ? `vOnKeysGuard` : ``);11const V_SHOW = Symbol((process.env.NODE_ENV !== 'production') ? `vShow` : ``);12const TRANSITION = Symbol((process.env.NODE_ENV !== 'production') ? `Transition` : ``);13const TRANSITION_GROUP = Symbol((process.env.NODE_ENV !== 'production') ? `TransitionGroup` : ``);14registerRuntimeHelpers({15 [V_MODEL_RADIO]: `vModelRadio`,16 [V_MODEL_CHECKBOX]: `vModelCheckbox`,17 [V_MODEL_TEXT]: `vModelText`,18 [V_MODEL_SELECT]: `vModelSelect`,19 [V_MODEL_DYNAMIC]: `vModelDynamic`,20 [V_ON_WITH_MODIFIERS]: `withModifiers`,21 [V_ON_WITH_KEYS]: `withKeys`,22 [V_SHOW]: `vShow`,23 [TRANSITION]: `Transition`,24 [TRANSITION_GROUP]: `TransitionGroup`25});26/* eslint-disable no-restricted-globals */27let decoder;28function decodeHtmlBrowser(raw, asAttr = false) {...
index.js
Source:index.js
1"use strict";2var __assign = (this && this.__assign) || function () {3 __assign = Object.assign || function(t) {4 for (var s, i = 1, n = arguments.length; i < n; i++) {5 s = arguments[i];6 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))7 t[p] = s[p];8 }9 return t;10 };11 return __assign.apply(this, arguments);12};13var __spreadArrays = (this && this.__spreadArrays) || function () {14 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;15 for (var r = Array(s), k = 0, i = 0; i < il; i++)16 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)17 r[k] = a[j];18 return r;19};20function __export(m) {21 for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];22}23Object.defineProperty(exports, "__esModule", { value: true });24var parse_1 = require("./parse");25var transform_1 = require("./transform");26var codegen_1 = require("./codegen");27var shared_1 = require("../../shared/js/index");28var vIf_1 = require("./transforms/vIf");29var vFor_1 = require("./transforms/vFor");30var transformExpression_1 = require("./transforms/transformExpression");31var transformSlotOutlet_1 = require("./transforms/transformSlotOutlet");32var transformElement_1 = require("./transforms/transformElement");33var vOn_1 = require("./transforms/vOn");34var vBind_1 = require("./transforms/vBind");35var errors_1 = require("./errors");36var vSlot_1 = require("./transforms/vSlot");37var transformText_1 = require("./transforms/transformText");38var vOnce_1 = require("./transforms/vOnce");39var vModel_1 = require("./transforms/vModel");40function baseCompile(template, options) {41 if (options === void 0) { options = {}; }42 if (__BROWSER__) {43 var onError = options.onError || errors_1.defaultOnError;44 if (options.prefixIdentifiers === true) {45 onError(errors_1.createCompilerError(51));46 }47 else if (options.mode === 'module') {48 onError(errors_1.createCompilerError(52));49 }50 }51 var ast = shared_1.isString(template) ? parse_1.parse(template, options) : template;52 var prefixIdentifiers = !__BROWSER__ &&53 (options.prefixIdentifiers === true || options.mode === 'module');54 transform_1.transform(ast, __assign(__assign({}, options), { prefixIdentifiers: prefixIdentifiers, nodeTransforms: __spreadArrays([55 vOnce_1.transformOnce,56 vIf_1.transformIf,57 vFor_1.transformFor58 ], (prefixIdentifiers59 ? [60 vSlot_1.trackVForSlotScopes,61 transformExpression_1.transformExpression62 ]63 : []), [64 transformSlotOutlet_1.transformSlotOutlet,65 transformElement_1.transformElement,66 vSlot_1.trackSlotScopes,67 transformText_1.transformText68 ], (options.nodeTransforms || [])), directiveTransforms: __assign({ on: vOn_1.transformOn, bind: vBind_1.transformBind, model: vModel_1.transformModel }, (options.directiveTransforms || {})) }));69 return codegen_1.generate(ast, __assign(__assign({}, options), { prefixIdentifiers: prefixIdentifiers }));70}71exports.baseCompile = baseCompile;72var parse_2 = require("./parse");73exports.parse = parse_2.parse;74var transform_2 = require("./transform");75exports.transform = transform_2.transform;76exports.createStructuralDirectiveTransform = transform_2.createStructuralDirectiveTransform;77var codegen_2 = require("./codegen");78exports.generate = codegen_2.generate;79var errors_2 = require("./errors");80exports.createCompilerError = errors_2.createCompilerError;81__export(require("./ast"));82__export(require("./utils"));83__export(require("./codeframe"));84var runtimeHelpers_1 = require("./runtimeHelpers");85exports.registerRuntimeHelpers = runtimeHelpers_1.registerRuntimeHelpers;86var vModel_2 = require("./transforms/vModel");87exports.transformModel = vModel_2.transformModel;88var vOn_2 = require("./transforms/vOn");...
runtimeHelpers.js
Source:runtimeHelpers.js
...43 _a[exports.TO_HANDLERS] = "toHandlers",44 _a[exports.CAMELIZE] = "camelize",45 _a[exports.SET_BLOCK_TRACKING] = "setBlockTracking",46 _a);47function registerRuntimeHelpers(helpers) {48 Object.getOwnPropertySymbols(helpers).forEach(function (s) {49 exports.helperNameMap[s] = helpers[s];50 });51}...
actions.js
Source:actions.js
1import { registerRuntimeHelpers } from '@vue/compiler-core'2import { api } from '../../boot/axios'3export async function recordAction(actionCode, details) {4 return await api.post('/actions', { actionCode, details })5}6export async function fetchActions(actionFilterBuilder) {7 console.log('filter', actionFilterBuilder)8 const queryStr = actionFilterBuilder.buildQueryString()9 console.log('finding actions that match:', queryStr)10 const results = await api.get(`/actions?${queryStr}`)11 return results.data12}13// hold builder in actionFilter component; call build with api call14export const actionFilterBuilder = () => {15 return {16 filterSet: {},17 setStart(start) {18 this.filterSet.start = start19 return this20 },21 setEnd(end) {22 this.filterSet.end = end23 return this24 },25 setActionCode(code) {26 this.filterSet.action = code27 return this28 },29 setUserKey(key) {30 this.filterSet.user = key31 return this32 },33 setLimit(limit) {34 this.filterSet.limit = limit35 return this36 },37 setOffset(offset) {38 this.filterSet.offset = offset39 return this40 },41 nextPage() {42 if (!this.filterSet.limit) {43 return44 }45 const start = this.filterSet.offset || 046 this.setOffset(start + this.filterSet.limit)47 },48 priorPage() {49 if (!this.filterSet.limit || !this.filterSet.offset) {50 return51 }52 this.setOffset(this.filterSet.offset - this.filterSet.limit)53 if (this.filterSet.offset < 0) {54 this.setOffset(0)55 }56 },57 buildQueryString() {58 const keys = Object.keys(this.filterSet)59 const start = ''60 const query = keys.reduce((before, current) => {61 let frag = before62 if (before.length) {63 frag += '&'64 }65 frag += current + '=' + this.filterSet[current]66 return frag67 }, start)68 return query69 },70 }...
Using AI Code Generation
1const playwright = require('playwright');2const { registerRuntimeHelpers } = require('playwright/lib/client/runtimeHelpers');3registerRuntimeHelpers(playwright);4const { chromium } = require('playwright');5(async () => {6 const browser = await chromium.launch();7 const context = await browser.newContext();8 const page = await context.newPage();9 await page.screenshot({ path: `example.png` });10 await browser.close();11})();12const playwright = require('playwright');13const { registerRuntimeHelpers } = require('playwright/lib/client/runtimeHelpers');14registerRuntimeHelpers(playwright, { scope: 'global' });15const { chromium } = require('playwright');16(async () => {17 const browser = await chromium.launch();18 const context = await browser.newContext();19 const page = await context.newPage();20 await page.screenshot({ path: `example.png` });21 await browser.close();22})();
Using AI Code Generation
1const { registerRuntimeHelpers } = require('@playwright/test/lib/server/trace/common/instrumentation');2const { Page } = require('@playwright/test/lib/server/page');3const { BrowserContext } = require('@playwright/test/lib/server/browserContext');4const { BrowserServer } = require('@playwright/test/lib/server/browserServer');5const { Browser } = require('@playwright/test/lib/server/browser');6const { BrowserType } = require('@playwright/test/lib/server/browserType');7const { helper } = require('@playwright/test/lib/server/helper');8const { debugLogger } = require('@playwright/test/lib/utils/debugLogger');9const { debugError } = require('@playwright/test/lib/utils/debugLogger');10const { debugLog } = require('@playwright/test/lib/utils/debugLogger');11const { helper } = require('@playwright/test/lib/server/helper');12const { debugLogger } = require('@playwright/test/lib/utils/debugLogger');13const { debugError } = require('@playwright/test/lib/utils/debugLogger');14const { debugLog } = require('@playwright/test/lib/utils/debugLogger');15const { helper } = require('@playwright/test/lib/server/helper');16const { debugLogger } = require('@playwright/test/lib/utils/debugLogger');17const { debugError } = require('@playwright/test/lib/utils/debugLogger');18const { debugLog } = require('@playwright/test/lib/utils/debugLogger');19const { helper } = require('@playwright/test/lib/server/helper');20const { debugLogger } = require('@playwright/test/lib/utils/debugLogger');21const { debugError } = require('@playwright/test/lib/utils/debugLogger');22const { debugLog } = require('@playwright/test/lib/utils/debugLogger');23const { helper } = require('@playwright/test/lib/server/helper');24const { debugLogger } = require('@playwright/test/lib/utils/debugLogger');25const { debugError } = require('@playwright/test/lib/utils/debugLogger');26const { debugLog } = require('@playwright/test/lib/utils/debugLogger');27const { helper } = require('@playwright/test/lib/server/helper');28const { debugLogger } = require('@playwright/test/lib/utils/debugLogger');29const { debugError } = require('@playwright/test/lib/utils/debugLogger');30const { debugLog } = require('@playwright/test/lib/utils/debugLogger');31const { helper } = require('@playwright/test/lib/server/helper');32const { debugLogger } = require('@playwright/test/lib/utils/debug
Using AI Code Generation
1const playwright = require('playwright');2const { registerRuntimeHelpers } = require('playwright/lib/server/frames');3registerRuntimeHelpers(playwright);4const playwright = require('playwright');5const { registerRuntimeHelpers } = require('playwright/lib/server/frames');6registerRuntimeHelpers(playwright.chromium);7const playwright = require('playwright');8const { registerRuntimeHelpers } = require('playwright/lib/server/frames');9registerRuntimeHelpers(playwright);10(async () => {11 const browser = await playwright.chromium.launch();12 const context = await browser.newContext();13 const page = await context.newPage();14 const element = await page.$('text=Get Started');15 const result = await element.evaluate((element) => {16 return element.textContent;17 });18 console.log(result);19 await browser.close();20})();
Using AI Code Generation
1const playwright = require('playwright');2const { registerRuntimeHelpers } = playwright;3registerRuntimeHelpers();4const { waitForEvent } = require('playwright');5const { Page } = require('playwright');6const page = await Page();7await waitForEvent(page, 'request', () => true);8### `registerRuntimeHelpers()`9### `waitForEvent(object, eventName, predicate, options)`10### `waitForEventOrError(object, eventName, predicate, options)`11### `waitForEventWithError(object, eventName, predicate, options)`12### `waitForNextEvent(object, eventName, predicate, options)`
Using AI Code Generation
1const playwright = require('playwright-core');2const path = require('path');3const fs = require('fs');4const { registerRuntimeHelpers } = require('playwright-core/lib/server/registry');5const { helper } = require('playwright-core/lib/helper');6const { helperName } = require('playwright-core/lib/helper');7const { helperName } = require('playwright-core/lib/helper');8const playwrightPath = require.resolve('playwright-core');
Using AI Code Generation
1const { registerRuntimeHelpers } = require('playwright/lib/utils/registry');2const { test } = require('@playwright/test');3registerRuntimeHelpers({4});5test('test', async ({ page }) => {6 await page.waitForSelector('text=Get started');7});8const { registerRuntimeHelpers } = require('playwright/lib/utils/registry');9const { test } = require('@playwright/test');10registerRuntimeHelpers({11});12test('test', async ({ page }) => {13 await page.waitForSelector('text=Get started');14});15const { registerRuntimeHelpers } = require('playwright/lib/utils/registry');16const { test } = require('@playwright/test');17registerRuntimeHelpers({18});19test('test', async ({ page }) => {20 await page.waitForSelector('text=Get started');21});
Using AI Code Generation
1const { registerRuntimeHelpers } = require('playwright/lib/server/browserContext');2registerRuntimeHelpers(context);3context.addInitScript(() => {4 const { registerRuntimeHelpers } = require('playwright/lib/server/browserContext');5 registerRuntimeHelpers(context);6});
Using AI Code Generation
1const playwright = require('playwright');2const { registerRuntimeHelpers } = require('playwright/lib/protocol/protocol.js');3registerRuntimeHelpers(playwright);4playwright.registerTest('test', async ({ page }) => {5});6playwright.run();7const playwright = require('playwright');8const { registerRuntimeHelpers } = require('playwright/lib/protocol/protocol.js');9registerRuntimeHelpers(playwright);10playwright.registerTest('test', async ({ page }) => {11}, { headless: true });12playwright.run();13const playwright = require('playwright');14const { registerRuntimeHelpers } = require('playwright/lib/protocol/protocol.js');15registerRuntimeHelpers(playwright);16playwright.registerTest('test', async ({ page }) => {17}, { headless: false });18playwright.run();19const playwright = require('playwright');20const { registerRuntimeHelpers } = require('playwright/lib/protocol/protocol.js');21registerRuntimeHelpers(playwright);22playwright.registerTest('test', async ({ page }) => {23}, { headless: false, slowMo: 100 });24playwright.run();
Using AI Code Generation
1const { registerRuntimeHelpers } = require('playwright/lib/internal/exports');2registerRuntimeHelpers();3const { expect } = require('playwright/lib/internal/expect');4expect(1).toBe(1);5expect(1).toBe(2);6expect(1).toBe(3);7expect(1).toBe(4);8expect(1).toBe(5);9expect(1).toBe(6);10expect(1).toBe(7);11expect(1).toBe(8);12expect(1).toBe(9);13expect(1).toBe(10);14expect(1).toBe(11);15expect(1).toBe(12);16expect(1).toBe(13);17expect(1).toBe(14);18expect(1).toBe(15);19expect(1).toBe(16);20expect(1).toBe(17);21expect(1).toBe(18);22expect(1).toBe(19);23expect(1).toBe(20);24expect(1).toBe(21);25expect(1).toBe(22);26expect(1).toBe(23);27expect(1).toBe(24);28expect(1).toBe(25);29expect(1).toBe(26);30expect(1).toBe(27);31expect(1).toBe(28);32expect(1).toBe(29);33expect(1).toBe(30);
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.
Get 100 minutes of automation test minutes FREE!!