/* @flow */
|
|
import { getStyle, normalizeStyleBinding } from 'web/util/style'
|
import { cached, camelize, extend, isDef, isUndef, hyphenate } from 'shared/util'
|
|
const cssVarRE = /^--/
|
const importantRE = /\s*!important$/
|
const setProp = (el, name, val) => {
|
/* istanbul ignore if */
|
if (cssVarRE.test(name)) {
|
el.style.setProperty(name, val)
|
} else if (importantRE.test(val)) {
|
el.style.setProperty(hyphenate(name), val.replace(importantRE, ''), 'important')
|
} else {
|
const normalizedName = normalize(name)
|
if (Array.isArray(val)) {
|
// Support values array created by autoprefixer, e.g.
|
// {display: ["-webkit-box", "-ms-flexbox", "flex"]}
|
// Set them one by one, and the browser will only set those it can recognize
|
for (let i = 0, len = val.length; i < len; i++) {
|
el.style[normalizedName] = val[i]
|
}
|
} else {
|
el.style[normalizedName] = val
|
}
|
}
|
}
|
|
const vendorNames = ['Webkit', 'Moz', 'ms']
|
|
let emptyStyle
|
const normalize = cached(function (prop) {
|
emptyStyle = emptyStyle || document.createElement('div').style
|
prop = camelize(prop)
|
if (prop !== 'filter' && (prop in emptyStyle)) {
|
return prop
|
}
|
const capName = prop.charAt(0).toUpperCase() + prop.slice(1)
|
for (let i = 0; i < vendorNames.length; i++) {
|
const name = vendorNames[i] + capName
|
if (name in emptyStyle) {
|
return name
|
}
|
}
|
})
|
|
function updateStyle (oldVnode: VNodeWithData, vnode: VNodeWithData) {
|
const data = vnode.data
|
const oldData = oldVnode.data
|
|
if (isUndef(data.staticStyle) && isUndef(data.style) &&
|
isUndef(oldData.staticStyle) && isUndef(oldData.style)
|
) {
|
return
|
}
|
|
let cur, name
|
const el: any = vnode.elm
|
const oldStaticStyle: any = oldData.staticStyle
|
const oldStyleBinding: any = oldData.normalizedStyle || oldData.style || {}
|
|
// if static style exists, stylebinding already merged into it when doing normalizeStyleData
|
const oldStyle = oldStaticStyle || oldStyleBinding
|
|
const style = normalizeStyleBinding(vnode.data.style) || {}
|
|
// store normalized style under a different key for next diff
|
// make sure to clone it if it's reactive, since the user likely wants
|
// to mutate it.
|
vnode.data.normalizedStyle = isDef(style.__ob__)
|
? extend({}, style)
|
: style
|
|
const newStyle = getStyle(vnode, true)
|
|
for (name in oldStyle) {
|
if (isUndef(newStyle[name])) {
|
setProp(el, name, '')
|
}
|
}
|
for (name in newStyle) {
|
cur = newStyle[name]
|
if (cur !== oldStyle[name]) {
|
// ie9 setting to null has no effect, must use empty string
|
setProp(el, name, cur == null ? '' : cur)
|
}
|
}
|
}
|
|
export default {
|
create: updateStyle,
|
update: updateStyle
|
}
|