1
// eslint-disable-next-line @typescript-eslint/no-var-requires
2 1
const camelCase = require('camelcase')
3

4
export type CreateElementFunction = (
5
	component: string | object,
6
	attributes?: { [k: string]: any },
7
	children?: any | any[]
8
) => any[] | any
9

10
/**
11
 * Groups atributes passed to a React pragma to the VueJS fashion
12
 * @param h the VueJS createElement function passed in render functions
13
 * @returns pragma usable in buble rendered JSX for VueJS
14
 */
15 1
export default function adaptCreateElement(h: CreateElementFunction): CreateElementFunction {
16 1
	return (comp, attr, ...children: any[]) => {
17 1
		if (attr === undefined) {
18 0
			return h(comp)
19 1
		} else if (!children.length) {
20 1
			return h(comp, groupAttr(attr))
21
		}
22 0
		return h(comp, groupAttr(attr), children)
23
	}
24
}
25

26 1
const rootAttributes = [
27
	'staticClass',
28
	'class',
29
	'style',
30
	'key',
31
	'ref',
32
	'refInFor',
33
	'slot',
34
	'scopedSlots',
35
	'model'
36
]
37

38 1
const prefixedRE = /^(on|nativeOn|props|domProps|hook|v)([A-Z][a-zA-Z]+)?$/
39

40 1
const getRawName = (name: string): string => {
41 1
	return name.replace(/^(on|native(On|-on)|props|dom(Props|-props)|hook|v)-?/, '')
42
}
43

44
/**
45
 * Make sure an object is an array
46
 * and if it is not wrap it inside one
47
 * @param a
48
 */
49 1
const makeArray = (a: any): any[] => {
50 1
	return Array.isArray(a) ? a : [a]
51
}
52

53
/**
54
 * create a functoin out of two other
55
 * @param fn1
56
 * @param fn2
57
 */
58 1
const mergeFn = (
59
	fn1: (...argz1: any[]) => void,
60 0
	fn2: (...argz2: any[]) => void
61
): ((...argz: any[]) => void) =>
62 0
	function (this: any, ...argzMain: any[]) {
63 1
		fn1 && fn1.apply(this, argzMain)
64 1
		fn2 && fn2.apply(this, argzMain)
65
	}
66

67
/**
68
 * merge two members of the spread
69
 * @param a
70
 * @param b
71
 */
72 1
const merge = (a: any, b: any): any => {
73
	// initialization case
74 1
	if (a === undefined) {
75 1
		return b
76
	}
77
	// merge of functions
78 1
	if (typeof a === 'function' && typeof b === 'function') {
79 0
		return mergeFn(a, b)
80
	}
81
	// merge of other options (like class)
82 0
	return makeArray(a).concat(b)
83
}
84

85 1
export const concatenate = (
86 0
	src: { [key: string]: any },
87 0
	...otherObj: { [key: string]: any }[]
88
): { [key: string]: any } => {
89 1
	src = src || {}
90 0
	otherObj.forEach(obj => {
91 0
		Object.keys(obj).forEach((key: string) => {
92 0
			src[key] = merge(src[key], obj[key])
93
		})
94
	})
95 0
	return src
96
}
97

98 1
const groupAttr = (attrsIn: { [key: string]: any }): { [key: string]: any } | undefined => {
99 1
	if (!attrsIn) {
100 0
		return undefined
101
	}
102 1
	const attrsOut: { [key: string]: any } = {}
103 1
	Object.keys(attrsIn).forEach(name => {
104 1
		const value = attrsIn[name]
105 1
		const ccName = camelCase(name)
106 1
		if (rootAttributes.indexOf(ccName) > 0) {
107 0
			attrsOut[ccName] = value
108 1
		} else if (name === 'attrs') {
109 0
			attrsOut.attrs = concatenate(attrsOut.attrs, value)
110 1
		} else if (prefixedRE.test(ccName)) {
111 1
			const foundName = prefixedRE.exec(ccName)
112 1
			if (foundName) {
113 1
				const prefix = foundName[1]
114 1
				const rawName = getRawName(name)
115 1
				const camelCasedName = rawName.length ? rawName[0].toLowerCase() + rawName.slice(1) : ''
116 1
				if (prefix === 'v') {
117 1
					if (!attrsOut.directives) {
118 0
						attrsOut.directives = []
119
					}
120 0
					attrsOut.directives.push({
121
						name: camelCasedName,
122
						value
123
					})
124
				} else {
125 1
					if (!attrsOut[prefix]) {
126 1
						attrsOut[prefix] = {}
127
					}
128 1
					if (camelCasedName.length) {
129
						// if it is a litteral prefixed attribute
130 1
						attrsOut[prefix][camelCasedName] = merge(attrsOut[prefix][camelCasedName], value)
131
					} else {
132
						// if it is a spread
133 0
						concatenate(attrsOut[prefix], value)
134
					}
135
				}
136
			}
137
		} else {
138 1
			attrsOut.attrs = attrsOut.attrs || {}
139 1
			const finalName = /^data-/.test(name) ? name : ccName === 'xlinkHref' ? 'xlink:href' : ccName
140 1
			attrsOut.attrs[finalName] = value
141
		}
142
	})
143 1
	return attrsOut
144
}

Read our documentation on viewing source code .

Loading