diff options
Diffstat (limited to 'node_modules/vue/src/platforms/web/util')
| -rw-r--r-- | node_modules/vue/src/platforms/web/util/attrs.js | 43 | ||||
| -rw-r--r-- | node_modules/vue/src/platforms/web/util/class.js | 85 | ||||
| -rw-r--r-- | node_modules/vue/src/platforms/web/util/compat.js | 16 | ||||
| -rw-r--r-- | node_modules/vue/src/platforms/web/util/element.js | 77 | ||||
| -rw-r--r-- | node_modules/vue/src/platforms/web/util/index.js | 25 | ||||
| -rw-r--r-- | node_modules/vue/src/platforms/web/util/style.js | 72 |
6 files changed, 318 insertions, 0 deletions
diff --git a/node_modules/vue/src/platforms/web/util/attrs.js b/node_modules/vue/src/platforms/web/util/attrs.js new file mode 100644 index 00000000..59517da9 --- /dev/null +++ b/node_modules/vue/src/platforms/web/util/attrs.js @@ -0,0 +1,43 @@ +/* @flow */ + +import { makeMap } from 'shared/util' + +// these are reserved for web because they are directly compiled away +// during template compilation +export const isReservedAttr = makeMap('style,class') + +// attributes that should be using props for binding +const acceptValue = makeMap('input,textarea,option,select,progress') +export const mustUseProp = (tag: string, type: ?string, attr: string): boolean => { + return ( + (attr === 'value' && acceptValue(tag)) && type !== 'button' || + (attr === 'selected' && tag === 'option') || + (attr === 'checked' && tag === 'input') || + (attr === 'muted' && tag === 'video') + ) +} + +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,' + + 'enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,' + + 'muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,' + + 'required,reversed,scoped,seamless,selected,sortable,translate,' + + 'truespeed,typemustmatch,visible' +) + +export const xlinkNS = 'http://www.w3.org/1999/xlink' + +export const isXlink = (name: string): boolean => { + return name.charAt(5) === ':' && name.slice(0, 5) === 'xlink' +} + +export const getXlinkProp = (name: string): string => { + return isXlink(name) ? name.slice(6, name.length) : '' +} + +export const isFalsyAttrValue = (val: any): boolean => { + return val == null || val === false +} diff --git a/node_modules/vue/src/platforms/web/util/class.js b/node_modules/vue/src/platforms/web/util/class.js new file mode 100644 index 00000000..542dcbc4 --- /dev/null +++ b/node_modules/vue/src/platforms/web/util/class.js @@ -0,0 +1,85 @@ +/* @flow */ + +import { isDef, isObject } from 'shared/util' + +export function genClassForVnode (vnode: VNodeWithData): string { + let data = vnode.data + let parentNode = vnode + let childNode = vnode + while (isDef(childNode.componentInstance)) { + childNode = childNode.componentInstance._vnode + if (childNode && childNode.data) { + data = mergeClassData(childNode.data, data) + } + } + while (isDef(parentNode = parentNode.parent)) { + if (parentNode && parentNode.data) { + data = mergeClassData(data, parentNode.data) + } + } + return renderClass(data.staticClass, data.class) +} + +function mergeClassData (child: VNodeData, parent: VNodeData): { + staticClass: string, + class: any +} { + return { + staticClass: concat(child.staticClass, parent.staticClass), + class: isDef(child.class) + ? [child.class, parent.class] + : parent.class + } +} + +export function renderClass ( + staticClass: ?string, + dynamicClass: any +): string { + if (isDef(staticClass) || isDef(dynamicClass)) { + return concat(staticClass, stringifyClass(dynamicClass)) + } + /* istanbul ignore next */ + return '' +} + +export function concat (a: ?string, b: ?string): string { + return a ? b ? (a + ' ' + b) : a : (b || '') +} + +export function stringifyClass (value: any): string { + if (Array.isArray(value)) { + return stringifyArray(value) + } + if (isObject(value)) { + return stringifyObject(value) + } + if (typeof value === 'string') { + return value + } + /* istanbul ignore next */ + return '' +} + +function stringifyArray (value: Array<any>): string { + let res = '' + let stringified + for (let i = 0, l = value.length; i < l; i++) { + if (isDef(stringified = stringifyClass(value[i])) && stringified !== '') { + if (res) res += ' ' + res += stringified + } + } + return res +} + +function stringifyObject (value: Object): string { + let res = '' + for (const key in value) { + if (value[key]) { + if (res) res += ' ' + res += key + } + } + return res +} diff --git a/node_modules/vue/src/platforms/web/util/compat.js b/node_modules/vue/src/platforms/web/util/compat.js new file mode 100644 index 00000000..d95759cc --- /dev/null +++ b/node_modules/vue/src/platforms/web/util/compat.js @@ -0,0 +1,16 @@ +/* @flow */ + +import { inBrowser } from 'core/util/index' + +// check whether current browser encodes a char inside attribute values +let div +function getShouldDecode (href: boolean): boolean { + div = div || document.createElement('div') + div.innerHTML = href ? `<a href="\n"/>` : `<div a="\n"/>` + return div.innerHTML.indexOf(' ') > 0 +} + +// #3663: IE encodes newlines inside attribute values while other browsers don't +export const shouldDecodeNewlines = inBrowser ? getShouldDecode(false) : false +// #6828: chrome encodes content in a[href] +export const shouldDecodeNewlinesForHref = inBrowser ? getShouldDecode(true) : false diff --git a/node_modules/vue/src/platforms/web/util/element.js b/node_modules/vue/src/platforms/web/util/element.js new file mode 100644 index 00000000..65f1aafb --- /dev/null +++ b/node_modules/vue/src/platforms/web/util/element.js @@ -0,0 +1,77 @@ +/* @flow */ + +import { inBrowser } from 'core/util/env' +import { makeMap } from 'shared/util' + +export const namespaceMap = { + svg: 'http://www.w3.org/2000/svg', + math: 'http://www.w3.org/1998/Math/MathML' +} + +export const isHTMLTag = makeMap( + 'html,body,base,head,link,meta,style,title,' + + 'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' + + 'div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,' + + 'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' + + 's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' + + 'embed,object,param,source,canvas,script,noscript,del,ins,' + + 'caption,col,colgroup,table,thead,tbody,td,th,tr,' + + 'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' + + 'output,progress,select,textarea,' + + 'details,dialog,menu,menuitem,summary,' + + 'content,element,shadow,template,blockquote,iframe,tfoot' +) + +// this map is intentionally selective, only covering SVG elements that may +// contain child elements. +export const isSVG = makeMap( + 'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,' + + 'foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' + + 'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view', + true +) + +export const isPreTag = (tag: ?string): boolean => tag === 'pre' + +export const isReservedTag = (tag: string): ?boolean => { + return isHTMLTag(tag) || isSVG(tag) +} + +export function getTagNamespace (tag: string): ?string { + if (isSVG(tag)) { + return 'svg' + } + // basic support for MathML + // note it doesn't support other MathML elements being component roots + if (tag === 'math') { + return 'math' + } +} + +const unknownElementCache = Object.create(null) +export function isUnknownElement (tag: string): boolean { + /* istanbul ignore if */ + if (!inBrowser) { + return true + } + if (isReservedTag(tag)) { + return false + } + tag = tag.toLowerCase() + /* istanbul ignore if */ + if (unknownElementCache[tag] != null) { + return unknownElementCache[tag] + } + const el = document.createElement(tag) + if (tag.indexOf('-') > -1) { + // http://stackoverflow.com/a/28210364/1070244 + return (unknownElementCache[tag] = ( + el.constructor === window.HTMLUnknownElement || + el.constructor === window.HTMLElement + )) + } else { + return (unknownElementCache[tag] = /HTMLUnknownElement/.test(el.toString())) + } +} + +export const isTextInputType = makeMap('text,number,password,search,email,tel,url') diff --git a/node_modules/vue/src/platforms/web/util/index.js b/node_modules/vue/src/platforms/web/util/index.js new file mode 100644 index 00000000..da5e46ed --- /dev/null +++ b/node_modules/vue/src/platforms/web/util/index.js @@ -0,0 +1,25 @@ +/* @flow */ + +import { warn } from 'core/util/index' + +export * from './attrs' +export * from './class' +export * from './element' + +/** + * Query an element selector if it's not an element already. + */ +export function query (el: string | Element): Element { + if (typeof el === 'string') { + const selected = document.querySelector(el) + if (!selected) { + process.env.NODE_ENV !== 'production' && warn( + 'Cannot find element: ' + el + ) + return document.createElement('div') + } + return selected + } else { + return el + } +} diff --git a/node_modules/vue/src/platforms/web/util/style.js b/node_modules/vue/src/platforms/web/util/style.js new file mode 100644 index 00000000..fc119043 --- /dev/null +++ b/node_modules/vue/src/platforms/web/util/style.js @@ -0,0 +1,72 @@ +/* @flow */ + +import { cached, extend, toObject } from 'shared/util' + +export const parseStyleText = cached(function (cssText) { + const res = {} + const listDelimiter = /;(?![^(]*\))/g + const propertyDelimiter = /:(.+)/ + cssText.split(listDelimiter).forEach(function (item) { + if (item) { + var tmp = item.split(propertyDelimiter) + tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim()) + } + }) + return res +}) + +// merge static and dynamic style data on the same vnode +function normalizeStyleData (data: VNodeData): ?Object { + const style = normalizeStyleBinding(data.style) + // static style is pre-processed into an object during compilation + // and is always a fresh object, so it's safe to merge into it + return data.staticStyle + ? extend(data.staticStyle, style) + : style +} + +// normalize possible array / string values into Object +export function normalizeStyleBinding (bindingStyle: any): ?Object { + if (Array.isArray(bindingStyle)) { + return toObject(bindingStyle) + } + if (typeof bindingStyle === 'string') { + return parseStyleText(bindingStyle) + } + return bindingStyle +} + +/** + * parent component style should be after child's + * so that parent component's style could override it + */ +export function getStyle (vnode: VNodeWithData, checkChild: boolean): Object { + const res = {} + let styleData + + if (checkChild) { + let childNode = vnode + while (childNode.componentInstance) { + childNode = childNode.componentInstance._vnode + if ( + childNode && childNode.data && + (styleData = normalizeStyleData(childNode.data)) + ) { + extend(res, styleData) + } + } + } + + if ((styleData = normalizeStyleData(vnode.data))) { + extend(res, styleData) + } + + let parentNode = vnode + while ((parentNode = parentNode.parent)) { + if (parentNode.data && (styleData = normalizeStyleData(parentNode.data))) { + extend(res, styleData) + } + } + return res +} + |
