11import Vue from 'vue'
22import { looseEqual } from 'shared/util'
33
4+ // Android 4.4 Chrome 30 has the bug that a multi-select option cannot be
5+ // deseleted by setting its "selected" prop via JavaScript.
6+ function hasMultiSelectBug ( ) {
7+ var s = document . createElement ( 'select' )
8+ s . setAttribute ( 'multiple' , '' )
9+ s . innerHTML = '<option>1</option>'
10+ s . options [ 0 ] . selected = true
11+ s . options [ 0 ] . selected = false
12+ return s . options [ 0 ] . selected !== false
13+ }
14+
415/**
516 * setting <select>'s value in IE9 doesn't work
617 * we have to manually loop through the options
@@ -187,33 +198,68 @@ describe('Directive v-model select', () => {
187198 } ) . then ( done )
188199 } )
189200
190- it ( 'multiple' , done => {
191- const vm = new Vue ( {
192- data : {
193- test : [ 'b' ]
194- } ,
195- template :
196- '<select v-model="test" multiple>' +
197- '<option>a</option>' +
198- '<option>b</option>' +
199- '<option>c</option>' +
200- '</select>'
201- } ) . $mount ( )
202- var opts = vm . $el . options
203- expect ( opts [ 0 ] . selected ) . toBe ( false )
204- expect ( opts [ 1 ] . selected ) . toBe ( true )
205- expect ( opts [ 2 ] . selected ) . toBe ( false )
206- vm . test = [ 'a' , 'c' ]
207- waitForUpdate ( ( ) => {
208- expect ( opts [ 0 ] . selected ) . toBe ( true )
209- expect ( opts [ 1 ] . selected ) . toBe ( false )
210- expect ( opts [ 2 ] . selected ) . toBe ( true )
211- opts [ 0 ] . selected = false
212- opts [ 1 ] . selected = true
213- triggerEvent ( vm . $el , 'change' )
214- expect ( vm . test ) . toEqual ( [ 'b' , 'c' ] )
215- } ) . then ( done )
216- } )
201+ if ( ! hasMultiSelectBug ( ) ) {
202+ it ( 'multiple' , done => {
203+ const vm = new Vue ( {
204+ data : {
205+ test : [ 'b' ]
206+ } ,
207+ template :
208+ '<select v-model="test" multiple>' +
209+ '<option>a</option>' +
210+ '<option>b</option>' +
211+ '<option>c</option>' +
212+ '</select>'
213+ } ) . $mount ( )
214+ var opts = vm . $el . options
215+ expect ( opts [ 0 ] . selected ) . toBe ( false )
216+ expect ( opts [ 1 ] . selected ) . toBe ( true )
217+ expect ( opts [ 2 ] . selected ) . toBe ( false )
218+ vm . test = [ 'a' , 'c' ]
219+ waitForUpdate ( ( ) => {
220+ expect ( opts [ 0 ] . selected ) . toBe ( true )
221+ expect ( opts [ 1 ] . selected ) . toBe ( false )
222+ expect ( opts [ 2 ] . selected ) . toBe ( true )
223+ opts [ 0 ] . selected = false
224+ opts [ 1 ] . selected = true
225+ triggerEvent ( vm . $el , 'change' )
226+ expect ( vm . test ) . toEqual ( [ 'b' , 'c' ] )
227+ } ) . then ( done )
228+ } )
229+
230+ it ( 'multiple + v-for' , done => {
231+ const vm = new Vue ( {
232+ data : {
233+ test : [ 'b' ] ,
234+ opts : [ 'a' , 'b' , 'c' ]
235+ } ,
236+ template :
237+ '<select v-model="test" multiple>' +
238+ '<option v-for="o in opts">{{ o }}</option>' +
239+ '</select>'
240+ } ) . $mount ( )
241+ var opts = vm . $el . options
242+ expect ( opts [ 0 ] . selected ) . toBe ( false )
243+ expect ( opts [ 1 ] . selected ) . toBe ( true )
244+ expect ( opts [ 2 ] . selected ) . toBe ( false )
245+ vm . test = [ 'a' , 'c' ]
246+ waitForUpdate ( ( ) => {
247+ expect ( opts [ 0 ] . selected ) . toBe ( true )
248+ expect ( opts [ 1 ] . selected ) . toBe ( false )
249+ expect ( opts [ 2 ] . selected ) . toBe ( true )
250+ opts [ 0 ] . selected = false
251+ opts [ 1 ] . selected = true
252+ triggerEvent ( vm . $el , 'change' )
253+ expect ( vm . test ) . toEqual ( [ 'b' , 'c' ] )
254+ // update v-for opts
255+ vm . opts = [ 'c' , 'd' ]
256+ } ) . then ( ( ) => {
257+ expect ( opts [ 0 ] . selected ) . toBe ( true )
258+ expect ( opts [ 1 ] . selected ) . toBe ( false )
259+ expect ( vm . test ) . toEqual ( [ 'c' ] ) // should remove 'd' which no longer has a matching option
260+ } ) . then ( done )
261+ } )
262+ }
217263
218264 it ( 'multiple with static template' , ( ) => {
219265 const vm = new Vue ( {
@@ -230,39 +276,6 @@ describe('Directive v-model select', () => {
230276 expect ( opts [ 2 ] . selected ) . toBe ( true )
231277 } )
232278
233- it ( 'multiple + v-for' , done => {
234- const vm = new Vue ( {
235- data : {
236- test : [ 'b' ] ,
237- opts : [ 'a' , 'b' , 'c' ]
238- } ,
239- template :
240- '<select v-model="test" multiple>' +
241- '<option v-for="o in opts">{{ o }}</option>' +
242- '</select>'
243- } ) . $mount ( )
244- var opts = vm . $el . options
245- expect ( opts [ 0 ] . selected ) . toBe ( false )
246- expect ( opts [ 1 ] . selected ) . toBe ( true )
247- expect ( opts [ 2 ] . selected ) . toBe ( false )
248- vm . test = [ 'a' , 'c' ]
249- waitForUpdate ( ( ) => {
250- expect ( opts [ 0 ] . selected ) . toBe ( true )
251- expect ( opts [ 1 ] . selected ) . toBe ( false )
252- expect ( opts [ 2 ] . selected ) . toBe ( true )
253- opts [ 0 ] . selected = false
254- opts [ 1 ] . selected = true
255- triggerEvent ( vm . $el , 'change' )
256- expect ( vm . test ) . toEqual ( [ 'b' , 'c' ] )
257- // update v-for opts
258- vm . opts = [ 'c' , 'd' ]
259- } ) . then ( ( ) => {
260- expect ( opts [ 0 ] . selected ) . toBe ( true )
261- expect ( opts [ 1 ] . selected ) . toBe ( false )
262- expect ( vm . test ) . toEqual ( [ 'c' ] ) // should remove 'd' which no longer has a matching option
263- } ) . then ( done )
264- } )
265-
266279 it ( 'multiple selects' , ( done ) => {
267280 const spy = jasmine . createSpy ( )
268281 const vm = new Vue ( {
0 commit comments