| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- import {
- getCurrentInstance,
- warn,
- VNode,
- Fragment,
- Static,
- watchPostEffect,
- onMounted,
- onUnmounted
- } from '@vue/runtime-core'
- import { ShapeFlags } from '@vue/shared'
- export const CSS_VAR_TEXT = Symbol(__DEV__ ? 'CSS_VAR_TEXT' : '')
- /**
- * Runtime helper for SFC's CSS variable injection feature.
- * @private
- */
- export function useCssVars(getter: (ctx: any) => Record<string, string>) {
- if (!__BROWSER__ && !__TEST__) return
- const instance = getCurrentInstance()
- /* istanbul ignore next */
- if (!instance) {
- __DEV__ &&
- warn(`useCssVars is called without current active component instance.`)
- return
- }
- const updateTeleports = (instance.ut = (vars = getter(instance.proxy)) => {
- Array.from(
- document.querySelectorAll(`[data-v-owner="${instance.uid}"]`)
- ).forEach(node => setVarsOnNode(node, vars))
- })
- const setVars = () => {
- const vars = getter(instance.proxy)
- setVarsOnVNode(instance.subTree, vars)
- updateTeleports(vars)
- }
- watchPostEffect(setVars)
- onMounted(() => {
- const ob = new MutationObserver(setVars)
- ob.observe(instance.subTree.el!.parentNode, { childList: true })
- onUnmounted(() => ob.disconnect())
- })
- }
- function setVarsOnVNode(vnode: VNode, vars: Record<string, string>) {
- if (__FEATURE_SUSPENSE__ && vnode.shapeFlag & ShapeFlags.SUSPENSE) {
- const suspense = vnode.suspense!
- vnode = suspense.activeBranch!
- if (suspense.pendingBranch && !suspense.isHydrating) {
- suspense.effects.push(() => {
- setVarsOnVNode(suspense.activeBranch!, vars)
- })
- }
- }
- // drill down HOCs until it's a non-component vnode
- while (vnode.component) {
- vnode = vnode.component.subTree
- }
- if (vnode.shapeFlag & ShapeFlags.ELEMENT && vnode.el) {
- setVarsOnNode(vnode.el as Node, vars)
- } else if (vnode.type === Fragment) {
- ;(vnode.children as VNode[]).forEach(c => setVarsOnVNode(c, vars))
- } else if (vnode.type === Static) {
- let { el, anchor } = vnode
- while (el) {
- setVarsOnNode(el as Node, vars)
- if (el === anchor) break
- el = el.nextSibling
- }
- }
- }
- function setVarsOnNode(el: Node, vars: Record<string, string>) {
- if (el.nodeType === 1) {
- const style = (el as HTMLElement).style
- let cssText = ''
- for (const key in vars) {
- style.setProperty(`--${key}`, vars[key])
- cssText += `--${key}: ${vars[key]};`
- }
- ;(style as any)[CSS_VAR_TEXT] = cssText
- }
- }
|