first commit
This commit is contained in:
+2
@@ -0,0 +1,2 @@
|
||||
import { type CompilerOptions } from '@vue/compiler-dom';
|
||||
export declare function compileTemplate(source: string, options: CompilerOptions): import("@vue/compiler-dom").RootNode;
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.compileTemplate = compileTemplate;
|
||||
const compiler_dom_1 = require("@vue/compiler-dom");
|
||||
const transformElement_1 = require("./transforms/transformElement");
|
||||
const transformText_1 = require("./transforms/transformText");
|
||||
const vFor_1 = require("./transforms/vFor");
|
||||
const vIf_1 = require("./transforms/vIf");
|
||||
function compileTemplate(source, options) {
|
||||
const [nodeTransforms, directiveTransforms] = (0, compiler_dom_1.getBaseTransformPreset)();
|
||||
const resolvedOptions = {
|
||||
...options,
|
||||
comments: true,
|
||||
nodeTransforms: [
|
||||
nodeTransforms[0], // transformVBindShorthand
|
||||
vIf_1.transformIf,
|
||||
vFor_1.transformFor,
|
||||
transformElement_1.transformElement,
|
||||
transformText_1.transformText,
|
||||
...options.nodeTransforms || [],
|
||||
],
|
||||
directiveTransforms: {
|
||||
...directiveTransforms,
|
||||
...options.directiveTransforms,
|
||||
},
|
||||
};
|
||||
const ast = (0, compiler_dom_1.parse)(source, resolvedOptions);
|
||||
(0, compiler_dom_1.transform)(ast, resolvedOptions);
|
||||
return ast;
|
||||
}
|
||||
//# sourceMappingURL=compile.js.map
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import { type NodeTransform } from '@vue/compiler-dom';
|
||||
export declare const transformElement: NodeTransform;
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.transformElement = void 0;
|
||||
const compiler_dom_1 = require("@vue/compiler-dom");
|
||||
const shared_1 = require("@vue/shared");
|
||||
const transformElement = (node, context) => {
|
||||
return () => {
|
||||
if (node.type !== compiler_dom_1.NodeTypes.ELEMENT || node.tagType === compiler_dom_1.ElementTypes.TEMPLATE) {
|
||||
return;
|
||||
}
|
||||
const isComponent = node.tagType === compiler_dom_1.ElementTypes.COMPONENT;
|
||||
const isSlotOutlet = node.tagType === compiler_dom_1.ElementTypes.SLOT;
|
||||
for (const prop of node.props) {
|
||||
if (prop.type !== compiler_dom_1.NodeTypes.DIRECTIVE) {
|
||||
continue;
|
||||
}
|
||||
if (prop.name === 'slot') {
|
||||
if (!isComponent) {
|
||||
context.onError((0, compiler_dom_1.createCompilerError)(compiler_dom_1.ErrorCodes.X_V_SLOT_MISPLACED, prop.loc));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const isVBind = prop.name === 'bind';
|
||||
const isVOn = prop.name === 'on';
|
||||
if (!prop.arg && (isVBind || isVOn)) {
|
||||
if (!prop.exp) {
|
||||
context.onError((0, compiler_dom_1.createCompilerError)(isVBind
|
||||
? compiler_dom_1.ErrorCodes.X_V_BIND_NO_EXPRESSION
|
||||
: compiler_dom_1.ErrorCodes.X_V_ON_NO_EXPRESSION, prop.loc));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const runtimeDirectives = [];
|
||||
const directiveTransform = context.directiveTransforms[prop.name];
|
||||
if (directiveTransform) {
|
||||
const { needRuntime } = directiveTransform(prop, node, context);
|
||||
if (needRuntime) {
|
||||
runtimeDirectives.push(prop);
|
||||
}
|
||||
}
|
||||
else if (!(0, shared_1.isBuiltInDirective)(prop.name)) {
|
||||
runtimeDirectives.push(prop);
|
||||
}
|
||||
if (isSlotOutlet && runtimeDirectives.length) {
|
||||
context.onError((0, compiler_dom_1.createCompilerError)(compiler_dom_1.ErrorCodes.X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET, prop.loc));
|
||||
}
|
||||
}
|
||||
if (isComponent) {
|
||||
let hasNamedDefaultSlot = false;
|
||||
const implicitDefaultChildren = [];
|
||||
const seenSlotNames = new Set();
|
||||
const onComponentSlot = (0, compiler_dom_1.findDir)(node, 'slot', true);
|
||||
for (let child of node.children) {
|
||||
// <template v-for> -> for > template
|
||||
if (child.type === compiler_dom_1.NodeTypes.FOR) {
|
||||
child = child.children[0];
|
||||
}
|
||||
// <template v-if> -> if > branch > template
|
||||
else if (child.type === compiler_dom_1.NodeTypes.IF) {
|
||||
child = child.branches[0].children[0];
|
||||
}
|
||||
let slotDir;
|
||||
if (!(0, compiler_dom_1.isTemplateNode)(child) || !(slotDir = (0, compiler_dom_1.findDir)(child, 'slot', true))) {
|
||||
if (child.type !== compiler_dom_1.NodeTypes.COMMENT) {
|
||||
implicitDefaultChildren.push(child);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (onComponentSlot) {
|
||||
context.onError((0, compiler_dom_1.createCompilerError)(compiler_dom_1.ErrorCodes.X_V_SLOT_MIXED_SLOT_USAGE, slotDir.loc));
|
||||
break;
|
||||
}
|
||||
const staticSlotName = slotDir.arg
|
||||
? (0, compiler_dom_1.isStaticExp)(slotDir.arg)
|
||||
? slotDir.arg.content
|
||||
: undefined
|
||||
: 'default';
|
||||
if (staticSlotName) {
|
||||
if (seenSlotNames.has(staticSlotName)) {
|
||||
context.onError((0, compiler_dom_1.createCompilerError)(compiler_dom_1.ErrorCodes.X_V_SLOT_DUPLICATE_SLOT_NAMES, slotDir.loc));
|
||||
continue;
|
||||
}
|
||||
seenSlotNames.add(staticSlotName);
|
||||
if (staticSlotName === 'default') {
|
||||
hasNamedDefaultSlot = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasNamedDefaultSlot
|
||||
&& implicitDefaultChildren.some(node => node.type !== compiler_dom_1.NodeTypes.TEXT || !!node.content.trim())) {
|
||||
context.onError((0, compiler_dom_1.createCompilerError)(compiler_dom_1.ErrorCodes.X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN, implicitDefaultChildren[0].loc));
|
||||
}
|
||||
context.components.add(node.tag);
|
||||
}
|
||||
};
|
||||
};
|
||||
exports.transformElement = transformElement;
|
||||
//# sourceMappingURL=transformElement.js.map
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import { type NodeTransform } from '@vue/compiler-dom';
|
||||
export declare const transformText: NodeTransform;
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.transformText = void 0;
|
||||
const compiler_dom_1 = require("@vue/compiler-dom");
|
||||
const transformText = node => {
|
||||
if (node.type === compiler_dom_1.NodeTypes.ROOT
|
||||
|| node.type === compiler_dom_1.NodeTypes.ELEMENT
|
||||
|| node.type === compiler_dom_1.NodeTypes.FOR
|
||||
|| node.type === compiler_dom_1.NodeTypes.IF_BRANCH) {
|
||||
return () => {
|
||||
const children = node.children;
|
||||
let currentContainer = undefined;
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const child = children[i];
|
||||
if ((0, compiler_dom_1.isText)(child)) {
|
||||
for (let j = i + 1; j < children.length; j++) {
|
||||
const next = children[j];
|
||||
if ((0, compiler_dom_1.isText)(next)) {
|
||||
currentContainer ??= children[i] = (0, compiler_dom_1.createCompoundExpression)([child], child.loc);
|
||||
currentContainer.children.push(` + `, next);
|
||||
children.splice(j, 1);
|
||||
j--;
|
||||
}
|
||||
else {
|
||||
currentContainer = undefined;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
exports.transformText = transformText;
|
||||
//# sourceMappingURL=transformText.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
export declare const transformFor: import("@vue/compiler-dom").NodeTransform;
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.transformFor = void 0;
|
||||
const compiler_dom_1 = require("@vue/compiler-dom");
|
||||
const utils_1 = require("../utils");
|
||||
exports.transformFor = (0, utils_1.createStructuralDirectiveTransform)('for', (node, dir, context) => {
|
||||
if (!dir.exp) {
|
||||
context.onError((0, compiler_dom_1.createCompilerError)(compiler_dom_1.ErrorCodes.X_V_FOR_NO_EXPRESSION, dir.loc));
|
||||
return;
|
||||
}
|
||||
const parseResult = dir.forParseResult;
|
||||
if (!parseResult) {
|
||||
context.onError((0, compiler_dom_1.createCompilerError)(compiler_dom_1.ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION, dir.loc));
|
||||
return;
|
||||
}
|
||||
const { source, value, key, index } = parseResult;
|
||||
const forNode = {
|
||||
type: compiler_dom_1.NodeTypes.FOR,
|
||||
loc: dir.loc,
|
||||
source,
|
||||
valueAlias: value,
|
||||
keyAlias: key,
|
||||
objectIndexAlias: index,
|
||||
parseResult,
|
||||
children: [node],
|
||||
};
|
||||
context.replaceNode(forNode);
|
||||
return () => {
|
||||
if ((0, compiler_dom_1.isTemplateNode)(node)) {
|
||||
for (const child of node.children) {
|
||||
if (child.type === compiler_dom_1.NodeTypes.ELEMENT) {
|
||||
const key = (0, compiler_dom_1.findProp)(child, 'key');
|
||||
if (key) {
|
||||
context.onError((0, compiler_dom_1.createCompilerError)(compiler_dom_1.ErrorCodes.X_V_FOR_TEMPLATE_KEY_PLACEMENT, key.loc));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
//# sourceMappingURL=vFor.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
export declare const transformIf: import("@vue/compiler-dom").NodeTransform;
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.transformIf = void 0;
|
||||
const compiler_dom_1 = require("@vue/compiler-dom");
|
||||
const utils_1 = require("../utils");
|
||||
exports.transformIf = (0, utils_1.createStructuralDirectiveTransform)(/^(?:if|else-if|else)$/, (node, dir, context) => {
|
||||
if (dir.name !== 'else'
|
||||
&& (!dir.exp || !dir.exp.content.trim())) {
|
||||
context.onError((0, compiler_dom_1.createCompilerError)(compiler_dom_1.ErrorCodes.X_V_IF_NO_EXPRESSION, dir.loc));
|
||||
}
|
||||
if (dir.name === 'if') {
|
||||
const branch = createIfBranch(node, dir);
|
||||
const ifNode = {
|
||||
type: compiler_dom_1.NodeTypes.IF,
|
||||
loc: (0, utils_1.cloneLoc)(node.loc),
|
||||
branches: [branch],
|
||||
};
|
||||
context.replaceNode(ifNode);
|
||||
}
|
||||
else {
|
||||
const siblings = context.parent.children;
|
||||
const comments = [];
|
||||
let i = siblings.indexOf(node);
|
||||
while (i-- >= -1) {
|
||||
const sibling = siblings[i];
|
||||
if (sibling?.type === compiler_dom_1.NodeTypes.COMMENT) {
|
||||
context.removeNode(sibling);
|
||||
comments.unshift(sibling);
|
||||
continue;
|
||||
}
|
||||
if (sibling?.type === compiler_dom_1.NodeTypes.TEXT && !sibling.content.trim().length) {
|
||||
context.removeNode(sibling);
|
||||
continue;
|
||||
}
|
||||
if (sibling?.type === compiler_dom_1.NodeTypes.IF) {
|
||||
if (!sibling.branches.at(-1).condition) {
|
||||
context.onError((0, compiler_dom_1.createCompilerError)(compiler_dom_1.ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, node.loc));
|
||||
}
|
||||
context.removeNode();
|
||||
const branch = createIfBranch(node, dir);
|
||||
if (comments.length) {
|
||||
branch.children.unshift(...comments);
|
||||
}
|
||||
if (branch.userKey) {
|
||||
for (const { userKey } of sibling.branches) {
|
||||
if (isSameKey(userKey, branch.userKey)) {
|
||||
context.onError((0, compiler_dom_1.createCompilerError)(compiler_dom_1.ErrorCodes.X_V_IF_SAME_KEY, branch.userKey.loc));
|
||||
}
|
||||
}
|
||||
}
|
||||
sibling.branches.push(branch);
|
||||
(0, compiler_dom_1.traverseNode)(branch, context);
|
||||
context.currentNode = null;
|
||||
}
|
||||
else {
|
||||
context.onError((0, compiler_dom_1.createCompilerError)(compiler_dom_1.ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, node.loc));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
function createIfBranch(node, dir) {
|
||||
return {
|
||||
type: compiler_dom_1.NodeTypes.IF_BRANCH,
|
||||
loc: node.loc,
|
||||
condition: dir.name === 'else' ? undefined : dir.exp,
|
||||
children: [node],
|
||||
userKey: (0, compiler_dom_1.findProp)(node, 'key'),
|
||||
};
|
||||
}
|
||||
function isSameKey(a, b) {
|
||||
if (!a || a.type !== b.type) {
|
||||
return false;
|
||||
}
|
||||
if (a.type === compiler_dom_1.NodeTypes.ATTRIBUTE) {
|
||||
if (a.value.content !== b.value.content) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const exp = a.exp;
|
||||
const branchExp = b.exp;
|
||||
if (exp.type !== branchExp.type
|
||||
|| exp.type !== compiler_dom_1.NodeTypes.SIMPLE_EXPRESSION
|
||||
|| exp.isStatic !== branchExp.isStatic
|
||||
|| exp.content !== branchExp.content) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//# sourceMappingURL=vIf.js.map
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import { type NodeTransform, type SourceLocation, type StructuralDirectiveTransform } from '@vue/compiler-dom';
|
||||
export declare function createStructuralDirectiveTransform(name: string | RegExp, fn: StructuralDirectiveTransform): NodeTransform;
|
||||
export declare function cloneLoc(loc: SourceLocation): SourceLocation;
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createStructuralDirectiveTransform = createStructuralDirectiveTransform;
|
||||
exports.cloneLoc = cloneLoc;
|
||||
const compiler_dom_1 = require("@vue/compiler-dom");
|
||||
const shared_1 = require("@vue/shared");
|
||||
function createStructuralDirectiveTransform(name, fn) {
|
||||
const matches = (0, shared_1.isString)(name)
|
||||
? (n) => n === name
|
||||
: (n) => name.test(n);
|
||||
return (node, context) => {
|
||||
if (node.type === compiler_dom_1.NodeTypes.ELEMENT) {
|
||||
const { props } = node;
|
||||
const exitFns = [];
|
||||
for (let i = 0; i < props.length; i++) {
|
||||
const prop = props[i];
|
||||
if (prop.type === compiler_dom_1.NodeTypes.DIRECTIVE && matches(prop.name)) {
|
||||
props.splice(i, 1);
|
||||
i--;
|
||||
const onExit = fn(node, prop, context);
|
||||
if (onExit) {
|
||||
exitFns.push(onExit);
|
||||
}
|
||||
}
|
||||
}
|
||||
return exitFns;
|
||||
}
|
||||
};
|
||||
}
|
||||
function cloneLoc(loc) {
|
||||
return {
|
||||
start: { ...loc.start },
|
||||
end: { ...loc.end },
|
||||
source: loc.source,
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=utils.js.map
|
||||
Reference in New Issue
Block a user