Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quantum-kittens
GitHub Repository: quantum-kittens/platypus
Path: blob/main/frontend/vue/wc-wrapper/utils.ts
3367 views
1
/**
2
* Port of https://github.com/cloudera/hue/tree/master/desktop/core/src/desktop/js/vue/wrapper
3
* for Vue 3 support of web components
4
* To remove once @vuejs/vue-web-component-wrapper starts supporting Vue 3
5
* https://github.com/vuejs/vue-web-component-wrapper/issues/93
6
*/
7
8
import { ComponentPublicInstance, VNode } from 'vue'
9
10
// eslint-disable-next-line @typescript-eslint/no-explicit-any
11
export type KeyHash = { [key: string]: any };
12
13
const camelizeRE = /-(\w)/g
14
export const camelize = (str: string): string => {
15
return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''))
16
}
17
18
const hyphenateRE = /\B([A-Z])/g
19
export const hyphenate = (str: string): string => {
20
return str.replace(hyphenateRE, '-$1').toLowerCase()
21
}
22
23
export function setInitialProps (propsList: string[]): KeyHash {
24
const res: KeyHash = {}
25
propsList.forEach((key) => {
26
res[key] = undefined
27
})
28
return res
29
}
30
31
export function callHooks (vm: ComponentPublicInstance | undefined, hook: string): void {
32
if (vm) {
33
let hooks = vm.$options[hook] || []
34
if (!Array.isArray(hooks)) {
35
hooks = [hooks]
36
}
37
hooks.forEach((hook: () => void): void => {
38
hook.call(vm)
39
})
40
}
41
}
42
43
export function createCustomEvent (name: string, args: unknown[]): CustomEvent {
44
return new CustomEvent(name, {
45
bubbles: false,
46
cancelable: false,
47
detail: args.length === 1 ? args[0] : args
48
})
49
}
50
51
const isBoolean = (val: unknown) => /function Boolean/.test(String(val))
52
const isNumber = (val: unknown) => /function Number/.test(String(val))
53
54
export function convertAttributeValue (
55
value: unknown,
56
name: string,
57
{ type }: { type?: unknown } = {}
58
): unknown {
59
if (isBoolean(type)) {
60
if (value === 'true' || value === 'false') {
61
return value === 'true'
62
}
63
if (value === '' || value === name) {
64
return true
65
}
66
return value != null
67
} else if (isNumber(type)) {
68
const parsed = parseFloat(<string>value)
69
return isNaN(parsed) ? value : parsed
70
} else {
71
return value
72
}
73
}
74
75
export function toVNodes (
76
children: NodeListOf<ChildNode>,
77
// eslint-disable-next-line @typescript-eslint/no-explicit-any
78
h: (name: string, data: any) => VNode
79
): (VNode | null)[] {
80
const res: (VNode | null)[] = []
81
82
for (let i = 0, l = children.length; i < l; i++) {
83
res.push(toVNode(children[i], h))
84
}
85
86
return res
87
}
88
89
// eslint-disable-next-line @typescript-eslint/no-explicit-any
90
function toVNode (node: any, h: (name: string, data: any) => VNode): VNode | null {
91
if (node.nodeType === 3) {
92
return node.data.trim() ? node.data : null
93
} else if (node.nodeType === 1) {
94
// eslint-disable-next-line @typescript-eslint/no-explicit-any
95
// const data: { attrs: any; domProps: any; slot?: any } = {
96
// attrs: getAttributes(node),
97
// domProps: {
98
// innerHTML: node.innerHTML
99
// }
100
// };
101
102
// For Vue 3.x VNode props should be flattened
103
// https://v3.vuejs.org/guide/migration/render-function-api.html#vnode-props-format
104
const attrs = getAttributes(node)
105
const data = {
106
innerHTML: node.innerHTML,
107
...attrs
108
}
109
110
return h(node.tagName, data)
111
} else {
112
return null
113
}
114
}
115
116
function getAttributes (node: { attributes: { nodeName: string; nodeValue: unknown }[] }): KeyHash {
117
const res: KeyHash = {}
118
for (let i = 0, l = node.attributes.length; i < l; i++) {
119
const attr = node.attributes[i]
120
res[attr.nodeName] = attr.nodeValue
121
}
122
return res
123
}
124
125