You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
200 lines
8.1 KiB
200 lines
8.1 KiB
6 months ago
|
"use strict";
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
exports.processProps = exports.transformElement = void 0;
|
||
|
const shared_1 = require("@vue/shared");
|
||
|
const compiler_core_1 = require("@vue/compiler-core");
|
||
|
const uni_shared_1 = require("@dcloudio/uni-shared");
|
||
|
const errors_1 = require("../errors");
|
||
|
const vModel_1 = require("./vModel");
|
||
|
const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared");
|
||
|
const transformElement = (node, context) => {
|
||
|
return function postTransformElement() {
|
||
|
node = context.currentNode;
|
||
|
if (!(node.type === 1 /* NodeTypes.ELEMENT */ &&
|
||
|
(node.tagType === 0 /* ElementTypes.ELEMENT */ ||
|
||
|
node.tagType === 1 /* ElementTypes.COMPONENT */))) {
|
||
|
return;
|
||
|
}
|
||
|
if (node.tagType === 1 /* ElementTypes.COMPONENT */) {
|
||
|
processComponent(node, context);
|
||
|
}
|
||
|
if (context.scopeId) {
|
||
|
addScopeId(node, context.scopeId);
|
||
|
}
|
||
|
const { props } = node;
|
||
|
if (props.length > 0) {
|
||
|
processProps(node, context);
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
exports.transformElement = transformElement;
|
||
|
function addScopeId(node, scopeId) {
|
||
|
return (0, uni_cli_shared_1.addStaticClass)(node, scopeId);
|
||
|
}
|
||
|
function processComponent(node, context) {
|
||
|
const { tag } = node;
|
||
|
if (context.bindingComponents[tag]) {
|
||
|
return;
|
||
|
}
|
||
|
// 1. dynamic component
|
||
|
if ((0, uni_shared_1.isComponentTag)(tag)) {
|
||
|
return context.onError((0, errors_1.createMPCompilerError)(8 /* MPErrorCodes.X_DYNAMIC_COMPONENT_NOT_SUPPORTED */, node.loc));
|
||
|
}
|
||
|
if ((0, compiler_core_1.findDir)(node, 'is')) {
|
||
|
return context.onError((0, errors_1.createMPCompilerError)(6 /* MPErrorCodes.X_V_IS_NOT_SUPPORTED */, node.loc));
|
||
|
}
|
||
|
// TODO not supported
|
||
|
// const isProp = findProp(node, 'is')
|
||
|
// if (isProp) {
|
||
|
// }
|
||
|
// 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)
|
||
|
const builtIn = (0, compiler_core_1.isCoreComponent)(tag) || context.isBuiltInComponent(tag);
|
||
|
if (builtIn) {
|
||
|
return context.onError((0, errors_1.createMPCompilerError)(7 /* MPErrorCodes.X_NOT_SUPPORTED */, node.loc, tag));
|
||
|
}
|
||
|
// 3. user component (from setup bindings)
|
||
|
const fromSetup = resolveSetupReference(tag, context);
|
||
|
if (fromSetup) {
|
||
|
return (context.bindingComponents[tag] = {
|
||
|
name: fromSetup,
|
||
|
type: "setup" /* BindingComponentTypes.SETUP */,
|
||
|
});
|
||
|
}
|
||
|
const dotIndex = tag.indexOf('.');
|
||
|
if (dotIndex > 0) {
|
||
|
return context.onError((0, errors_1.createMPCompilerError)(7 /* MPErrorCodes.X_NOT_SUPPORTED */, node.loc, tag));
|
||
|
}
|
||
|
// 4. Self referencing component (inferred from filename)
|
||
|
if (context.selfName && (0, shared_1.capitalize)((0, shared_1.camelize)(tag)) === context.selfName) {
|
||
|
return (context.bindingComponents[tag] = {
|
||
|
name: (0, compiler_core_1.toValidAssetId)(tag, `component`),
|
||
|
type: "self" /* BindingComponentTypes.SELF */,
|
||
|
});
|
||
|
}
|
||
|
// 5. user component (resolve)
|
||
|
context.bindingComponents[tag] = {
|
||
|
name: (0, compiler_core_1.toValidAssetId)(tag, `component`),
|
||
|
type: "unknown" /* BindingComponentTypes.UNKNOWN */,
|
||
|
};
|
||
|
context.helper(compiler_core_1.RESOLVE_COMPONENT);
|
||
|
}
|
||
|
function resolveSetupReference(name, context) {
|
||
|
const bindings = context.bindingMetadata;
|
||
|
if (!bindings || bindings.__isScriptSetup === false) {
|
||
|
return;
|
||
|
}
|
||
|
const camelName = (0, shared_1.camelize)(name);
|
||
|
const PascalName = (0, shared_1.capitalize)(camelName);
|
||
|
const checkType = (type) => {
|
||
|
if (bindings[name] === type) {
|
||
|
return name;
|
||
|
}
|
||
|
if (bindings[camelName] === type) {
|
||
|
return camelName;
|
||
|
}
|
||
|
if (bindings[PascalName] === type) {
|
||
|
return PascalName;
|
||
|
}
|
||
|
};
|
||
|
const fromConst = checkType("setup-const" /* BindingTypes.SETUP_CONST */) ||
|
||
|
checkType("setup-reactive-const" /* BindingTypes.SETUP_REACTIVE_CONST */);
|
||
|
if (fromConst) {
|
||
|
return context.inline
|
||
|
? // in inline mode, const setup bindings (e.g. imports) can be used as-is
|
||
|
fromConst
|
||
|
: `$setup[${JSON.stringify(fromConst)}]`;
|
||
|
}
|
||
|
const fromMaybeRef = checkType("setup-let" /* BindingTypes.SETUP_LET */) ||
|
||
|
checkType("setup-ref" /* BindingTypes.SETUP_REF */) ||
|
||
|
checkType("setup-maybe-ref" /* BindingTypes.SETUP_MAYBE_REF */);
|
||
|
if (fromMaybeRef) {
|
||
|
return context.inline
|
||
|
? // setup scope bindings that may be refs need to be unrefed
|
||
|
`${context.helperString(compiler_core_1.UNREF)}(${fromMaybeRef})`
|
||
|
: `$setup[${JSON.stringify(fromMaybeRef)}]`;
|
||
|
}
|
||
|
}
|
||
|
function processProps(node, context, props = node.props) {
|
||
|
const { tag } = node;
|
||
|
const isComponent = node.tagType === 1 /* ElementTypes.COMPONENT */;
|
||
|
const isPluginComponent = isComponent && context.isMiniProgramComponent(node.tag) === 'plugin';
|
||
|
for (let i = 0; i < props.length; i++) {
|
||
|
const prop = props[i];
|
||
|
if (prop.type === 7 /* NodeTypes.DIRECTIVE */) {
|
||
|
// directives
|
||
|
const { name, arg, loc } = prop;
|
||
|
const isVBind = name === 'bind';
|
||
|
const isVOn = name === 'on';
|
||
|
// skip v-slot - it is handled by its dedicated transform.
|
||
|
if (name === 'slot') {
|
||
|
if (!isComponent) {
|
||
|
context.onError((0, compiler_core_1.createCompilerError)(40 /* ErrorCodes.X_V_SLOT_MISPLACED */, loc));
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
// skip v-once/v-memo - they are handled by dedicated transforms.
|
||
|
if (name === 'once' || name === 'memo') {
|
||
|
continue;
|
||
|
}
|
||
|
// skip v-is and :is on <component>
|
||
|
if (name === 'is' ||
|
||
|
(isVBind && (0, compiler_core_1.isStaticArgOf)(arg, 'is') && (0, uni_shared_1.isComponentTag)(tag))) {
|
||
|
continue;
|
||
|
}
|
||
|
if (isVBind || isVOn) {
|
||
|
// v-on=""
|
||
|
// v-bind=""
|
||
|
if (!arg) {
|
||
|
if (isVOn) {
|
||
|
context.onError((0, errors_1.createMPCompilerError)(0 /* MPErrorCodes.X_V_ON_NO_ARGUMENT */, loc));
|
||
|
}
|
||
|
if (isVBind && (!isComponent || isPluginComponent)) {
|
||
|
context.onError((0, errors_1.createMPCompilerError)(2 /* MPErrorCodes.X_V_BIND_NO_ARGUMENT */, loc));
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
// v-on:[a]=""
|
||
|
// v-on:[a.b]=""
|
||
|
// v-bind:[a]=""
|
||
|
// v-bind:[a.b]=""
|
||
|
if (!(arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && arg.isStatic)) {
|
||
|
if (isVOn) {
|
||
|
context.onError((0, errors_1.createMPCompilerError)(1 /* MPErrorCodes.X_V_ON_DYNAMIC_EVENT */, loc));
|
||
|
}
|
||
|
if (isVBind && (!isComponent || isPluginComponent)) {
|
||
|
context.onError((0, errors_1.createMPCompilerError)(3 /* MPErrorCodes.X_V_BIND_DYNAMIC_ARGUMENT */, loc));
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
const directiveTransform = context.directiveTransforms[name];
|
||
|
if (name !== 'model' && directiveTransform) {
|
||
|
const { props } = directiveTransform(prop, node, context);
|
||
|
if (props.length) {
|
||
|
prop.exp = props[0].value;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
const transformVModel = (context.directiveTransforms.model ||
|
||
|
vModel_1.transformModel);
|
||
|
processVModel(node, transformVModel, context);
|
||
|
}
|
||
|
exports.processProps = processProps;
|
||
|
function processVModel(node, transformVModel, context) {
|
||
|
const { props } = node;
|
||
|
const dirs = [];
|
||
|
for (let i = 0; i < props.length; i++) {
|
||
|
const prop = props[i];
|
||
|
if (prop.type === 7 /* NodeTypes.DIRECTIVE */ && prop.name === 'model') {
|
||
|
dirs.push(...transformVModel(prop, node, context)
|
||
|
.props);
|
||
|
props.splice(i, 1);
|
||
|
i--;
|
||
|
}
|
||
|
}
|
||
|
if (dirs.length) {
|
||
|
props.push(...dirs);
|
||
|
}
|
||
|
}
|