Skip to content

Commit a350926

Browse files
committed
feat(compiler): allow unicode characters for component name
resolve vuejs#8564
1 parent 21112ec commit a350926

File tree

3 files changed

+17
-8
lines changed

3 files changed

+17
-8
lines changed

src/compiler/parser/html-parser.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ import { isNonPhrasingTag } from 'web/compiler/util'
1414

1515
// Regular Expressions for parsing tags and attributes
1616
const attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/
17-
// could use https://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-QName
18-
// but for Vue templates we can enforce a simple charset
19-
const ncname = '[a-zA-Z_][\\w\\-\\.]*'
17+
// use https://www.w3.org/TR/html53/semantics-scripting.html#potentialcustomelementname
18+
// except \u10000-\uEFFFF because of performance problem
19+
export const pcenchars = '[\\-\\.0-9_a-zA-Z\\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]'
20+
const ncname = `[a-zA-Z_]${pcenchars}*`
2021
const qnameCapture = `((?:${ncname}\\:)?${ncname})`
2122
const startTagOpen = new RegExp(`^<${qnameCapture}`)
2223
const startTagClose = /^\s*(\/?)>/

src/core/util/options.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import config from '../config'
44
import { warn } from './debug'
55
import { nativeWatch } from './env'
66
import { set } from '../observer/index'
7+
import { pcenchars } from '../../compiler/parser/html-parser'
78

89
import {
910
ASSET_TYPES,
@@ -253,11 +254,10 @@ function checkComponents (options: Object) {
253254
}
254255

255256
export function validateComponentName (name: string) {
256-
if (!/^[a-zA-Z][\w-]*$/.test(name)) {
257+
if (!new RegExp(`^[a-zA-Z]${pcenchars}*$`).test(name)) {
257258
warn(
258259
'Invalid component name: "' + name + '". Component names ' +
259-
'can only contain alphanumeric characters and the hyphen, ' +
260-
'and must start with a letter.'
260+
'should conform to valid custom element name in html5 specification.'
261261
)
262262
}
263263
if (isBuiltInTag(name) || config.isReservedTag(name)) {

test/unit/features/options/name.spec.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ describe('Options name', () => {
1515
})
1616

1717
/* eslint-disable */
18-
expect(`Invalid component name: "Hyper*Vue". Component names can only contain alphanumeric characters and the hyphen, and must start with a letter.`)
18+
expect(`Invalid component name: "Hyper*Vue".`)
1919
.toHaveBeenWarned()
2020
/* eslint-enable */
2121

@@ -24,7 +24,7 @@ describe('Options name', () => {
2424
})
2525

2626
/* eslint-disable */
27-
expect(`Invalid component name: "2Cool2BValid". Component names can only contain alphanumeric characters and the hyphen, and must start with a letter.`)
27+
expect(`Invalid component name: "2Cool2BValid".`)
2828
.toHaveBeenWarned()
2929
/* eslint-enable */
3030
})
@@ -37,4 +37,12 @@ describe('Options name', () => {
3737
expect(SuperComponent.options.components['SuperVue']).toEqual(SuperComponent)
3838
expect(SuperComponent.options.components['super-component']).toEqual(SuperComponent)
3939
})
40+
41+
it('should allow all potential custom element name for component name including non-alphanumeric characters', () => {
42+
Vue.extend({
43+
name: 'my-컴포넌트'
44+
})
45+
46+
expect(`Invalid component name`).not.toHaveBeenWarned()
47+
})
4048
})

0 commit comments

Comments
 (0)