From 5fb1a549d2104d01b8b9711079c7d7701514c890 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 7 May 2016 16:27:33 -0400 Subject: [PATCH] make attr behavior more consistent + fix tests --- src/platforms/web/runtime/modules/attrs.js | 21 ++++++++++++++------- src/platforms/web/server/modules/attrs.js | 17 ++++++++++------- src/platforms/web/util/attrs.js | 1 + test/ssr/ssr.sync.spec.js | 6 +++++- test/unit/features/directives/bind.spec.js | 10 ++++++++-- 5 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/platforms/web/runtime/modules/attrs.js b/src/platforms/web/runtime/modules/attrs.js index 7563e89d..121a3ea3 100644 --- a/src/platforms/web/runtime/modules/attrs.js +++ b/src/platforms/web/runtime/modules/attrs.js @@ -1,4 +1,11 @@ -import { isBooleanAttr, isEnumeratedAttr, isXlink, xlinkNS, getXlinkProp } from 'web/util/index' +import { + isBooleanAttr, + isEnumeratedAttr, + isXlink, + xlinkNS, + getXlinkProp, + isFalsyAttrValue +} from 'web/util/index' function updateAttrs (oldVnode, vnode) { if (!oldVnode.data.attrs && !vnode.data.attrs) { @@ -31,24 +38,24 @@ function setAttr (el, key, value) { if (isBooleanAttr(key)) { // set attribute for blank value // e.g. - if (value == null || value === false) { + if (isFalsyAttrValue(value)) { el.removeAttribute(key) } else { el.setAttribute(key, key) } } else if (isEnumeratedAttr(key)) { - el.setAttribute(key, value ? 'true' : 'false') + el.setAttribute(key, isFalsyAttrValue(value) || value === 'false' ? 'false' : 'true') } else if (isXlink(key)) { - if (value == null || value === false) { + if (isFalsyAttrValue(value)) { el.removeAttributeNS(xlinkNS, getXlinkProp(key)) } else { - el.setAttributeNS(xlinkNS, key, value === true ? '' : value) + el.setAttributeNS(xlinkNS, key, value) } } else { - if (value == null || value === false) { + if (isFalsyAttrValue(value)) { el.removeAttribute(key) } else { - el.setAttribute(key, value === true ? '' : value) + el.setAttribute(key, value) } } } diff --git a/src/platforms/web/server/modules/attrs.js b/src/platforms/web/server/modules/attrs.js index debdc98b..69c66a38 100644 --- a/src/platforms/web/server/modules/attrs.js +++ b/src/platforms/web/server/modules/attrs.js @@ -1,4 +1,9 @@ -import { isBooleanAttr, isEnumeratedAttr, propsToAttrMap } from 'web/util/index' +import { + isBooleanAttr, + isEnumeratedAttr, + isFalsyAttrValue, + propsToAttrMap +} from 'web/util/index' export default function renderAttrs (node) { if (node.data.attrs || node.data.props || node.data.staticAttrs) { @@ -25,15 +30,13 @@ function serialize (attrs, asProps) { } const value = attrs[key] if (isBooleanAttr(key)) { - if (!(value == null || value === false)) { + if (!isFalsyAttrValue(value)) { res += ` ${key}="${key}"` } } else if (isEnumeratedAttr(key)) { - res += ` ${key}="${value ? 'true' : 'false'}"` - } else { - if (!(value == null || value === false)) { - res += ` ${key}="${value === true ? '' : value}"` - } + res += ` ${key}="${isFalsyAttrValue(value) || value === 'false' ? 'false' : 'true'}"` + } else if (!isFalsyAttrValue(value)) { + res += ` ${key}="${value}"` } } return res diff --git a/src/platforms/web/util/attrs.js b/src/platforms/web/util/attrs.js index 799ab535..1429e3c7 100644 --- a/src/platforms/web/util/attrs.js +++ b/src/platforms/web/util/attrs.js @@ -24,3 +24,4 @@ export const propsToAttrMap = { export const xlinkNS = 'http://www.w3.org/1999/xlink' export const isXlink = name => name.charAt(5) === ':' && name.slice(0, 5) === 'xlink' export const getXlinkProp = name => isXlink(name) ? name.slice(6, name.length) : '' +export const isFalsyAttrValue = val => val == null || val === false diff --git a/test/ssr/ssr.sync.spec.js b/test/ssr/ssr.sync.spec.js index a84cfd39..cf1b2ce7 100644 --- a/test/ssr/ssr.sync.spec.js +++ b/test/ssr/ssr.sync.spec.js @@ -142,7 +142,7 @@ describe('SSR: renderToString', () => { 'hello' + 'hello' + 'hello' + - 'hello' + + 'hello' + 'hello' + '' ) @@ -155,7 +155,9 @@ describe('SSR: renderToString', () => { hello hello hello + hello hello + hello ` })).toContain( @@ -163,7 +165,9 @@ describe('SSR: renderToString', () => { 'hello' + 'hello' + 'hello' + + 'hello' + 'hello' + + 'hello' + '' ) }) diff --git a/test/unit/features/directives/bind.spec.js b/test/unit/features/directives/bind.spec.js index 3e123efa..2da17d4f 100644 --- a/test/unit/features/directives/bind.spec.js +++ b/test/unit/features/directives/bind.spec.js @@ -19,7 +19,7 @@ describe('Directive v-bind', () => { expect(vm.$el.firstChild.hasAttribute('test')).toBe(false) vm.foo = true }).then(() => { - expect(vm.$el.firstChild.getAttribute('test')).toBe('') + expect(vm.$el.firstChild.getAttribute('test')).toBe('true') vm.foo = 0 }).then(() => { expect(vm.$el.firstChild.getAttribute('test')).toBe('0') @@ -68,7 +68,7 @@ describe('Directive v-bind', () => { expect(vm.$el.firstChild.hasAttributeNS(xlinkNS, 'special')).toBe(false) vm.foo = true }).then(() => { - expect(vm.$el.firstChild.getAttributeNS(xlinkNS, 'special')).toBe('') + expect(vm.$el.firstChild.getAttributeNS(xlinkNS, 'special')).toBe('true') done() }).catch(done) }) @@ -87,6 +87,12 @@ describe('Directive v-bind', () => { }).then(() => { expect(vm.$el.firstChild.getAttribute('draggable')).toBe('false') vm.foo = '' + }).then(() => { + expect(vm.$el.firstChild.getAttribute('draggable')).toBe('true') + vm.foo = false + }).then(() => { + expect(vm.$el.firstChild.getAttribute('draggable')).toBe('false') + vm.foo = 'false' }).then(() => { expect(vm.$el.firstChild.getAttribute('draggable')).toBe('false') done()