feat: add isCustomElement option (#299)
This commit is contained in:
parent
b60355d857
commit
f71bf2f1d3
@ -616,6 +616,25 @@ describe('compiler: parse', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('custom element', () => {
|
||||||
|
const ast = parse('<div></div><comp></comp>', {
|
||||||
|
isNativeTag: tag => tag === 'div',
|
||||||
|
isCustomElement: tag => tag === 'comp'
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(ast.children[0]).toMatchObject({
|
||||||
|
type: NodeTypes.ELEMENT,
|
||||||
|
tag: 'div',
|
||||||
|
tagType: ElementTypes.ELEMENT
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(ast.children[1]).toMatchObject({
|
||||||
|
type: NodeTypes.ELEMENT,
|
||||||
|
tag: 'comp',
|
||||||
|
tagType: ElementTypes.ELEMENT
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
test('attribute with no value', () => {
|
test('attribute with no value', () => {
|
||||||
const ast = parse('<div id></div>')
|
const ast = parse('<div id></div>')
|
||||||
const element = ast.children[0] as ElementNode
|
const element = ast.children[0] as ElementNode
|
||||||
|
@ -32,6 +32,7 @@ import { extend } from '@vue/shared'
|
|||||||
export interface ParserOptions {
|
export interface ParserOptions {
|
||||||
isVoidTag?: (tag: string) => boolean // e.g. img, br, hr
|
isVoidTag?: (tag: string) => boolean // e.g. img, br, hr
|
||||||
isNativeTag?: (tag: string) => boolean // e.g. loading-indicator in weex
|
isNativeTag?: (tag: string) => boolean // e.g. loading-indicator in weex
|
||||||
|
isCustomElement?: (tag: string) => boolean
|
||||||
getNamespace?: (tag: string, parent: ElementNode | undefined) => Namespace
|
getNamespace?: (tag: string, parent: ElementNode | undefined) => Namespace
|
||||||
getTextMode?: (tag: string, ns: Namespace) => TextModes
|
getTextMode?: (tag: string, ns: Namespace) => TextModes
|
||||||
delimiters?: [string, string] // ['{{', '}}']
|
delimiters?: [string, string] // ['{{', '}}']
|
||||||
@ -54,6 +55,7 @@ export const defaultParserOptions: MergedParserOptions = {
|
|||||||
getNamespace: () => Namespaces.HTML,
|
getNamespace: () => Namespaces.HTML,
|
||||||
getTextMode: () => TextModes.DATA,
|
getTextMode: () => TextModes.DATA,
|
||||||
isVoidTag: NO,
|
isVoidTag: NO,
|
||||||
|
isCustomElement: NO,
|
||||||
namedCharacterReferences: {
|
namedCharacterReferences: {
|
||||||
'gt;': '>',
|
'gt;': '>',
|
||||||
'lt;': '<',
|
'lt;': '<',
|
||||||
@ -433,7 +435,7 @@ function parseTag(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let tagType = ElementTypes.ELEMENT
|
let tagType = ElementTypes.ELEMENT
|
||||||
if (!context.inPre) {
|
if (!context.inPre && !context.options.isCustomElement(tag)) {
|
||||||
if (context.options.isNativeTag) {
|
if (context.options.isNativeTag) {
|
||||||
if (!context.options.isNativeTag(tag)) tagType = ElementTypes.COMPONENT
|
if (!context.options.isNativeTag(tag)) tagType = ElementTypes.COMPONENT
|
||||||
} else {
|
} else {
|
||||||
|
@ -28,6 +28,7 @@ export interface AppConfig {
|
|||||||
devtools: boolean
|
devtools: boolean
|
||||||
performance: boolean
|
performance: boolean
|
||||||
readonly isNativeTag?: (tag: string) => boolean
|
readonly isNativeTag?: (tag: string) => boolean
|
||||||
|
isCustomElement?: (tag: string) => boolean
|
||||||
errorHandler?: (
|
errorHandler?: (
|
||||||
err: Error,
|
err: Error,
|
||||||
instance: ComponentPublicInstance | null,
|
instance: ComponentPublicInstance | null,
|
||||||
@ -62,6 +63,7 @@ export function createAppContext(): AppContext {
|
|||||||
devtools: true,
|
devtools: true,
|
||||||
performance: false,
|
performance: false,
|
||||||
isNativeTag: NO,
|
isNativeTag: NO,
|
||||||
|
isCustomElement: NO,
|
||||||
errorHandler: undefined,
|
errorHandler: undefined,
|
||||||
warnHandler: undefined
|
warnHandler: undefined
|
||||||
},
|
},
|
||||||
|
@ -350,6 +350,7 @@ function finishComponentSetup(
|
|||||||
if (__RUNTIME_COMPILE__ && Component.template && !Component.render) {
|
if (__RUNTIME_COMPILE__ && Component.template && !Component.render) {
|
||||||
if (compile) {
|
if (compile) {
|
||||||
Component.render = compile(Component.template, {
|
Component.render = compile(Component.template, {
|
||||||
|
isCustomElement: instance.appContext.config.isCustomElement || NO,
|
||||||
onError(err: CompilerError) {
|
onError(err: CompilerError) {
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
const message = `Template compilation error: ${err.message}`
|
const message = `Template compilation error: ${err.message}`
|
||||||
|
@ -29,3 +29,14 @@ it('should correctly normalize class with on-the-fly template compilation', () =
|
|||||||
expect(classes.contains('test')).toBe(true)
|
expect(classes.contains('test')).toBe(true)
|
||||||
expect(classes.contains('test2')).toBe(false)
|
expect(classes.contains('test2')).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should support custom element', () => {
|
||||||
|
const app = createApp()
|
||||||
|
const container = document.createElement('div')
|
||||||
|
const App = {
|
||||||
|
template: '<custom></custom>'
|
||||||
|
}
|
||||||
|
app.config.isCustomElement = tag => tag === 'custom'
|
||||||
|
app.mount(App, container)
|
||||||
|
expect(container.innerHTML).toBe('<custom></custom>')
|
||||||
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user