tiny-vue/internals/vite-plugin-template2jsx/src/helpers.js

223 lines
5.7 KiB
JavaScript

import path from 'node:path'
import { fileURLToPath } from 'node:url'
export const builtinDirective = ['v-if', 'v-for', 'v-model', 'v-slot', 'v-else', 'v-else-if']
export const builtinDirectivesWithoutVModel = builtinDirective.filter((x) => x !== 'v-model')
export const isNamedSlot = function (dObj) {
return Object.keys(dObj.attribs).find(isSlotAttribute)
}
export function getSlotName(dObj) {
if (!dObj.attribs) return 'default'
const attr = Object.keys(dObj.attribs).find(isSlotAttribute)
if (!isNamedSlot(dObj)) return 'default'
const prefix = attr.startsWith('#') ? '#' : 'v-slot:'
return attr.split(prefix)[1]
}
export function getSlotProps(dObj) {
const attr = Object.keys(dObj.attribs).find(isSlotAttribute)
return dObj.attribs[attr]
}
export const getCondition = function (dObj) {
return dObj.attribs['v-if'] || dObj.attribs['v-else-if']
}
export function isConditional(dObj) {
return isVIf(dObj) || isVElse(dObj) || isVElseIf(dObj)
}
export function isVIf(dObj) {
return dObj.type !== 'text' && Object.prototype.hasOwnProperty.call(dObj.attribs, 'v-if')
}
export function isVElseIf(dObj) {
return dObj.type !== 'text' && Object.prototype.hasOwnProperty.call(dObj.attribs, 'v-else-if')
}
export function isVElse(dObj) {
return dObj.type !== 'text' && Object.prototype.hasOwnProperty.call(dObj.attribs, 'v-else')
}
export function isVifOrVElseIf(dObj) {
return isVIf(dObj) || isVElseIf(dObj)
}
export const isVFor = function (dObj) {
return dObj.attribs && Object.prototype.hasOwnProperty.call(dObj.attribs, 'v-for')
}
export const isSlotAttribute = function (attr) {
return attr.startsWith('#') || attr.startsWith('v-slot')
}
export function isValueAttribute(attr) {
return !['v-if', 'v-else', 'v-else-if', 'v-for', 'v-slot'].includes(attr)
}
export function isTextBlank(txt) {
for (let i of txt) {
if (i !== ' ' && i !== '\n') {
return false
}
}
return true
}
export function getTag(dObj) {
return dObj.name
}
export function getFirstChild(dObj) {
return dObj.children.length && dObj.children[0]
}
export function isEmptyObject(dObj) {
return dObj.type === 'text' && isTextBlank(dObj.data)
}
export function isText(dObj) {
return dObj.type === 'text'
}
export function isComponent(dObj) {
return dObj.name === 'component'
}
export function isTransition(dObj) {
return ['transition-group', 'transition'].includes(dObj.name)
}
export function getText(dObj) {
return dObj.data
}
export function convertText(text) {
return text.replace(/{{/g, '{').replace(/}}/g, '}').replace(/\$t/g, 't')
}
export function setDynamicComponent(dObj) {
let component = dObj.attribs[':is']
dObj.attribs[':component'] = `resolveComponent(${component}, useIcons)`
delete dObj.attribs[':is']
dObj.name = 'Dynamic'
}
export function isBindClass(attrName) {
return attrName === ':class'
}
export function isBindAll(attrName) {
return attrName === 'v-bind'
}
export function getLoopCommand(dObj) {
const command = dObj.attribs['v-for']
const separator = command.includes(' in ') ? ' in ' : ' of '
const s = command.split(separator)
return `${s[1].trim()}.map(${s[0].trim()} `
}
export function isBindingAttrs(attrName) {
return attrName.startsWith(':')
}
export const toCamelCase = function (s) {
let res = ''
for (let i = 0; i < s.length; i++) {
if (i > 0 && s[i - 1] === '-') {
res += s[i].toUpperCase()
} else if (s[i] !== '-') res += s[i]
}
return res
}
export function getAttrName(attrName, prefix) {
return toCamelCase(attrName.split(prefix)[1])
}
export function isEventListener(attrName) {
return attrName.startsWith('@')
}
export function getListenerName(attrName) {
const idx = attrName.indexOf('.')
if (idx === -1) return attrName.substr(1)
else return attrName.substr(1, idx - 1)
}
export function getModifiers(attrName) {
let res = attrName.split('.')
res.shift()
return res
}
export const convertEventListenerName = function (attrName) {
const name = getListenerName(attrName)
return toCamelCase(`on-${name}`).replace(/modelvalue/g, 'modelValue')
}
export const convertListener = function (listener) {
const isFunction = listener.includes('=>') || (!listener.includes('(') && !listener.includes('='))
return isFunction
? listener
: listener.includes('$event')
? `(v) => {${listener.replace(/\$event/g, 'v')}}`
: `() => ${listener}`
}
export const convertEventListener = function (listener, modifiers = []) {
const eventName = convertListener(listener)
return modifiers.length === 0
? `${eventName}`
: `(event) => withModifiers(event, ${eventName}, [${modifiers.map((m) => `'${m}'`).join(', ')}])`
}
export const isVModel = function (attrName) {
return attrName.startsWith('v-model')
}
export const isBooleanAttrs = function (attrName) {
return attrName === ''
}
export const isRef = function (attrName) {
return attrName === 'ref'
}
export const isDynamic = function (attrName) {
return attrName === ':is'
}
export const convertRefName = function (name) {
return toCamelCase(name)
}
const filename = fileURLToPath(import.meta.url)
export const dirname = path.dirname(filename)
export const capitalize = function (str) {
return typeof str === 'string' ? str.slice(0, 1).toUpperCase() + str.slice(1) : str
}
export const capitalizeKebabCase = function (str, splitChar = '-') {
return typeof str === 'string' ? str.split(splitChar).map(capitalize).join('') : str
}
export const kebabCase = (str, splitChar = '-') => {
if (!str || typeof str !== 'string') return str
return str
.split('')
.map((char, index) => {
const charCod = char.charCodeAt(0)
if (charCod < 65 || charCod > 122) return char
return charCod >= 65 && charCod <= 90 ? (index !== 0 ? splitChar : '') + char.toLowerCase() : char
})
.join('')
}