How to use registerRuntimeHelpers method in Playwright Internal

Best JavaScript code snippet using playwright-internal

compiler-dom.global.js

Source:compiler-dom.global.js Github

copy

Full Screen

...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 }...

Full Screen

Full Screen

compiler-ssr.cjs.js

Source:compiler-ssr.cjs.js Github

copy

Full Screen

...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 ...

Full Screen

Full Screen

compiler-dom.esm-bundler.js

Source:compiler-dom.esm-bundler.js Github

copy

Full Screen

...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) {...

Full Screen

Full Screen

index.js

Source:index.js Github

copy

Full Screen

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");...

Full Screen

Full Screen

runtimeHelpers.js

Source:runtimeHelpers.js Github

copy

Full Screen

...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}...

Full Screen

Full Screen

actions.js

Source:actions.js Github

copy

Full Screen

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 }...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

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})();

Full Screen

Using AI Code Generation

copy

Full Screen

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

Full Screen

Using AI Code Generation

copy

Full Screen

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})();

Full Screen

Using AI Code Generation

copy

Full Screen

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)`

Full Screen

Using AI Code Generation

copy

Full Screen

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');

Full Screen

Using AI Code Generation

copy

Full Screen

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});

Full Screen

Using AI Code Generation

copy

Full Screen

1const { registerRuntimeHelpers } = require('playwright/lib/server/browserContext');2registerRuntimeHelpers(context);3context.addInitScript(() => {4 const { registerRuntimeHelpers } = require('playwright/lib/server/browserContext');5 registerRuntimeHelpers(context);6});

Full Screen

Using AI Code Generation

copy

Full Screen

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();

Full Screen

Using AI Code Generation

copy

Full Screen

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);

Full Screen

Using AI Code Generation

copy

Full Screen

1const { registerRuntimeHelpers } = require('@playwright/test');2registerRuntimeHelpers({3 myHelper: async (page, data) => {4 }5});6const { test } = require('@playwright/test');7test('test', async ({ page, myHelper }) => {8 await myHelper(page, 'data');9});

Full Screen

Playwright tutorial

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

Chapters:

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

Run Playwright Internal automation tests on LambdaTest cloud grid

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

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful