Skip to content

Commit

Permalink
fix: allow more enumerated values for contenteditable
Browse files Browse the repository at this point in the history
close #9397
  • Loading branch information
yyx990803 committed Jan 31, 2019
1 parent 6afd96f commit e632e9a
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 12 deletions.
5 changes: 3 additions & 2 deletions src/platforms/web/runtime/modules/attrs.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import {
getXlinkProp,
isBooleanAttr,
isEnumeratedAttr,
isFalsyAttrValue
isFalsyAttrValue,
convertEnumeratedValue
} from 'web/util/index'

function updateAttrs (oldVnode: VNodeWithData, vnode: VNodeWithData) {
Expand Down Expand Up @@ -75,7 +76,7 @@ function setAttr (el: Element, key: string, value: any) {
el.setAttribute(key, value)
}
} else if (isEnumeratedAttr(key)) {
el.setAttribute(key, isFalsyAttrValue(value) || value === 'false' ? 'false' : 'true')
el.setAttribute(key, convertEnumeratedValue(key, value))
} else if (isXlink(key)) {
if (isFalsyAttrValue(value)) {
el.removeAttributeNS(xlinkNS, getXlinkProp(key))
Expand Down
5 changes: 3 additions & 2 deletions src/platforms/web/server/modules/attrs.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
import {
isBooleanAttr,
isEnumeratedAttr,
isFalsyAttrValue
isFalsyAttrValue,
convertEnumeratedValue
} from 'web/util/attrs'

import { isSSRUnsafeAttr } from 'web/server/util'
Expand Down Expand Up @@ -54,7 +55,7 @@ export function renderAttr (key: string, value: string): string {
return ` ${key}="${key}"`
}
} else if (isEnumeratedAttr(key)) {
return ` ${key}="${isFalsyAttrValue(value) || value === 'false' ? 'false' : 'true'}"`
return ` ${key}="${escape(convertEnumeratedValue(key, value))}"`
} else if (!isFalsyAttrValue(value)) {
return ` ${key}="${escape(String(value))}"`
}
Expand Down
11 changes: 11 additions & 0 deletions src/platforms/web/util/attrs.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ export const mustUseProp = (tag: string, type: ?string, attr: string): boolean =

export const isEnumeratedAttr = makeMap('contenteditable,draggable,spellcheck')

const isValidContentEditableValue = makeMap('events,caret,typing,plaintext-only')

export const convertEnumeratedValue = (key: string, value: any) => {
return isFalsyAttrValue(value) || value === 'false'
? 'false'
// allow arbitrary string value for contenteditable
: key === 'contenteditable' && isValidContentEditableValue(value)
? value
: 'true'
}

export const isBooleanAttr = makeMap(
'allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,' +
'default,defaultchecked,defaultmuted,defaultselected,defer,disabled,' +
Expand Down
16 changes: 8 additions & 8 deletions test/unit/features/directives/bind.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,25 +69,25 @@ describe('Directive v-bind', () => {

it('enumerated attr', done => {
const vm = new Vue({
template: '<div><span :draggable="foo">hello</span></div>',
template: '<div><span :contenteditable="foo">hello</span></div>',
data: { foo: true }
}).$mount()
expect(vm.$el.firstChild.getAttribute('draggable')).toBe('true')
vm.foo = 'again'
expect(vm.$el.firstChild.getAttribute('contenteditable')).toBe('true')
vm.foo = 'plaintext-only' // allow special values
waitForUpdate(() => {
expect(vm.$el.firstChild.getAttribute('draggable')).toBe('true')
expect(vm.$el.firstChild.getAttribute('contenteditable')).toBe('plaintext-only')
vm.foo = null
}).then(() => {
expect(vm.$el.firstChild.getAttribute('draggable')).toBe('false')
expect(vm.$el.firstChild.getAttribute('contenteditable')).toBe('false')
vm.foo = ''
}).then(() => {
expect(vm.$el.firstChild.getAttribute('draggable')).toBe('true')
expect(vm.$el.firstChild.getAttribute('contenteditable')).toBe('true')
vm.foo = false
}).then(() => {
expect(vm.$el.firstChild.getAttribute('draggable')).toBe('false')
expect(vm.$el.firstChild.getAttribute('contenteditable')).toBe('false')
vm.foo = 'false'
}).then(() => {
expect(vm.$el.firstChild.getAttribute('draggable')).toBe('false')
expect(vm.$el.firstChild.getAttribute('contenteditable')).toBe('false')
}).then(done)
})

Expand Down

0 comments on commit e632e9a

Please sign in to comment.