Skip to content

Commit c884e47

Browse files
committed
+ Update domProps detection.
1 parent fa4588e commit c884e47

File tree

4 files changed

+41
-38
lines changed

4 files changed

+41
-38
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ And in `.swcrc`:
7070
}
7171
```
7272

73-
### Vite (with SWC for example)
73+
### Vite
7474

7575
Please read the section below.
7676

@@ -437,7 +437,7 @@ For Vite users, it's better to use TSC or SWC instead of built-in ESBuild. Becau
437437

438438
For faster compilation, SWC is recommended. You can use [unplugin-swc](https://github.com/egoist/unplugin-swc) to make Vite uses SWC.
439439

440-
Once you have switched to SWC (TSC) from ESBuild, you will not only be able to use this package, but also get more features like `emitDecoratorMetadata` which is not supported by ESBuild, and the whole process is still darn fast.
440+
Once you have switched to SWC (TSC) from ESBuild, you will not only be able to use JSX, but also get more features like `emitDecoratorMetadata` which is not supported by ESBuild, and the whole process is still darn fast.
441441

442442
### Configuration
443443

lib/directives/v-model.ts

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { checkIsInputOrTextarea, checkIsRefObj, isArray, isString, isUndefined } from '../utils'
1+
import { checkIsRefObj, isArray, isString, isUndefined } from '../utils'
22
import type { Ref } from '@vue/composition-api'
33
import type { VNodeData } from 'vue'
44
import { ConfigType, TagType } from '../type'
@@ -35,27 +35,34 @@ const dealWithVModel = (
3535
}
3636
}
3737

38-
if (checkIsInputOrTextarea(tag)) {
39-
const isInput = tag === 'input'
40-
const inputType = config.type // 'file', 'text', 'number', .ect.
38+
const instance = getCurrentInstance()
4139

42-
// Skip unsupported input.
43-
const isSkippedInput = /button|submit|reset/.test(inputType)
44-
if (isSkippedInput) {
45-
return
40+
if (tag === 'select') {
41+
vNodeData.domProps.value = isString(bindingTarget)
42+
? instance[bindingTarget]
43+
: bindingTarget.value
44+
vNodeData.on.change = (event: Event) => {
45+
const target = event.target as HTMLSelectElement
46+
if (isString(bindingTarget)) {
47+
instance[bindingTarget] = target.value
48+
} else {
49+
bindingTarget.value = target.value
50+
}
4651
}
52+
return
53+
}
4754

48-
const instance = getCurrentInstance()
55+
if (tag === 'input') {
56+
const inputType = config.type // 'file', 'text', 'number', .ect.
4957

50-
// File.
51-
const isFileInput = isInput && inputType === 'file'
52-
if (isFileInput) {
53-
// TODO: ...
58+
// Skip unsupported input.
59+
const isSkippedInput = /button|file|submit|reset/.test(inputType)
60+
if (isSkippedInput) {
5461
return
5562
}
5663

5764
// Radio.
58-
const isRadioInput = isInput && inputType === 'radio'
65+
const isRadioInput = inputType === 'radio'
5966
if (isRadioInput) {
6067
vNodeData.domProps.checked = isString(bindingTarget)
6168
? instance[bindingTarget] === config.value
@@ -72,7 +79,7 @@ const dealWithVModel = (
7279
}
7380

7481
// Checkbox.
75-
const isCheckboxInput = isInput && inputType === 'checkbox'
82+
const isCheckboxInput = inputType === 'checkbox'
7683
if (isCheckboxInput) {
7784
const arrayBindingExec = (bindingArr: unknown[]) => {
7885
vNodeData.domProps.checked = bindingArr.includes(config.value)
@@ -121,8 +128,10 @@ const dealWithVModel = (
121128
}
122129
return
123130
}
131+
}
124132

125-
// Others are treated as text fields.
133+
// Others are treated as text fields.
134+
if (tag === 'input' || tag === 'textarea') {
126135
const isDirectInput = modifiers.includes('direct')
127136
const isLazyInput = modifiers.includes('lazy')
128137
const emitValue = (value: string) => {
@@ -147,7 +156,7 @@ const dealWithVModel = (
147156
: bindingTarget.value
148157
vNodeData.on.input = (event: Event) => {
149158
if (
150-
modifiers.includes('lazy') ||
159+
isLazyInput ||
151160
(!isDirectInput && vNodeData.attrs[IME_START_KEY])
152161
) {
153162
return

lib/jsx.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
checkKeyIsNativeOn,
66
checkKeyIsChildren,
77
checkKeyIsClass,
8-
checkKeyIsHtmlAttr,
8+
checkKeyIsDomProp,
99
checkKeyIsKey,
1010
checkKeyIsOnEvent,
1111
checkKeyIsOnObject,
@@ -121,10 +121,10 @@ const jsx = function (
121121
}
122122

123123
if (isHTMLElement) {
124-
if (checkKeyIsHtmlAttr(key)) {
125-
vNodeData.attrs[key] = value
126-
} else {
124+
if (checkKeyIsDomProp(key)) {
127125
vNodeData.domProps[key] = value
126+
} else {
127+
vNodeData.attrs[key] = value
128128
}
129129
} else {
130130
vNodeData.props[key] = value

lib/utils.ts

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,20 @@
11
import { camelCase } from 'change-case'
22

33
// https://github.com/vuejs/vue/blob/0603ff695d2f41286239298210113cbe2b209e28/src/platforms/web/server/util.js#L5
4-
// Difference:
5-
// + role
6-
// - id
7-
const htmlAttrList = (
8-
'accept,accept-charset,accesskey,action,align,alt,async,autocomplete,' +
4+
const domPropsList = 'accept,accesskey,action,align,alt,async,autocomplete,' +
95
'autofocus,autoplay,autosave,bgcolor,border,buffered,challenge,charset,' +
10-
'checked,cite,class,code,codebase,color,cols,colspan,content,' +
6+
'checked,cite,code,codebase,color,cols,colspan,content,' +
117
'contenteditable,contextmenu,controls,coords,data,datetime,default,' +
128
'defer,dir,dirname,disabled,download,draggable,dropzone,enctype,for,' +
13-
'form,formaction,headers,height,hidden,high,href,hreflang,http-equiv,' +
14-
'icon,ismap,itemprop,keytype,kind,label,lang,language,list,loop,low,' +
9+
'form,formaction,headers,height,hidden,high,href,hreflang,' +
10+
'icon,id,ismap,itemprop,keytype,kind,label,lang,language,list,loop,low,' +
1511
'manifest,max,maxlength,media,method,GET,POST,min,multiple,email,file,' +
1612
'muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,' +
17-
'preload,radiogroup,readonly,rel,required,reversed,role,rows,rowspan,sandbox,' +
13+
'preload,radiogroup,readonly,rel,required,reversed,rows,rowspan,sandbox,' +
1814
'scope,scoped,seamless,selected,shape,size,type,text,password,sizes,span,' +
1915
'spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,' +
20-
'target,title,usemap,value,width,wrap'
21-
).split(',')
16+
'target,title,usemap,value,width,wrap,' +
17+
'className,classList,innerHTML,innerText,outerHTML,outerText,textContent'.split(',')
2218

2319
const ON_EVENT_REGEXP = /^((v(-o|O)n:)|on)/
2420
const HTML_TAG_REGEXP = /^[\da-z]+$/
@@ -37,7 +33,7 @@ const checkIsHTMLElement = (tag: unknown) => isString(tag) && HTML_TAG_REGEXP.te
3733
const checkKeyIsClass = (key: string) => key === 'class'
3834
const checkKeyIsChildren = (key: string) => key === 'children'
3935
const checkKeyIsStyle = (key: string) => key === 'style'
40-
const checkKeyIsHtmlAttr = (key: string) => htmlAttrList.includes(key) || key.indexOf('data-') === 0 || key.indexOf('aria-') === 0
36+
const checkKeyIsDomProp = (key: string) => domPropsList.includes(key)
4137
const checkKeyIsOnEvent = (key: string) => ON_EVENT_REGEXP.test(key)
4238
const checkKeyIsOnObject = (key: string) => key === 'on'
4339
const checkKeyIsSlot = (key: string) => key === 'slot'
@@ -46,7 +42,6 @@ const checkKeyIsKey = (key: string) => key === 'key'
4642
const checkKeyIsNativeOn = (key: string) => NATIVE_ON_REGEXP.test(key)
4743
const checkKeyIsVueDirective = (key: string) => /^v(-|[A-Z])/.test(key)
4844
const checkKeyIsRef = (key: string) => key === 'ref'
49-
const checkIsInputOrTextarea = (target: unknown): target is 'input' | 'textarea' => target === 'input' || target === 'textarea'
5045

5146
// The reason why I don't use "isRef" which is provided by @vue/composition-api is that
5247
// this function will be broken under SWC.
@@ -76,7 +71,7 @@ export {
7671
checkKeyIsClass,
7772
checkKeyIsChildren,
7873
checkKeyIsStyle,
79-
checkKeyIsHtmlAttr,
74+
checkKeyIsDomProp,
8075
checkKeyIsOnEvent,
8176
checkKeyIsOnObject,
8277
checkKeyIsSlot,
@@ -87,7 +82,6 @@ export {
8782
checkIsRefObj,
8883

8984
checkKeyIsVueDirective,
90-
checkIsInputOrTextarea,
9185

9286
removeOn,
9387
removeNativeOn

0 commit comments

Comments
 (0)