vue-jsx-runtime
Version:
jsx runtime support
255 lines (250 loc) • 8.79 kB
JavaScript
/*!
* vue-jsx-runtime v0.1.0
* (c) 2021 dolymood (dolymood@gmail.com)
* @license MIT
*/
import { createVNode, withDirectives, isVNode, toDisplayString, vShow, resolveDirective, vModelText, vModelRadio, vModelCheckbox, vModelDynamic, vModelSelect } from 'vue';
export { Fragment } from 'vue';
const hasOwnProperty = Object.prototype.hasOwnProperty;
const hasOwn = (val, key) => hasOwnProperty.call(val, key);
const isFunction = (val) => typeof val === 'function';
const isString = (val) => typeof val === 'string';
const isSymbol = (val) => typeof val === 'symbol';
const isObject = (val) => val !== null && typeof val === 'object';
const isArray = Array.isArray;
const vModelEleDirTypes = {
select: vModelSelect,
textarea: vModelText
};
const vModelDirTypes = {
default: vModelText,
radio: vModelRadio,
checkbox: vModelCheckbox,
dynamic: vModelDynamic
};
const DIR_CASES = {
// directives
html: (type, val, props) => {
props.innerHTML = val;
},
text: (type, val, props) => {
props.textContent = toDisplayString(val);
},
show: (type, val, props, directives) => {
directives.push([vShow, val]);
},
model: (type, val, props, directives, config, arg) => {
const isPlainNode = isString(type) || isSymbol(type);
const [{ get, set }, args, modifiers] = processDirVal(val, arg);
const prop = args || 'modelValue';
props[prop] = get();
const fixProp = prop === 'modelValue' ? 'model' : prop;
const fixModifiersKey = `${fixProp}Modifiers`;
props[fixModifiersKey] = modifiers;
// @ts-ignore
props[`onUpdate:${prop}`] = set;
// @ts-ignore
const eleDir = vModelEleDirTypes[type];
// @ts-ignore
const typeDir = (isString(config.type) || !config.type) ? (vModelDirTypes[config.type] || vModelDirTypes.default) : vModelDirTypes.dynamic;
const directiveName = eleDir || typeDir;
directives.push([
directiveName,
props[prop],
isPlainNode ? undefined : prop,
props[fixModifiersKey]
]);
if (isPlainNode) {
// delete props value
delete props[prop];
delete props[fixModifiersKey];
}
else {
// component, do not need to add vModel dir
directives.pop();
}
},
slots: (type, val, props, directives, config) => {
PROP_CASES.children(type, config.children, props, directives, config);
const children = props.children;
if (!children || !children.default) {
// just normal nodes
let defaultSlot = children;
if (children) {
if (!isFunction(children)) {
defaultSlot = () => children;
}
}
props.children = {};
if (defaultSlot) {
props.children.default = defaultSlot;
}
}
Object.assign(props.children, val);
},
__custom__: (type, val, props, directives, config, arg, name) => {
const [{ get, set }, args, modifiers] = processDirVal(val, arg);
props[`onUpdate:${name}`] = set;
directives.push([
resolveDirective(name),
get(),
args,
modifiers
]);
}
};
const PROP_CASES = {
children: (type, nodes, props) => {
if (props.__processed__children)
return;
props.__processed__children = true;
if (isString(type) || isSymbol(type)) {
if (!isArray(nodes) && isVNode(nodes)) {
nodes = [nodes];
}
props.children = nodes;
}
else {
// component
if (isVNode(nodes) || isArray(nodes) || !isObject(nodes)) {
// nodes
props.children = {
default: isFunction(nodes) ? nodes : () => nodes
};
}
else {
// is object slots
props.children = nodes;
}
}
}
};
// todo
const reversedProps = {
children: 1,
__processed__children: 1
};
const xlinkRE = /^xlink([A-Z])/;
function jsx$1(type, config = {}, maybeKey, source, self) {
let propName;
const directives = [];
const props = {};
for (propName in config) {
if (hasOwn(config, propName)) {
propName = propName;
const val = config[propName];
// /^(v-[A-Za-z0-9-]|:|\.|@|#)/
if (/^(v-[A-Za-z0-9-])/.test(propName)) {
// directive
// /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i
const match = /(?:^v-([a-z0-9-]+))?(?:(?::)([^\.]+))?(.+)?$/i.exec(propName);
const dirName = match[1];
const arg = match[2];
// let modifiers = match![3] && match![3].slice(1).split('.') as string[]
const dirFn = DIR_CASES[dirName] || DIR_CASES.__custom__;
dirFn(type, val, props, directives, config, arg, dirName);
}
else {
if (hasOwn(PROP_CASES, propName)) {
const propVal = PROP_CASES[propName](type, val, props, directives, config);
if (propVal !== undefined) {
props[propName] = propVal;
}
}
else {
if (propName.match(xlinkRE)) {
propName = propName.replace(xlinkRE, (_, firstCharacter) => `xlink:${firstCharacter.toLowerCase()}`);
}
props[propName] = val;
}
}
}
}
const children = props.children;
Object.keys(reversedProps).forEach((k) => {
delete props[k];
});
if (maybeKey !== undefined && !hasOwn(props, 'key')) {
props.key = '' + maybeKey;
}
const vnode = createVNode(type, props, children);
if (directives.length) {
// @ts-ignore
return withDirectives(vnode, directives);
}
return vnode;
}
const jsxs$1 = jsx$1;
function processDirVal(val, arg) {
if (!isArray(val)) {
val = [val, 'value'];
}
let [value, path, args, modifiers] = val;
if (isArray(args)) {
// args is modifiers
modifiers = args;
args = undefined;
}
if (!arg) {
arg = args;
}
const _modifiers = modifiers ? processModifiers(modifiers) : undefined;
const paths = isArray(path) ? path : [path];
const get = () => {
return baseGetSet(value, paths);
};
const set = (v) => {
return baseGetSet(value, paths, v);
};
return [{ get, set }, arg, _modifiers];
}
function processModifiers(modifiers) {
modifiers = Array.isArray(modifiers) ? modifiers : modifiers ? [modifiers] : [];
const realModifiers = {};
modifiers.forEach((modifier) => {
realModifiers[modifier] = true;
});
return realModifiers;
}
function baseGetSet(object, paths, set) {
let val = object;
let index = 0;
const length = paths.length;
const max = length - 1;
while (val != null && index <= max) {
if (set && index === max) {
val[paths[index]] = set;
return set;
}
val = val[paths[index++]];
}
return (index && index == length) ? val : undefined;
}
function jsxDEV$1(type, config = {}, maybeKey, source, self) {
// istanbul ignore next
if ((process.env.NODE_ENV !== 'production')) {
return jsx$1(type, config, maybeKey);
}
}
function jsxWithValidation(type, props = {}, key, isStaticChildren, source, self) {
return jsxDEV$1(type, props, key);
}
// istanbul ignore next
function jsxWithValidationStatic(type, props = {}, key) {
if ((process.env.NODE_ENV !== 'production')) {
return jsxWithValidation(type, props, key);
}
}
// istanbul ignore next
function jsxWithValidationDynamic(type, props = {}, key) {
if ((process.env.NODE_ENV !== 'production')) {
return jsxWithValidation(type, props, key);
}
}
// istanbul ignore next
const jsx = (process.env.NODE_ENV !== 'production') ? jsxWithValidationDynamic : jsx$1;
// istanbul ignore next
const jsxs = (process.env.NODE_ENV !== 'production') ? jsxWithValidationStatic : jsxs$1;
// istanbul ignore next
const jsxDEV = (process.env.NODE_ENV !== 'production') ? jsxWithValidation : undefined;
export { jsx, jsxDEV, jsxs };