106ad6026322cb3e4eb8a888a822f36ca27e2ba1e57a0ae8f48639da10b474a818eb0c89f9b8277cade89beaee4dce545b2abf94080d2ba602117543971276 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /* @flow */
  2. import { getStyle, normalizeStyleBinding } from 'web/util/style'
  3. import { cached, camelize, extend, isDef, isUndef, hyphenate } from 'shared/util'
  4. const cssVarRE = /^--/
  5. const importantRE = /\s*!important$/
  6. const setProp = (el, name, val) => {
  7. /* istanbul ignore if */
  8. if (cssVarRE.test(name)) {
  9. el.style.setProperty(name, val)
  10. } else if (importantRE.test(val)) {
  11. el.style.setProperty(hyphenate(name), val.replace(importantRE, ''), 'important')
  12. } else {
  13. const normalizedName = normalize(name)
  14. if (Array.isArray(val)) {
  15. // Support values array created by autoprefixer, e.g.
  16. // {display: ["-webkit-box", "-ms-flexbox", "flex"]}
  17. // Set them one by one, and the browser will only set those it can recognize
  18. for (let i = 0, len = val.length; i < len; i++) {
  19. el.style[normalizedName] = val[i]
  20. }
  21. } else {
  22. el.style[normalizedName] = val
  23. }
  24. }
  25. }
  26. const vendorNames = ['Webkit', 'Moz', 'ms']
  27. let emptyStyle
  28. const normalize = cached(function (prop) {
  29. emptyStyle = emptyStyle || document.createElement('div').style
  30. prop = camelize(prop)
  31. if (prop !== 'filter' && (prop in emptyStyle)) {
  32. return prop
  33. }
  34. const capName = prop.charAt(0).toUpperCase() + prop.slice(1)
  35. for (let i = 0; i < vendorNames.length; i++) {
  36. const name = vendorNames[i] + capName
  37. if (name in emptyStyle) {
  38. return name
  39. }
  40. }
  41. })
  42. function updateStyle (oldVnode: VNodeWithData, vnode: VNodeWithData) {
  43. const data = vnode.data
  44. const oldData = oldVnode.data
  45. if (isUndef(data.staticStyle) && isUndef(data.style) &&
  46. isUndef(oldData.staticStyle) && isUndef(oldData.style)
  47. ) {
  48. return
  49. }
  50. let cur, name
  51. const el: any = vnode.elm
  52. const oldStaticStyle: any = oldData.staticStyle
  53. const oldStyleBinding: any = oldData.normalizedStyle || oldData.style || {}
  54. // if static style exists, stylebinding already merged into it when doing normalizeStyleData
  55. const oldStyle = oldStaticStyle || oldStyleBinding
  56. const style = normalizeStyleBinding(vnode.data.style) || {}
  57. // store normalized style under a different key for next diff
  58. // make sure to clone it if it's reactive, since the user likely wants
  59. // to mutate it.
  60. vnode.data.normalizedStyle = isDef(style.__ob__)
  61. ? extend({}, style)
  62. : style
  63. const newStyle = getStyle(vnode, true)
  64. for (name in oldStyle) {
  65. if (isUndef(newStyle[name])) {
  66. setProp(el, name, '')
  67. }
  68. }
  69. for (name in newStyle) {
  70. cur = newStyle[name]
  71. if (cur !== oldStyle[name]) {
  72. // ie9 setting to null has no effect, must use empty string
  73. setProp(el, name, cur == null ? '' : cur)
  74. }
  75. }
  76. }
  77. export default {
  78. create: updateStyle,
  79. update: updateStyle
  80. }