+++ /dev/null
-import {
- camelize,
- capitalize,
- hyphenate,
- isArray,
- isString,
- normalizeStyle,
-} from '@vue/shared'
-import { warn } from '@vue/runtime-dom'
-import { mergeInheritAttr } from './prop'
-
-export function setStyle(
- el: HTMLElement,
- prev: any,
- value: any,
- root?: boolean,
-): any {
- value = normalizeStyle(root ? mergeInheritAttr('style', value) : value)
- patchStyle(el, prev, value)
- return value
-}
-
-// TODO copied from packages/runtime-dom/src/modules/style.ts
-
-type Style = string | Record<string, string | string[]> | null
-
-function patchStyle(el: Element, prev: Style, next: Style) {
- const style = (el as HTMLElement).style
- const isCssString = isString(next)
- if (next && !isCssString) {
- if (prev && !isString(prev)) {
- for (const key in prev) {
- if (next[key] == null) {
- setStyleValue(style, key, '')
- }
- }
- }
-
- for (const key in next) {
- setStyleValue(style, key, next[key])
- }
- } else {
- if (isCssString) {
- // TODO: combine with v-show
- if (prev !== next) {
- style.cssText = next
- }
- } else if (prev) {
- el.removeAttribute('style')
- }
- }
-}
-
-const semicolonRE = /[^\\];\s*$/
-const importantRE = /\s*!important$/
-
-function setStyleValue(
- style: CSSStyleDeclaration,
- name: string,
- val: string | string[],
-) {
- if (isArray(val)) {
- val.forEach(v => setStyleValue(style, name, v))
- } else {
- if (val == null) val = ''
- if (__DEV__) {
- if (semicolonRE.test(val)) {
- warn(
- `Unexpected semicolon at the end of '${name}' style value: '${val}'`,
- )
- }
- }
- if (name.startsWith('--')) {
- // custom property definition
- style.setProperty(name, val)
- } else {
- const prefixed = autoPrefix(style, name)
- if (importantRE.test(val)) {
- // !important
- style.setProperty(
- hyphenate(prefixed),
- val.replace(importantRE, ''),
- 'important',
- )
- } else {
- style[prefixed as any] = val
- }
- }
- }
-}
-
-const prefixes = ['Webkit', 'Moz', 'ms']
-const prefixCache: Record<string, string> = {}
-
-function autoPrefix(style: CSSStyleDeclaration, rawName: string): string {
- const cached = prefixCache[rawName]
- if (cached) {
- return cached
- }
- let name = camelize(rawName)
- if (name !== 'filter' && name in style) {
- return (prefixCache[rawName] = name)
- }
- name = capitalize(name)
- for (let i = 0; i < prefixes.length; i++) {
- const prefixed = prefixes[i] + name
- if (prefixed in style) {
- return (prefixCache[rawName] = prefixed)
- }
- }
- return rawName
-}