From: 月迷津渡 Date: Tue, 15 Oct 2019 21:30:47 +0000 (+0800) Subject: feat: add isCustomElement option (#299) X-Git-Tag: v3.0.0-alpha.0~416 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f71bf2f1d39bcf6f6d84467f02b20762245319fb;p=thirdparty%2Fvuejs%2Fcore.git feat: add isCustomElement option (#299) --- diff --git a/packages/compiler-core/__tests__/parse.spec.ts b/packages/compiler-core/__tests__/parse.spec.ts index 3e0ccef798..4237b5faf7 100644 --- a/packages/compiler-core/__tests__/parse.spec.ts +++ b/packages/compiler-core/__tests__/parse.spec.ts @@ -616,6 +616,25 @@ describe('compiler: parse', () => { }) }) + test('custom element', () => { + const ast = parse('
', { + 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', () => { const ast = parse('
') const element = ast.children[0] as ElementNode diff --git a/packages/compiler-core/src/parse.ts b/packages/compiler-core/src/parse.ts index 2c39a28c4f..6402981896 100644 --- a/packages/compiler-core/src/parse.ts +++ b/packages/compiler-core/src/parse.ts @@ -32,6 +32,7 @@ import { extend } from '@vue/shared' export interface ParserOptions { isVoidTag?: (tag: string) => boolean // e.g. img, br, hr isNativeTag?: (tag: string) => boolean // e.g. loading-indicator in weex + isCustomElement?: (tag: string) => boolean getNamespace?: (tag: string, parent: ElementNode | undefined) => Namespace getTextMode?: (tag: string, ns: Namespace) => TextModes delimiters?: [string, string] // ['{{', '}}'] @@ -54,6 +55,7 @@ export const defaultParserOptions: MergedParserOptions = { getNamespace: () => Namespaces.HTML, getTextMode: () => TextModes.DATA, isVoidTag: NO, + isCustomElement: NO, namedCharacterReferences: { 'gt;': '>', 'lt;': '<', @@ -433,7 +435,7 @@ function parseTag( } let tagType = ElementTypes.ELEMENT - if (!context.inPre) { + if (!context.inPre && !context.options.isCustomElement(tag)) { if (context.options.isNativeTag) { if (!context.options.isNativeTag(tag)) tagType = ElementTypes.COMPONENT } else { diff --git a/packages/runtime-core/src/apiApp.ts b/packages/runtime-core/src/apiApp.ts index d7f393bc8d..31d61047aa 100644 --- a/packages/runtime-core/src/apiApp.ts +++ b/packages/runtime-core/src/apiApp.ts @@ -28,6 +28,7 @@ export interface AppConfig { devtools: boolean performance: boolean readonly isNativeTag?: (tag: string) => boolean + isCustomElement?: (tag: string) => boolean errorHandler?: ( err: Error, instance: ComponentPublicInstance | null, @@ -62,6 +63,7 @@ export function createAppContext(): AppContext { devtools: true, performance: false, isNativeTag: NO, + isCustomElement: NO, errorHandler: undefined, warnHandler: undefined }, diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index 72c3fdac3f..20328af9e2 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -350,6 +350,7 @@ function finishComponentSetup( if (__RUNTIME_COMPILE__ && Component.template && !Component.render) { if (compile) { Component.render = compile(Component.template, { + isCustomElement: instance.appContext.config.isCustomElement || NO, onError(err: CompilerError) { if (__DEV__) { const message = `Template compilation error: ${err.message}` diff --git a/packages/vue/__tests__/index.spec.ts b/packages/vue/__tests__/index.spec.ts index 754b717a69..d121360dbc 100644 --- a/packages/vue/__tests__/index.spec.ts +++ b/packages/vue/__tests__/index.spec.ts @@ -29,3 +29,14 @@ it('should correctly normalize class with on-the-fly template compilation', () = expect(classes.contains('test')).toBe(true) expect(classes.contains('test2')).toBe(false) }) + +it('should support custom element', () => { + const app = createApp() + const container = document.createElement('div') + const App = { + template: '' + } + app.config.isCustomElement = tag => tag === 'custom' + app.mount(App, container) + expect(container.innerHTML).toBe('') +})