Skip to content

Commit d9fa2b4

Browse files
committed
support objects in v-bind
1 parent ca6934d commit d9fa2b4

File tree

5 files changed

+55
-19
lines changed

5 files changed

+55
-19
lines changed

src/directives/internal/style.js

+15-16
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ var _ = require('../../util')
22
var prefixes = ['-webkit-', '-moz-', '-ms-']
33
var camelPrefixes = ['Webkit', 'Moz', 'ms']
44
var importantRE = /!important;?$/
5-
var camelRE = /([a-z])([A-Z])/g
65
var testEl = null
76
var propCache = {}
87

@@ -14,33 +13,33 @@ module.exports = {
1413
if (typeof value === 'string') {
1514
this.el.style.cssText = value
1615
} else if (_.isArray(value)) {
17-
this.objectHandler(value.reduce(_.extend, {}))
16+
this.handleObject(value.reduce(_.extend, {}))
1817
} else {
19-
this.objectHandler(value)
18+
this.handleObject(value || {})
2019
}
2120
},
2221

23-
objectHandler: function (value) {
22+
handleObject: function (value) {
2423
// cache object styles so that only changed props
2524
// are actually updated.
2625
var cache = this.cache || (this.cache = {})
27-
var prop, val
28-
for (prop in cache) {
29-
if (!(prop in value)) {
30-
this.setProp(prop, null)
31-
delete cache[prop]
26+
var name, val
27+
for (name in cache) {
28+
if (!(name in value)) {
29+
this.handleSingle(name, null)
30+
delete cache[name]
3231
}
3332
}
34-
for (prop in value) {
35-
val = value[prop]
36-
if (val !== cache[prop]) {
37-
cache[prop] = val
38-
this.setProp(prop, val)
33+
for (name in value) {
34+
val = value[name]
35+
if (val !== cache[name]) {
36+
cache[name] = val
37+
this.handleSingle(name, val)
3938
}
4039
}
4140
},
4241

43-
setProp: function (prop, value) {
42+
handleSingle: function (prop, value) {
4443
prop = normalize(prop)
4544
if (!prop) return // unsupported prop
4645
// cast possible numbers/booleans into strings
@@ -88,7 +87,7 @@ function normalize (prop) {
8887
*/
8988

9089
function prefix (prop) {
91-
prop = prop.replace(camelRE, '$1-$2').toLowerCase()
90+
prop = _.hyphenate(prop)
9291
var camel = _.camelize(prop)
9392
var upper = camel.charAt(0).toUpperCase() + camel.slice(1)
9493
if (!testEl) {

src/directives/public/bind.js

+11
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,17 @@ module.exports = {
7474
return
7575
}
7676
var attr = this.arg
77+
if (this.arg) {
78+
this.handleSingle(attr, value)
79+
} else {
80+
this.handleObject(value || {})
81+
}
82+
},
83+
84+
// share object handler with v-bind:class
85+
handleObject: require('../internal/style').handleObject,
86+
87+
handleSingle: function (attr, value) {
7788
if (inputProps[attr] && attr in this.el) {
7889
this.el[attr] = value
7990
}

src/util/lang.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,9 @@ exports.stripQuotes = function (str) {
156156
* @return {String}
157157
*/
158158

159+
var camelizeRE = /-(\w)/g
159160
exports.camelize = function (str) {
160-
return str.replace(/-(\w)/g, toUpper)
161+
return str.replace(camelizeRE, toUpper)
161162
}
162163

163164
function toUpper (_, c) {
@@ -171,9 +172,10 @@ function toUpper (_, c) {
171172
* @return {String}
172173
*/
173174

175+
var hyphenateRE = /([a-z\d])([A-Z])/g
174176
exports.hyphenate = function (str) {
175177
return str
176-
.replace(/([a-z\d])([A-Z])/g, '$1-$2')
178+
.replace(hyphenateRE, '$1-$2')
177179
.toLowerCase()
178180
}
179181

test/unit/specs/directives/internal/style_spec.js

+6
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ if (_.inBrowser) {
8888
expect(el.style.getPropertyValue('color')).toBe('blue')
8989
expect(el.style.getPropertyValue('margin-right')).toBeFalsy()
9090
expect(el.style.getPropertyValue('padding')).toBeFalsy()
91+
92+
// handle falsy value
93+
dir.update(null)
94+
expect(el.style.getPropertyValue('color')).toBeFalsy()
95+
expect(el.style.getPropertyValue('margin-right')).toBeFalsy()
96+
expect(el.style.getPropertyValue('padding')).toBeFalsy()
9197
})
9298

9399
it('array of objects', function () {

test/unit/specs/directives/public/bind_spec.js

+19-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
var _ = require('../../../../../src/util')
22
var def = require('../../../../../src/directives/public/bind')
3+
var xlinkNS = 'http://www.w3.org/1999/xlink'
34

45
if (_.inBrowser) {
56
describe('v-bind', function () {
@@ -39,7 +40,6 @@ if (_.inBrowser) {
3940
})
4041

4142
it('xlink', function () {
42-
var xlinkNS = 'http://www.w3.org/1999/xlink'
4343
dir.arg = 'xlink:special'
4444
dir.update('ok')
4545
expect(el.getAttributeNS(xlinkNS, 'special')).toBe('ok')
@@ -48,5 +48,23 @@ if (_.inBrowser) {
4848
dir.update(null)
4949
expect(el.hasAttributeNS(xlinkNS, 'special')).toBe(false)
5050
})
51+
52+
it('object format', function () {
53+
dir.el = document.createElement('input')
54+
dir.update({
55+
'test': 'hi',
56+
'value': 'what'
57+
})
58+
expect(dir.el.getAttribute('test')).toBe('hi')
59+
expect(dir.el.value).toBe('what')
60+
dir.update({
61+
'xlink:special': 'ok'
62+
})
63+
expect(dir.el.hasAttribute('test')).toBe(false)
64+
expect(dir.el.value).toBeFalsy()
65+
expect(dir.el.getAttributeNS(xlinkNS, 'special')).toBe('ok')
66+
dir.update(null)
67+
expect(dir.el.hasAttributeNS(xlinkNS, 'special')).toBe(false)
68+
})
5169
})
5270
}

0 commit comments

Comments
 (0)