Browse Source

annotate platforms/web

dev
Evan You 9 years ago
parent
commit
750bec1024
  1. 14
      flow/compiler.js
  2. 18
      flow/vnode.js
  3. 2
      src/compiler/directives/ref.js
  4. 9
      src/core/vdom/patch.js
  5. 9
      src/entries/web-runtime-with-compiler.js
  6. 4
      src/platforms/web/compiler/directives/html.js
  7. 4
      src/platforms/web/compiler/directives/model.js
  8. 4
      src/platforms/web/compiler/directives/text.js
  9. 22
      src/platforms/web/runtime/class-util.js
  10. 5
      src/platforms/web/runtime/directives/model.js
  11. 8
      src/platforms/web/runtime/directives/show.js
  12. 9
      src/platforms/web/runtime/modules/attrs.js
  13. 6
      src/platforms/web/runtime/modules/class.js
  14. 4
      src/platforms/web/runtime/modules/events.js
  15. 6
      src/platforms/web/runtime/modules/props.js
  16. 24
      src/platforms/web/runtime/modules/style.js
  17. 75
      src/platforms/web/runtime/modules/transition.js
  18. 26
      src/platforms/web/runtime/node-ops.js
  19. 7
      src/platforms/web/server/directives/show.js
  20. 6
      src/platforms/web/server/modules/attrs.js
  21. 4
      src/platforms/web/server/modules/class.js
  22. 17
      src/platforms/web/server/modules/style.js
  23. 17
      src/platforms/web/util/attrs.js
  24. 26
      src/platforms/web/util/class.js
  25. 6
      src/platforms/web/util/element.js
  26. 8
      src/platforms/web/util/index.js
  27. 15
      src/shared/util.js

14
flow/compiler.js

@ -20,6 +20,13 @@ declare type ASTElementHandlers = {
declare type ASTElementHooks = { [key: string]: Array<string> }
declare type ASTDirective = {
name: string,
value: ?string,
arg: ?string,
modifiers: ?{ [key: string]: true }
}
declare type ASTText = {
text?: string,
expression?: string
@ -70,12 +77,7 @@ declare type ASTElement = {
transition?: string | true,
transitionOnAppear?: boolean,
directives?: Array<{
name: string,
value: ?string,
arg: ?string,
modifiers: ?{ [key: string]: true }
}>,
directives?: Array<ASTDirective>,
forbidden?: true,
once?: true

18
flow/vnode.js

@ -11,6 +11,7 @@ declare type VNodeComponentOptions = {
declare interface MountedComponentVNode {
componentOptions: VNodeComponentOptions;
child: Component;
parent: VNode;
}
// interface for vnodes in update modules
@ -19,10 +20,11 @@ declare interface VNodeWithData {
data: VNodeData;
children: Array<VNode> | void;
text: void;
elm: Node;
elm: HTMLElement;
ns: string | void;
context: Component;
key: string | number | void;
parent?: VNodeWithData;
}
declare interface VNodeData {
@ -46,10 +48,12 @@ declare interface VNodeData {
render: Function,
staticRenderFns: Array<Function>
};
directives?: Array<{
name: string,
value?: any,
arg?: string,
modifiers?: { [key: string]: boolean }
}>;
directives?: Array<VNodeDirective>;
}
declare type VNodeDirective = {
name: string,
value?: any,
arg?: string,
modifiers?: { [key: string]: boolean }
}

2
src/compiler/directives/ref.js

@ -2,7 +2,7 @@
import { addHook } from '../helpers'
export function ref (el: ASTElement, dir: { arg: string }) {
export function ref (el: ASTElement, dir: ASTDirective) {
// go up and check if this node is inside a v-for
let isFor = false
let parent = el

9
src/core/vdom/patch.js

@ -310,7 +310,7 @@ export function createPatchFunction (backend) {
}
if (isDef(tag)) {
if (isDef(children)) {
const childNodes = elm.childNodes
const childNodes = nodeOps.childNodes(elm)
for (let i = 0; i < children.length; i++) {
const success = hydrate(childNodes[i], children[i], insertedVnodeQueue)
if (!success) {
@ -330,10 +330,11 @@ export function createPatchFunction (backend) {
if (vnode.tag.indexOf('vue-component') === 0) {
return true
} else {
return vnode.tag === node.tagName.toLowerCase() && (
const childNodes = nodeOps.childNodes(node)
return vnode.tag === nodeOps.tagName(node).toLowerCase() && (
vnode.children
? vnode.children.length === node.childNodes.length
: node.childNodes.length === 0
? vnode.children.length === childNodes.length
: childNodes.length === 0
)
}
} else {

9
src/entries/web-runtime-with-compiler.js

@ -6,10 +6,13 @@ import { warn, cached } from 'core/util/index'
import { query } from 'web/util/index'
import { compileToFunctions } from './web-compiler'
const idToTemplate = cached(id => query(id).innerHTML)
const mount = Vue.prototype.$mount
const idToTemplate = cached(id => {
const el = query(id)
return el && el.innerHTML
})
Vue.prototype.$mount = function (el?: string | Element): Vue {
const mount = Vue.prototype.$mount
Vue.prototype.$mount = function (el: string | Element): Component {
el = el && query(el)
const options = this.$options
// resolve template/el and convert to render function

4
src/platforms/web/compiler/directives/html.js

@ -1,6 +1,8 @@
/* @flow */
import { addProp } from 'compiler/helpers'
export default function html (el, dir) {
export default function html (el: ASTElement, dir: ASTDirective) {
if (!dir.value) return
addProp(el, 'innerHTML', `__toString__(${dir.value})`)
}

4
src/platforms/web/compiler/directives/model.js

@ -1,6 +1,8 @@
/* @flow */
import { addHandler, addProp, getBindingAttr } from 'compiler/helpers'
export default function model (el, dir) {
export default function model (el: ASTElement, dir: ASTDirective) {
const value = dir.value
const modifiers = dir.modifiers
if (el.tag === 'select') {

4
src/platforms/web/compiler/directives/text.js

@ -1,6 +1,8 @@
/* @flow */
import { addProp } from 'compiler/helpers'
export default function text (el, dir) {
export default function text (el: ASTElement, dir: ASTDirective) {
if (!dir.value) return
addProp(el, 'textContent', `__toString__(${dir.value})`)
}

22
src/platforms/web/runtime/class-util.js

@ -1,3 +1,5 @@
/* @flow */
import { isIE9, namespaceMap } from 'web/util/index'
const svgNS = namespaceMap.svg
@ -7,11 +9,8 @@ const svgNS = namespaceMap.svg
* if the element also has the :class attribute; However in
* PhantomJS, setting `className` does not work on SVG elements...
* So we have to do a conditional check here.
*
* @param {Element} el
* @param {String} cls
*/
export function setClass (el, cls) {
export function setClass (el: Element, cls: string) {
/* istanbul ignore else */
if (!isIE9 || el.namespaceURI === svgNS) {
el.setAttribute('class', cls)
@ -22,11 +21,8 @@ export function setClass (el, cls) {
/**
* Add class with compatibility for IE & SVG
*
* @param {Element} el
* @param {String} cls
*/
export function addClass (el, cls) {
export function addClass (el: Element, cls: string) {
if (el.classList) {
if (cls.indexOf(' ') > -1) {
cls.split(/\s+/).forEach(c => el.classList.add(c))
@ -43,11 +39,8 @@ export function addClass (el, cls) {
/**
* Remove class with compatibility for IE & SVG
*
* @param {Element} el
* @param {String} cls
*/
export function removeClass (el, cls) {
export function removeClass (el: Element, cls: string) {
if (el.classList) {
if (cls.indexOf(' ') > -1) {
cls.split(/\s+/).forEach(c => el.classList.remove(c))
@ -71,11 +64,8 @@ export function removeClass (el, cls) {
* For IE9 compat: when both class and :class are present
* getAttribute('class') returns wrong value... but className
* on SVG elements returns an object.
*
* @param {Element} el
* @return {String}
*/
function getClass (el) {
function getClass (el: Element): string {
let classname = el.className
if (typeof classname === 'object') {
classname = classname.baseVal || ''

5
src/platforms/web/runtime/directives/model.js

@ -1,3 +1,8 @@
/**
* Not type checking this file because flow doesn't like attaching
* properties to Elements.
*/
import { isAndroid, isIE9 } from 'web/util/index'
if (isIE9) {

8
src/platforms/web/runtime/directives/show.js

@ -1,15 +1,17 @@
/* @flow */
import { isIE9 } from 'web/util/index'
import { enter, leave } from '../modules/transition'
export default {
bind (el, value, _, vnode) {
bind (el: HTMLElement, value: any, _: any, vnode: VNodeWithData) {
const transition = getTransition(vnode)
if (value && transition && transition.appea && !isIE9) {
enter(vnode)
}
el.style.display = value ? '' : 'none'
},
update (el, value, _, vnode) {
update (el: HTMLElement, value: any, _: any, vnode: VNodeWithData) {
const transition = getTransition(vnode)
if (transition && !isIE9) {
if (value) {
@ -26,7 +28,7 @@ export default {
}
}
function getTransition (vnode) {
function getTransition (vnode: VNodeWithData): Object | string | void {
const parent = vnode.parent
return parent && parent.data.transition != null
? parent.data.transition

9
src/platforms/web/runtime/modules/attrs.js

@ -1,3 +1,5 @@
/* @flow */
import {
isBooleanAttr,
isEnumeratedAttr,
@ -7,7 +9,7 @@ import {
isFalsyAttrValue
} from 'web/util/index'
function updateAttrs (oldVnode, vnode) {
function updateAttrs (oldVnode: VNodeWithData, vnode: VNodeWithData) {
if (!oldVnode.data.attrs && !vnode.data.attrs) {
return
}
@ -34,7 +36,7 @@ function updateAttrs (oldVnode, vnode) {
}
}
function setAttr (el, key, value) {
function setAttr (el: Element, key: string, value: any) {
if (isBooleanAttr(key)) {
// set attribute for blank value
// e.g. <option disabled>Select one</option>
@ -61,11 +63,10 @@ function setAttr (el, key, value) {
}
export default {
create: function (_, vnode) {
create: function (_: any, vnode: VNodeWithData) {
const attrs = vnode.data.staticAttrs
if (attrs) {
for (const key in attrs) {
if (!vnode.elm) debugger
setAttr(vnode.elm, key, attrs[key])
}
}

6
src/platforms/web/runtime/modules/class.js

@ -1,9 +1,11 @@
/* @flow */
import { setClass } from '../class-util'
import { genClassForVnode, concat, stringifyClass } from 'web/util/index'
function updateClass (oldVnode, vnode) {
function updateClass (oldVnode: any, vnode: any) {
const el = vnode.elm
const data = vnode.data
const data: VNodeData = vnode.data
if (!data.staticClass && !data.class) {
return
}

4
src/platforms/web/runtime/modules/events.js

@ -1,6 +1,8 @@
/* @flow */
import { updateListeners } from 'core/vdom/helpers'
function updateDOMListeners (oldVnode, vnode) {
function updateDOMListeners (oldVnode: VNodeWithData, vnode: VNodeWithData) {
if (!oldVnode.data.on && !vnode.data.on) {
return
}

6
src/platforms/web/runtime/modules/props.js

@ -1,9 +1,11 @@
function updateProps (oldVnode, vnode) {
/* @flow */
function updateProps (oldVnode: VNodeWithData, vnode: VNodeWithData) {
if (!oldVnode.data.props && !vnode.data.props) {
return
}
let key, cur, old
const elm = vnode.elm
const elm: any = vnode.elm
const oldProps = oldVnode.data.props || {}
const props = vnode.data.props || {}

24
src/platforms/web/runtime/modules/style.js

@ -1,10 +1,12 @@
import { extend, cached, camelize } from 'shared/util'
import { inBrowser } from 'core/util/env'
/* @flow */
import { cached, camelize, toObject } from 'shared/util'
const prefixes = ['Webkit', 'Moz', 'ms']
const testEl = inBrowser && document.createElement('div')
let testEl
const normalize = cached(function (prop) {
testEl = testEl || document.createElement('div')
prop = camelize(prop)
if (prop !== 'filter' && (prop in testEl.style)) {
return prop
@ -18,13 +20,13 @@ const normalize = cached(function (prop) {
}
})
function updateStyle (oldVnode, vnode) {
function updateStyle (oldVnode: VNodeWithData, vnode: VNodeWithData) {
if (!oldVnode.data.style && !vnode.data.style) {
return
}
let cur, name
const elm = vnode.elm
const oldStyle = oldVnode.data.style || {}
const elm: any = vnode.elm
const oldStyle: any = oldVnode.data.style || {}
let style = vnode.data.style || {}
// handle array syntax
@ -45,16 +47,6 @@ function updateStyle (oldVnode, vnode) {
}
}
function toObject (arr) {
const res = arr[0] || {}
for (let i = 1; i < arr.length; i++) {
if (arr[i]) {
extend(res, arr[i])
}
}
return res
}
export default {
create: updateStyle,
update: updateStyle

75
src/platforms/web/runtime/modules/transition.js

@ -1,27 +1,30 @@
/* @flow */
import { addClass, removeClass } from '../class-util'
import { inBrowser, resolveAsset } from 'core/util/index'
import { cached, remove } from 'shared/util'
import { isIE9 } from 'web/util/index'
const hasTransition = inBrowser && !isIE9
const TRANSITION = 'transition'
const ANIMATION = 'animation'
// Transition property/event sniffing
let transitionProp
let transitionEndEvent
let animationProp
let animationEndEvent
if (inBrowser && !isIE9) {
const isWebkitTrans =
window.ontransitionend === undefined &&
window.onwebkittransitionend !== undefined
const isWebkitAnim =
window.onanimationend === undefined &&
window.onwebkitanimationend !== undefined
transitionProp = isWebkitTrans ? 'WebkitTransition' : 'transition'
transitionEndEvent = isWebkitTrans ? 'webkitTransitionEnd' : 'transitionend'
animationProp = isWebkitAnim ? 'WebkitAnimation' : 'animation'
animationEndEvent = isWebkitAnim ? 'webkitAnimationEnd' : 'animationend'
let transitionProp = 'transition'
let transitionEndEvent = 'transitionend'
let animationProp = 'animation'
let animationEndEvent = 'animationend'
if (hasTransition) {
if (window.ontransitionend === undefined &&
window.onwebkittransitionend !== undefined) {
transitionProp = 'WebkitTransition'
transitionEndEvent = 'webkitTransitionEnd'
}
if (window.onanimationend === undefined &&
window.onwebkitanimationend !== undefined) {
animationProp = 'WebkitAnimation'
animationEndEvent = 'webkitAnimationEnd'
}
}
const raf = (inBrowser && window.requestAnimationFrame) || setTimeout
@ -31,8 +34,8 @@ function nextFrame (fn) {
})
}
export function enter (vnode) {
const el = vnode.elm
export function enter (vnode: VNodeWithData) {
const el: any = vnode.elm
// call leave callback now
if (el._leaveCb) {
el._leaveCb.cancelled = true
@ -89,8 +92,8 @@ export function enter (vnode) {
}
}
export function leave (vnode, rm) {
const el = vnode.elm
export function leave (vnode: VNodeWithData, rm: Function) {
const el: any = vnode.elm
// call enter callback now
if (el._enterCb) {
el._enterCb.cancelled = true
@ -145,7 +148,7 @@ export function leave (vnode, rm) {
}
}
function resolveTransition (id, context) {
function resolveTransition (id: string | Object, context: Component): Object {
let definition = id && typeof id === 'string'
? resolveAsset(context.$options, 'transitions', id) || id
: id
@ -155,7 +158,7 @@ function resolveTransition (id, context) {
: definition
}
const autoCssTransition = cached(name => {
const autoCssTransition: (name: string) => Object = cached(name => {
return {
enterClass: `${name}-enter`,
leaveClass: `${name}-leave`,
@ -164,17 +167,17 @@ const autoCssTransition = cached(name => {
}
})
function addTransitionClass (el, cls) {
function addTransitionClass (el: any, cls: string) {
(el._transitionClasses || (el._transitionClasses = [])).push(cls)
addClass(el, cls)
}
function removeTransitionClass (el, cls) {
function removeTransitionClass (el: any, cls: string) {
remove(el._transitionClasses, cls)
removeClass(el, cls)
}
function whenTransitionEnds (el, cb) {
function whenTransitionEnds (el: Element, cb: Function) {
const { type, timeout, propCount } = getTransitionInfo(el)
if (!type) return cb()
const event = type === TRANSITION ? transitionEndEvent : animationEndEvent
@ -196,7 +199,11 @@ function whenTransitionEnds (el, cb) {
el.addEventListener(event, onEnd)
}
function getTransitionInfo (el) {
function getTransitionInfo (el: Element): {
type: ?string,
propCount: number,
timeout: number
} {
const styles = window.getComputedStyle(el)
// 1. determine the maximum duration (timeout)
const transitioneDelays = styles[transitionProp + 'Delay'].split(', ')
@ -223,17 +230,17 @@ function getTransitionInfo (el) {
}
}
function getTimeout (delays, durations) {
function getTimeout (delays: Array<string>, durations: Array<string>): number {
return Math.max.apply(null, durations.map((d, i) => {
return toMs(d) + toMs(delays[i])
}))
}
function toMs (s) {
function toMs (s: string): number {
return Number(s.slice(0, -1)) * 1000
}
function once (fn) {
function once (fn: Function): Function {
let called = false
return () => {
if (!called) {
@ -243,8 +250,8 @@ function once (fn) {
}
}
function shouldSkipTransition (vnode) {
return (
function shouldSkipTransition (vnode: VNodeWithData): boolean {
return !!(
// if this is a component root node and the compoennt's
// parent container node also has transition, skip.
(vnode.parent && vnode.parent.data.transition) ||
@ -254,17 +261,17 @@ function shouldSkipTransition (vnode) {
)
}
export default !transitionEndEvent ? {} : {
create: function (_, vnode) {
export default hasTransition ? {
create: function (_: any, vnode: VNodeWithData) {
if (!shouldSkipTransition(vnode)) {
enter(vnode)
}
},
remove: function (vnode, rm) {
remove: function (vnode: VNode, rm: Function) {
if (!shouldSkipTransition(vnode)) {
leave(vnode, rm)
} else {
rm()
}
}
}
} : {}

26
src/platforms/web/runtime/node-ops.js

@ -1,41 +1,47 @@
/* @flow */
import { namespaceMap } from 'web/util/index'
export function createElement (tagName) {
export function createElement (tagName: string): Element {
return document.createElement(tagName)
}
export function createElementNS (namespace, tagName) {
export function createElementNS (namespace: string, tagName: string): Element {
return document.createElementNS(namespaceMap[namespace], tagName)
}
export function createTextNode (text) {
export function createTextNode (text: string): Text {
return document.createTextNode(text)
}
export function insertBefore (parentNode, newNode, referenceNode) {
export function insertBefore (parentNode: Node, newNode: Node, referenceNode: Node) {
parentNode.insertBefore(newNode, referenceNode)
}
export function removeChild (node, child) {
export function removeChild (node: Node, child: Node) {
node.removeChild(child)
}
export function appendChild (node, child) {
export function appendChild (node: Node, child: Node) {
node.appendChild(child)
}
export function parentNode (node) {
export function parentNode (node: Node): ?Element {
return node.parentElement
}
export function nextSibling (node) {
export function nextSibling (node: Node): Node {
return node.nextSibling
}
export function tagName (node) {
export function tagName (node: Element): string {
return node.tagName
}
export function setTextContent (node, text) {
export function setTextContent (node: Node, text: string) {
node.textContent = text
}
export function childNodes (node: Node): NodeList {
return node.childNodes
}

7
src/platforms/web/server/directives/show.js

@ -1,5 +1,8 @@
export default function show (node, dir) {
/* @flow */
export default function show (node: VNodeWithData, dir: VNodeDirective) {
if (!dir.value) {
(node.data.style || (node.data.style = {})).display = 'none'
const style: any = node.data.style || (node.data.style = {})
style.display = 'none'
}
}

6
src/platforms/web/server/modules/attrs.js

@ -1,3 +1,5 @@
/* @flow */
import {
isBooleanAttr,
isEnumeratedAttr,
@ -5,7 +7,7 @@ import {
propsToAttrMap
} from 'web/util/index'
export default function renderAttrs (node) {
export default function renderAttrs (node: VNodeWithData): ?string {
if (node.data.attrs || node.data.props || node.data.staticAttrs) {
return (
serialize(node.data.staticAttrs) +
@ -15,7 +17,7 @@ export default function renderAttrs (node) {
}
}
function serialize (attrs, asProps) {
function serialize (attrs: ?{ [key: string]: any }, asProps?: boolean): string {
let res = ''
if (!attrs) {
return res

4
src/platforms/web/server/modules/class.js

@ -1,6 +1,8 @@
/* @flow */
import { genClassForVnode } from 'web/util/index'
export default function renderClass (node) {
export default function renderClass (node: VNodeWithData): ?string {
if (node.data.class || node.data.staticClass) {
return ` class="${genClassForVnode(node)}"`
}

17
src/platforms/web/server/modules/style.js

@ -1,12 +1,19 @@
import { hyphenate } from 'shared/util'
/* @flow */
export default function renderStyle (node) {
import { hyphenate, toObject } from 'shared/util'
export default function renderStyle (node: VNodeWithData): ?string {
const staticStyle = node.data.staticAttrs && node.data.staticAttrs.style
if (node.data.style || staticStyle) {
const styles = node.data.style
let styles = node.data.style
let res = ' style="'
for (const key in styles) {
res += `${hyphenate(key)}:${styles[key]};`
if (styles) {
if (Array.isArray(styles)) {
styles = toObject(styles)
}
for (const key in styles) {
res += `${hyphenate(key)}:${styles[key]};`
}
}
return res + (staticStyle || '') + '"'
}

17
src/platforms/web/util/attrs.js

@ -1,3 +1,5 @@
/* @flow */
import { makeMap } from 'shared/util'
// attributes that should be using props for binding
@ -22,6 +24,15 @@ export const propsToAttrMap = {
}
export const xlinkNS = 'http://www.w3.org/1999/xlink'
export const isXlink = name => name.charAt(5) === ':' && name.slice(0, 5) === 'xlink'
export const getXlinkProp = name => isXlink(name) ? name.slice(6, name.length) : ''
export const isFalsyAttrValue = val => val == null || val === false
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
}

26
src/platforms/web/util/class.js

@ -1,6 +1,8 @@
/* @flow */
import { extend, isObject } from 'shared/util'
export function genClassForVnode (vnode) {
export function genClassForVnode (vnode: VNode): string {
let data = vnode.data
// Important: check if this is a component container node
// or a child component root node
@ -14,44 +16,50 @@ export function genClassForVnode (vnode) {
return genClassFromData(data)
}
function mergeClassData (child, parent) {
function mergeClassData (child: VNodeData, parent: VNodeData): {
staticClass: string,
class: ?Object
} {
return {
staticClass: concat(child.staticClass, parent.staticClass),
class: child.class ? extend(child.class, parent.class) : parent.class
class: child.class
? extend(child.class, parent.class)
: parent.class
}
}
function genClassFromData (data) {
function genClassFromData (data: Object): string {
const dynamicClass = data.class
const staticClass = data.staticClass
if (staticClass || dynamicClass) {
return concat(staticClass, stringifyClass(dynamicClass))
}
return ''
}
export function concat (a, b) {
export function concat (a: ?string, b: ?string): string {
return a ? b ? (a + ' ' + b) : a : (b || '')
}
export function stringifyClass (value) {
export function stringifyClass (value: any): string {
let res = ''
if (!value) {
return ''
return res
}
if (typeof value === 'string') {
return value
}
if (Array.isArray(value)) {
let res = ''
for (let i = 0, l = value.length; i < l; i++) {
if (value[i]) res += stringifyClass(value[i]) + ' '
}
return res.slice(0, -1)
}
if (isObject(value)) {
let res = ''
for (const key in value) {
if (value[key]) res += key + ' '
}
return res.slice(0, -1)
}
return res
}

6
src/platforms/web/util/element.js

@ -1,3 +1,5 @@
/* @flow */
import { inBrowser } from 'core/util/env'
import { makeMap } from 'shared/util'
@ -51,7 +53,7 @@ const isSVG = makeMap(
true
)
export function getTagNamespace (tag) {
export function getTagNamespace (tag: string): ?string {
if (isSVG(tag)) {
return 'svg'
}
@ -63,7 +65,7 @@ export function getTagNamespace (tag) {
}
const unknownElementCache = Object.create(null)
export function isUnknownElement (tag) {
export function isUnknownElement (tag: string): boolean {
if (!inBrowser) {
return true
}

8
src/platforms/web/util/index.js

@ -1,3 +1,5 @@
/* @flow */
import { warn, inBrowser } from 'core/util/index'
export * from './attrs'
@ -10,11 +12,8 @@ export const isAndroid = UA && UA.indexOf('android') > 0
/**
* Query an element selector if it's not an element already.
*
* @param {String|Element} el
* @return {Element}
*/
export function query (el) {
export function query (el: string | Element): Element {
if (typeof el === 'string') {
const selector = el
el = document.querySelector(el)
@ -22,6 +21,7 @@ export function query (el) {
process.env.NODE_ENV !== 'production' && warn(
'Cannot find element: ' + selector
)
return document.createElement('div')
}
}
return el

15
src/shared/util.js

@ -127,7 +127,7 @@ export function toArray (list: any, start?: number): Array<any> {
/**
* Mix properties into target object.
*/
export function extend (to: Object, _from: Object): Object {
export function extend (to: Object, _from: ?Object): Object {
for (const key in _from) {
to[key] = _from[key]
}
@ -153,6 +153,19 @@ export function isPlainObject (obj: any): boolean {
return toString.call(obj) === OBJECT_STRING
}
/**
* Merge an Array of Objects into a single Object.
*/
export function toObject (arr: Array<any>): Object {
const res = arr[0] || {}
for (let i = 1; i < arr.length; i++) {
if (arr[i]) {
extend(res, arr[i])
}
}
return res
}
/**
* Perform no operation.
*/

Loading…
Cancel
Save