aboutsummaryrefslogtreecommitdiff
path: root/node_modules/vue/src/platforms/web/util
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/vue/src/platforms/web/util')
-rw-r--r--node_modules/vue/src/platforms/web/util/attrs.js43
-rw-r--r--node_modules/vue/src/platforms/web/util/class.js85
-rw-r--r--node_modules/vue/src/platforms/web/util/compat.js16
-rw-r--r--node_modules/vue/src/platforms/web/util/element.js77
-rw-r--r--node_modules/vue/src/platforms/web/util/index.js25
-rw-r--r--node_modules/vue/src/platforms/web/util/style.js72
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('&#10;') > 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
+}
+