瀏覽代碼

move web-specific utils

Evan You 10 年之前
父節點
當前提交
14feb83879

+ 3 - 0
build/build.js

@@ -107,6 +107,9 @@ function buildEntry (opts) {
         fromString: true,
         output: {
           ascii_only: true
+        },
+        compress: {
+          pure_funcs: ['makeMap']
         }
       }).code
       return write(opts.out, minified).then(zip(opts.out))

+ 10 - 30
src/compiler/parser/html-parser.js

@@ -7,6 +7,7 @@
 
 import { decodeHTML } from 'entities'
 import { makeMap } from 'shared/util'
+import { isNonPhrasingTag, canBeLeftOpenTag } from 'web/util/index'
 
 // Regular Expressions for parsing tags and attributes
 const singleAttrIdentifier = /([^\s"'<>\/=]+)/
@@ -34,26 +35,9 @@ let IS_REGEX_CAPTURING_BROKEN = false
   IS_REGEX_CAPTURING_BROKEN = g === ''
 })
 
-// Empty Elements
-const empty = makeMap('area,base,basefont,br,col,embed,frame,hr,img,input,isindex,keygen,link,meta,param,source,track,wbr', true)
-
-// Inline Elements
-const inline = makeMap('a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,noscript,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,svg,textarea,tt,u,var', true)
-
-// Elements that you can, intentionally, leave open
-// (and which close themselves)
-const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source', true)
-
-// Attributes that have their values filled in disabled='disabled'
-const fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected', true)
-
 // Special Elements (can contain anything)
 const special = makeMap('script,style', true)
 
-// HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3
-// Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content
-const nonPhrasing = makeMap('address,article,aside,base,blockquote,body,caption,col,colgroup,dd,details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,title,tr,track', true)
-
 const reCache = {}
 
 function attrForHandler (handler) {
@@ -72,6 +56,8 @@ function joinSingleAttrAssigns (handler) {
 export function parseHTML (html, handler) {
   const stack = []
   const attribute = attrForHandler(handler)
+  const expectHTML = handler.expectHTML
+  const isUnaryTag = handler.isUnaryTag || (() => false)
   let last, prevTag, nextTag, lastTag
   while (html) {
     last = html
@@ -211,21 +197,16 @@ export function parseHTML (html, handler) {
     var tagName = match.tagName
     var unarySlash = match.unarySlash
 
-    if (handler.html5 && lastTag === 'p' && nonPhrasing(tagName)) {
-      parseEndTag('', lastTag)
-    }
-
-    if (!handler.html5) {
-      while (lastTag && inline(lastTag)) {
+    if (expectHTML) {
+      if (lastTag === 'p' && isNonPhrasingTag(tagName)) {
         parseEndTag('', lastTag)
       }
+      if (canBeLeftOpenTag(tagName) && lastTag === tagName) {
+        parseEndTag('', tagName)
+      }
     }
 
-    if (closeSelf(tagName) && lastTag === tagName) {
-      parseEndTag('', tagName)
-    }
-
-    var unary = empty(tagName) || tagName === 'html' && lastTag === 'head' || !!unarySlash
+    var unary = isUnaryTag(tagName) || tagName === 'html' && lastTag === 'head' || !!unarySlash
 
     var attrs = match.attrs.map(function (args) {
       // hackish work around FF bug https://bugzilla.mozilla.org/show_bug.cgi?id=369778
@@ -234,10 +215,9 @@ export function parseHTML (html, handler) {
         if (args[4] === '') { delete args[4] }
         if (args[5] === '') { delete args[5] }
       }
-      var value = args[3] || args[4] || (args[5] && fillAttrs(args[5]) ? args[1] : '')
       return {
         name: args[1],
-        value: decodeHTML(value)
+        value: decodeHTML(args[3] || args[4] || args[5] || '')
       }
     })
 

+ 2 - 2
src/compiler/parser/index.js

@@ -49,8 +49,8 @@ export function parse (template, options) {
   let inPre = false
   let warned = false
   parseHTML(template, {
-    html5: true,
-
+    expectHTML: options.expectHTML,
+    isUnaryTag: options.isUnaryTag,
     start (tag, attrs, unary) {
       // check camelCase tag
       if (camelRE.test(tag)) {

+ 3 - 1
src/entries/web-compiler.js

@@ -1,14 +1,16 @@
 import { extend } from 'shared/util'
 import { compile as baseCompile } from 'compiler/index'
 import directives from 'web/compiler/directives/index'
-import { isReservedTag, mustUseProp, getTagNamespace } from 'web/util/index'
+import { isReservedTag, isUnaryTag, mustUseProp, getTagNamespace } from 'web/util/index'
 
 const cache1 = Object.create(null)
 const cache2 = Object.create(null)
 
 const baseOptions = {
+  expectHTML: true,
   directives,
   isReservedTag,
+  isUnaryTag,
   mustUseProp,
   getTagNamespace
 }

+ 4 - 0
src/platforms/web/util/attrs.js

@@ -1,6 +1,10 @@
 import { makeMap } from 'shared/util'
 
+// attributes that should be using props for binding
+export const mustUseProp = makeMap('value,selected,checked,muted')
+
 export const isEnumeratedAttr = makeMap('contenteditable,draggable,spellcheck')
+
 export const isBooleanAttr = makeMap(
   'allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,' +
   'default,defaultchecked,defaultmuted,defaultselected,defer,disabled,' +

+ 23 - 2
src/platforms/web/util/element.js

@@ -20,8 +20,29 @@ export const isReservedTag = makeMap(
   'content,element,shadow,template'
 )
 
-// attributes that should be using props for binding
-export const mustUseProp = makeMap('value,selected,checked,muted')
+export const isUnaryTag = makeMap(
+  'area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' +
+  'link,meta,param,source,track,wbr',
+  true
+)
+
+// Elements that you can, intentionally, leave open
+// (and which close themselves)
+export const canBeLeftOpenTag = makeMap(
+  'colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source',
+  true
+)
+
+// HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3
+// Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content
+export const isNonPhrasingTag = makeMap(
+  'address,article,aside,base,blockquote,body,caption,col,colgroup,dd,' +
+  'details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,' +
+  'h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,' +
+  'optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,' +
+  'title,tr,track',
+  true
+)
 
 // this map covers namespace elements that can appear as template root nodes
 const isSVG = makeMap(

+ 4 - 3
src/shared/util.js

@@ -9,9 +9,10 @@
 
 export function makeMap (str, expectsLowerCase) {
   const map = Object.create(null)
-  str.split(',').forEach(key => {
-    map[key] = true
-  })
+  const list = str.split(',')
+  for (let i = 0; i < list.length; i++) {
+    map[list[i]] = true
+  }
   return expectsLowerCase
     ? val => map[val.toLowerCase()]
     : val => map[val]