diff --git a/flow/compiler.js b/flow/compiler.js index 18ed2855f1d..dc0db1d7800 100644 --- a/flow/compiler.js +++ b/flow/compiler.js @@ -5,6 +5,7 @@ declare type CompilerOptions = { staticKeys?: string; // a list of AST properties to be considered static; for optimization directives?: { [key: string]: Function }; // platform specific directives isUnaryTag?: (tag: string) => ?boolean; // check if a tag is unary for the platform + canBeLeftOpenTag?: (tag: string) => ?boolean; // check if a tag can be left opened isReservedTag?: (tag: string) => ?boolean; // check if a tag is a native for the platform mustUseProp?: (tag: string, type: ?string, name: string) => boolean; // check if an attribute should be bound as a property isPreTag?: (attr: string) => ?boolean; // check if a tag needs to preserve whitespace diff --git a/src/compiler/parser/html-parser.js b/src/compiler/parser/html-parser.js index 7d444ece141..79c380e6c6a 100644 --- a/src/compiler/parser/html-parser.js +++ b/src/compiler/parser/html-parser.js @@ -10,7 +10,7 @@ */ import { makeMap, no } from 'shared/util' -import { isNonPhrasingTag, canBeLeftOpenTag } from 'web/compiler/util' +import { isNonPhrasingTag } from 'web/compiler/util' // Regular Expressions for parsing tags and attributes const singleAttrIdentifier = /([^\s"'<>/=]+)/ @@ -68,6 +68,7 @@ export function parseHTML (html, options) { const stack = [] const expectHTML = options.expectHTML const isUnaryTag = options.isUnaryTag || no + const canBeLeftOpenTag = options.canBeLeftOpenTag || no let index = 0 let last, lastTag while (html) { diff --git a/src/compiler/parser/index.js b/src/compiler/parser/index.js index a10658a7fc5..36e253dab4a 100644 --- a/src/compiler/parser/index.js +++ b/src/compiler/parser/index.js @@ -75,6 +75,7 @@ export function parse ( warn, expectHTML: options.expectHTML, isUnaryTag: options.isUnaryTag, + canBeLeftOpenTag: options.canBeLeftOpenTag, shouldDecodeNewlines: options.shouldDecodeNewlines, start (tag, attrs, unary) { // check namespace. diff --git a/src/entries/web-server-renderer.js b/src/entries/web-server-renderer.js index 8bd327a6c25..3a11844ba9e 100644 --- a/src/entries/web-server-renderer.js +++ b/src/entries/web-server-renderer.js @@ -4,7 +4,7 @@ process.env.VUE_ENV = 'server' import { createRenderer as _createRenderer } from 'server/create-renderer' import { createBundleRendererCreator } from 'server/create-bundle-renderer' -import { isUnaryTag } from 'web/compiler/util' +import { isUnaryTag, canBeLeftOpenTag } from 'web/compiler/util' import modules from 'web/server/modules/index' import baseDirectives from 'web/server/directives/index' @@ -14,6 +14,7 @@ export function createRenderer (options?: Object = {}): { } { return _createRenderer({ isUnaryTag, + canBeLeftOpenTag, modules, // user can provide server-side implementations for custom directives // when creating the renderer. diff --git a/src/platforms/web/compiler/index.js b/src/platforms/web/compiler/index.js index 63f312115f9..bafccbc6547 100644 --- a/src/platforms/web/compiler/index.js +++ b/src/platforms/web/compiler/index.js @@ -1,6 +1,6 @@ /* @flow */ -import { isUnaryTag } from './util' +import { isUnaryTag, canBeLeftOpenTag } from './util' import { genStaticKeys } from 'shared/util' import { createCompiler } from 'compiler/index' @@ -21,6 +21,7 @@ export const baseOptions: CompilerOptions = { isPreTag, isUnaryTag, mustUseProp, + canBeLeftOpenTag, isReservedTag, getTagNamespace, staticKeys: genStaticKeys(modules) diff --git a/src/platforms/weex/compiler/index.js b/src/platforms/weex/compiler/index.js index 12068cd8fd6..cbbc6381c71 100644 --- a/src/platforms/weex/compiler/index.js +++ b/src/platforms/weex/compiler/index.js @@ -10,6 +10,7 @@ import { isUnaryTag, mustUseProp, isReservedTag, + canBeLeftOpenTag, getTagNamespace } from '../util/index' @@ -18,6 +19,7 @@ export const baseOptions: CompilerOptions = { directives, isUnaryTag, mustUseProp, + canBeLeftOpenTag, isReservedTag, getTagNamespace, preserveWhitespace: false, diff --git a/src/platforms/weex/util/index.js b/src/platforms/weex/util/index.js index bddfa640013..19bbe75752a 100755 --- a/src/platforms/weex/util/index.js +++ b/src/platforms/weex/util/index.js @@ -3,10 +3,27 @@ import { makeMap } from 'shared/util' export const isReservedTag = makeMap( - 'div,img,image,input,switch,indicator,list,scroller,cell,template,text,slider,image' + 'template,script,style,element,content,slot,link,meta,svg,view,' + + 'a,div,img,image,text,span,richtext,input,switch,textarea,spinner,select,' + + 'slider,slider-neighbor,indicator,trisition,trisition-group,canvas,' + + 'list,cell,header,loading,loading-indicator,refresh,scrollable,scroller,' + + 'video,web,embed,tabbar,tabheader,datepicker,timepicker,marquee,countdown', + true +) + +// Elements that you can, intentionally, leave open (and which close themselves) +// more flexable than web +export const canBeLeftOpenTag = makeMap( + 'web,spinner,switch,video,textarea,canvas,' + + 'indicator,marquee,countdown', + true +) + +export const isUnaryTag = makeMap( + 'embed,img,image,input,link,meta', + true ) -export function isUnaryTag () { /* console.log('isUnaryTag') */ } export function mustUseProp () { /* console.log('mustUseProp') */ } export function getTagNamespace () { /* console.log('getTagNamespace') */ } export function isUnknownElement () { /* console.log('isUnknownElement') */ } diff --git a/test/weex/compiler/compile.spec.js b/test/weex/compiler/compile.spec.js index c0d796f1e13..7a717f19146 100644 --- a/test/weex/compiler/compile.spec.js +++ b/test/weex/compiler/compile.spec.js @@ -1,4 +1,5 @@ import { compile } from '../../../packages/weex-template-compiler' +import { strToRegExp } from '../helpers/index' describe('compile basic', () => { it('should be compiled', () => { @@ -29,6 +30,36 @@ describe('compile basic', () => { expect(errors).toEqual([]) }) + it('should compile unary tag', () => { + const inputCase = compile(`
abc
`) + expect(inputCase.render).toMatch(strToRegExp(`return _m(0)`)) + expect(inputCase.staticRenderFns).toMatch(strToRegExp(`_c('div',[_c('input'),_c('text',[_v("abc")])])`)) + expect(inputCase.errors).toEqual([]) + + const imageCase = compile(`
abc
`) + expect(imageCase.render).toMatch(strToRegExp(`return _m(0)`)) + expect(imageCase.staticRenderFns).toMatch(strToRegExp(`_c('div',[_c('image',{attrs:{"src":"path"}}),_c('text',[_v("abc")])])`)) + expect(imageCase.errors).toEqual([]) + + const complexCase = compile(` +
+ + +
+ + start + + + end +
+
+ `) + expect(complexCase.render).toMatch(strToRegExp(`return _m(0)`)) + expect(complexCase.staticRenderFns).toMatch(strToRegExp(`_c('image',{attrs:{"src":"path"}}),_c('image'),_c('div'`)) + expect(complexCase.staticRenderFns).toMatch(strToRegExp(`_c('div',[_c('embed'),_c('text',[_v("start")]),_c('input',{attrs:{"type":"text"}}),_c('input',{attrs:{"type":"url"}}),_c('text',[_v("end")])]`)) + expect(complexCase.errors).toEqual([]) + }) + it('should compile more complex situation', () => { // from examples of https://github.com/alibaba/weex const { render, staticRenderFns, errors } = compile(` @@ -38,7 +69,7 @@ describe('compile basic', () => { Load more... `) - expect(render).toEqual(`with(this){return _c('refresh',{staticClass:["refresh"],staticStyle:{flexDirection:"row"},attrs:{"display":displayRefresh},on:{"refresh":handleRefresh}},[_c('loading-indicator'),_c('text',{staticStyle:{marginLeft:"36px",color:"#eee"}},[_v("Load more...")])],1)}`) + expect(render).toEqual(`with(this){return _c('refresh',{staticClass:["refresh"],staticStyle:{flexDirection:"row"},attrs:{"display":displayRefresh},on:{"refresh":handleRefresh}},[_c('loading-indicator'),_c('text',{staticStyle:{marginLeft:"36px",color:"#eee"}},[_v("Load more...")])])}`) expect(staticRenderFns).toEqual([]) expect(errors).toEqual([]) })