style.spec.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import Vue from 'vue'
  2. import { extend } from 'shared/util'
  3. function checkPrefixedProp (prop) {
  4. var el = document.createElement('div')
  5. var upper = prop.charAt(0).toUpperCase() + prop.slice(1)
  6. if (!(prop in el.style)) {
  7. var prefixes = ['Webkit', 'Moz', 'ms']
  8. var i = prefixes.length
  9. while (i--) {
  10. if ((prefixes[i] + upper) in el.style) {
  11. prop = prefixes[i] + upper
  12. }
  13. }
  14. }
  15. return prop
  16. }
  17. describe('Directive v-bind:style', () => {
  18. let vm
  19. beforeEach(() => {
  20. vm = new Vue({
  21. template: '<div :style="styles"></div>',
  22. data () {
  23. return {
  24. styles: {},
  25. fontSize: 16
  26. }
  27. }
  28. }).$mount()
  29. })
  30. it('plain object', done => {
  31. vm.styles = { color: 'red' }
  32. waitForUpdate(() => {
  33. expect(vm.$el.style.cssText.replace(/\s/g, '')).toBe('color:red;')
  34. }).then(done)
  35. })
  36. it('camelCase', done => {
  37. vm.styles = { marginRight: '10px' }
  38. waitForUpdate(() => {
  39. expect(vm.$el.style.marginRight).toBe('10px')
  40. }).then(done)
  41. })
  42. it('remove if falsy value', done => {
  43. vm.$el.style.color = 'red'
  44. waitForUpdate(() => {
  45. vm.styles = { color: null }
  46. }).then(() => {
  47. expect(vm.$el.style.color).toBe('')
  48. }).then(done)
  49. })
  50. it('ignore unsupported property', done => {
  51. vm.styles = { foo: 'bar' }
  52. waitForUpdate(() => {
  53. expect(vm.$el.style.foo).not.toBe('bar')
  54. }).then(done)
  55. })
  56. it('auto prefix', done => {
  57. const prop = checkPrefixedProp('transform')
  58. const val = 'scale(0.5)'
  59. vm.styles = { transform: val }
  60. waitForUpdate(() => {
  61. expect(vm.$el.style[prop]).toBe(val)
  62. }).then(done)
  63. })
  64. it('object with multiple entries', done => {
  65. vm.$el.style.color = 'red'
  66. vm.styles = {
  67. marginLeft: '10px',
  68. marginRight: '15px'
  69. }
  70. waitForUpdate(() => {
  71. expect(vm.$el.style.getPropertyValue('color')).toBe('red')
  72. expect(vm.$el.style.getPropertyValue('margin-left')).toBe('10px')
  73. expect(vm.$el.style.getPropertyValue('margin-right')).toBe('15px')
  74. vm.styles = {
  75. color: 'blue',
  76. padding: null
  77. }
  78. }).then(() => {
  79. expect(vm.$el.style.getPropertyValue('color')).toBe('blue')
  80. expect(vm.$el.style.getPropertyValue('padding')).toBeFalsy()
  81. expect(vm.$el.style.getPropertyValue('margin-left')).toBeFalsy()
  82. expect(vm.$el.style.getPropertyValue('margin-right')).toBeFalsy()
  83. // handle falsy value
  84. vm.styles = null
  85. }).then(() => {
  86. expect(vm.$el.style.getPropertyValue('color')).toBeFalsy()
  87. expect(vm.$el.style.getPropertyValue('padding')).toBeFalsy()
  88. expect(vm.$el.style.getPropertyValue('margin-left')).toBeFalsy()
  89. expect(vm.$el.style.getPropertyValue('margin-right')).toBeFalsy()
  90. }).then(done)
  91. })
  92. it('array of objects', done => {
  93. vm.$el.style.padding = '10px'
  94. vm.styles = [{ color: 'red' }, { marginRight: '20px' }]
  95. waitForUpdate(() => {
  96. expect(vm.$el.style.getPropertyValue('color')).toBe('red')
  97. expect(vm.$el.style.getPropertyValue('margin-right')).toBe('20px')
  98. expect(vm.$el.style.getPropertyValue('padding')).toBe('10px')
  99. vm.styles = [{ color: 'blue' }, { padding: null }]
  100. }).then(() => {
  101. expect(vm.$el.style.getPropertyValue('color')).toBe('blue')
  102. expect(vm.$el.style.getPropertyValue('margin-right')).toBeFalsy()
  103. expect(vm.$el.style.getPropertyValue('padding')).toBeFalsy()
  104. }).then(done)
  105. })
  106. it('updates objects deeply', done => {
  107. const el = document.createElement('div')
  108. el.setAttribute(':style', 'divStyling')
  109. vm = new Vue({
  110. el,
  111. data () {
  112. return {
  113. divStyling: { display: 'none' }
  114. }
  115. }
  116. })
  117. waitForUpdate(() => {
  118. expect(vm.$el.style.display).toBe('none')
  119. vm.divStyling = extend({}, { display: 'block' })
  120. }).then(() => {
  121. expect(vm.$el.style.display).toBe('block')
  122. }).then(done)
  123. })
  124. it('background size with only one value', done => {
  125. vm.styles = { backgroundSize: '100%' }
  126. waitForUpdate(() => {
  127. expect(vm.$el.style.cssText.replace(/\s/g, '')).toMatch(/background-size:100%(auto)?;/)
  128. }).then(done)
  129. })
  130. it('should work with interpolation', done => {
  131. vm.styles = { fontSize: `${vm.fontSize}px` }
  132. waitForUpdate(() => {
  133. expect(vm.$el.style.fontSize).toBe('16px')
  134. }).then(done)
  135. })
  136. })