Path: blob/main/frontend/vue/wc-wrapper/utils.ts
3367 views
/**1* Port of https://github.com/cloudera/hue/tree/master/desktop/core/src/desktop/js/vue/wrapper2* for Vue 3 support of web components3* To remove once @vuejs/vue-web-component-wrapper starts supporting Vue 34* https://github.com/vuejs/vue-web-component-wrapper/issues/935*/67import { ComponentPublicInstance, VNode } from 'vue'89// eslint-disable-next-line @typescript-eslint/no-explicit-any10export type KeyHash = { [key: string]: any };1112const camelizeRE = /-(\w)/g13export const camelize = (str: string): string => {14return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''))15}1617const hyphenateRE = /\B([A-Z])/g18export const hyphenate = (str: string): string => {19return str.replace(hyphenateRE, '-$1').toLowerCase()20}2122export function setInitialProps (propsList: string[]): KeyHash {23const res: KeyHash = {}24propsList.forEach((key) => {25res[key] = undefined26})27return res28}2930export function callHooks (vm: ComponentPublicInstance | undefined, hook: string): void {31if (vm) {32let hooks = vm.$options[hook] || []33if (!Array.isArray(hooks)) {34hooks = [hooks]35}36hooks.forEach((hook: () => void): void => {37hook.call(vm)38})39}40}4142export function createCustomEvent (name: string, args: unknown[]): CustomEvent {43return new CustomEvent(name, {44bubbles: false,45cancelable: false,46detail: args.length === 1 ? args[0] : args47})48}4950const isBoolean = (val: unknown) => /function Boolean/.test(String(val))51const isNumber = (val: unknown) => /function Number/.test(String(val))5253export function convertAttributeValue (54value: unknown,55name: string,56{ type }: { type?: unknown } = {}57): unknown {58if (isBoolean(type)) {59if (value === 'true' || value === 'false') {60return value === 'true'61}62if (value === '' || value === name) {63return true64}65return value != null66} else if (isNumber(type)) {67const parsed = parseFloat(<string>value)68return isNaN(parsed) ? value : parsed69} else {70return value71}72}7374export function toVNodes (75children: NodeListOf<ChildNode>,76// eslint-disable-next-line @typescript-eslint/no-explicit-any77h: (name: string, data: any) => VNode78): (VNode | null)[] {79const res: (VNode | null)[] = []8081for (let i = 0, l = children.length; i < l; i++) {82res.push(toVNode(children[i], h))83}8485return res86}8788// eslint-disable-next-line @typescript-eslint/no-explicit-any89function toVNode (node: any, h: (name: string, data: any) => VNode): VNode | null {90if (node.nodeType === 3) {91return node.data.trim() ? node.data : null92} else if (node.nodeType === 1) {93// eslint-disable-next-line @typescript-eslint/no-explicit-any94// const data: { attrs: any; domProps: any; slot?: any } = {95// attrs: getAttributes(node),96// domProps: {97// innerHTML: node.innerHTML98// }99// };100101// For Vue 3.x VNode props should be flattened102// https://v3.vuejs.org/guide/migration/render-function-api.html#vnode-props-format103const attrs = getAttributes(node)104const data = {105innerHTML: node.innerHTML,106...attrs107}108109return h(node.tagName, data)110} else {111return null112}113}114115function getAttributes (node: { attributes: { nodeName: string; nodeValue: unknown }[] }): KeyHash {116const res: KeyHash = {}117for (let i = 0, l = node.attributes.length; i < l; i++) {118const attr = node.attributes[i]119res[attr.nodeName] = attr.nodeValue120}121return res122}123124125