diff options
| author | ruki <waruqi@gmail.com> | 2018-11-08 00:38:48 +0800 |
|---|---|---|
| committer | ruki <waruqi@gmail.com> | 2018-11-07 21:53:09 +0800 |
| commit | 26105034da4fcce7ac883c899d781f016559310d (patch) | |
| tree | c459a5dc4e3aa0972d9919033ece511ce76dd129 /node_modules/vue/src/shared/util.js | |
| parent | 2c77f00f1a7ecb6c8192f9c16d3b2001b254a107 (diff) | |
| download | xmake-docs-26105034da4fcce7ac883c899d781f016559310d.tar.gz xmake-docs-26105034da4fcce7ac883c899d781f016559310d.zip | |
switch to vuepress
Diffstat (limited to 'node_modules/vue/src/shared/util.js')
| -rw-r--r-- | node_modules/vue/src/shared/util.js | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/node_modules/vue/src/shared/util.js b/node_modules/vue/src/shared/util.js new file mode 100644 index 00000000..e4884734 --- /dev/null +++ b/node_modules/vue/src/shared/util.js @@ -0,0 +1,324 @@ +/* @flow */ + +export const emptyObject = Object.freeze({}) + +// these helpers produces better vm code in JS engines due to their +// explicitness and function inlining +export function isUndef (v: any): boolean %checks { + return v === undefined || v === null +} + +export function isDef (v: any): boolean %checks { + return v !== undefined && v !== null +} + +export function isTrue (v: any): boolean %checks { + return v === true +} + +export function isFalse (v: any): boolean %checks { + return v === false +} + +/** + * Check if value is primitive + */ +export function isPrimitive (value: any): boolean %checks { + return ( + typeof value === 'string' || + typeof value === 'number' || + // $flow-disable-line + typeof value === 'symbol' || + typeof value === 'boolean' + ) +} + +/** + * Quick object check - this is primarily used to tell + * Objects from primitive values when we know the value + * is a JSON-compliant type. + */ +export function isObject (obj: mixed): boolean %checks { + return obj !== null && typeof obj === 'object' +} + +/** + * Get the raw type string of a value e.g. [object Object] + */ +const _toString = Object.prototype.toString + +export function toRawType (value: any): string { + return _toString.call(value).slice(8, -1) +} + +/** + * Strict object type check. Only returns true + * for plain JavaScript objects. + */ +export function isPlainObject (obj: any): boolean { + return _toString.call(obj) === '[object Object]' +} + +export function isRegExp (v: any): boolean { + return _toString.call(v) === '[object RegExp]' +} + +/** + * Check if val is a valid array index. + */ +export function isValidArrayIndex (val: any): boolean { + const n = parseFloat(String(val)) + return n >= 0 && Math.floor(n) === n && isFinite(val) +} + +/** + * Convert a value to a string that is actually rendered. + */ +export function toString (val: any): string { + return val == null + ? '' + : typeof val === 'object' + ? JSON.stringify(val, null, 2) + : String(val) +} + +/** + * Convert a input value to a number for persistence. + * If the conversion fails, return original string. + */ +export function toNumber (val: string): number | string { + const n = parseFloat(val) + return isNaN(n) ? val : n +} + +/** + * Make a map and return a function for checking if a key + * is in that map. + */ +export function makeMap ( + str: string, + expectsLowerCase?: boolean +): (key: string) => true | void { + const map = Object.create(null) + const list: Array<string> = str.split(',') + for (let i = 0; i < list.length; i++) { + map[list[i]] = true + } + return expectsLowerCase + ? val => map[val.toLowerCase()] + : val => map[val] +} + +/** + * Check if a tag is a built-in tag. + */ +export const isBuiltInTag = makeMap('slot,component', true) + +/** + * Check if a attribute is a reserved attribute. + */ +export const isReservedAttribute = makeMap('key,ref,slot,slot-scope,is') + +/** + * Remove an item from an array + */ +export function remove (arr: Array<any>, item: any): Array<any> | void { + if (arr.length) { + const index = arr.indexOf(item) + if (index > -1) { + return arr.splice(index, 1) + } + } +} + +/** + * Check whether the object has the property. + */ +const hasOwnProperty = Object.prototype.hasOwnProperty +export function hasOwn (obj: Object | Array<*>, key: string): boolean { + return hasOwnProperty.call(obj, key) +} + +/** + * Create a cached version of a pure function. + */ +export function cached<F: Function> (fn: F): F { + const cache = Object.create(null) + return (function cachedFn (str: string) { + const hit = cache[str] + return hit || (cache[str] = fn(str)) + }: any) +} + +/** + * Camelize a hyphen-delimited string. + */ +const camelizeRE = /-(\w)/g +export const camelize = cached((str: string): string => { + return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '') +}) + +/** + * Capitalize a string. + */ +export const capitalize = cached((str: string): string => { + return str.charAt(0).toUpperCase() + str.slice(1) +}) + +/** + * Hyphenate a camelCase string. + */ +const hyphenateRE = /\B([A-Z])/g +export const hyphenate = cached((str: string): string => { + return str.replace(hyphenateRE, '-$1').toLowerCase() +}) + +/** + * Simple bind polyfill for environments that do not support it... e.g. + * PhantomJS 1.x. Technically we don't need this anymore since native bind is + * now more performant in most browsers, but removing it would be breaking for + * code that was able to run in PhantomJS 1.x, so this must be kept for + * backwards compatibility. + */ + +/* istanbul ignore next */ +function polyfillBind (fn: Function, ctx: Object): Function { + function boundFn (a) { + const l = arguments.length + return l + ? l > 1 + ? fn.apply(ctx, arguments) + : fn.call(ctx, a) + : fn.call(ctx) + } + + boundFn._length = fn.length + return boundFn +} + +function nativeBind (fn: Function, ctx: Object): Function { + return fn.bind(ctx) +} + +export const bind = Function.prototype.bind + ? nativeBind + : polyfillBind + +/** + * Convert an Array-like object to a real Array. + */ +export function toArray (list: any, start?: number): Array<any> { + start = start || 0 + let i = list.length - start + const ret: Array<any> = new Array(i) + while (i--) { + ret[i] = list[i + start] + } + return ret +} + +/** + * Mix properties into target object. + */ +export function extend (to: Object, _from: ?Object): Object { + for (const key in _from) { + to[key] = _from[key] + } + return to +} + +/** + * Merge an Array of Objects into a single Object. + */ +export function toObject (arr: Array<any>): Object { + const res = {} + for (let i = 0; i < arr.length; i++) { + if (arr[i]) { + extend(res, arr[i]) + } + } + return res +} + +/** + * Perform no operation. + * Stubbing args to make Flow happy without leaving useless transpiled code + * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/) + */ +export function noop (a?: any, b?: any, c?: any) {} + +/** + * Always return false. + */ +export const no = (a?: any, b?: any, c?: any) => false + +/** + * Return same value + */ +export const identity = (_: any) => _ + +/** + * Generate a static keys string from compiler modules. + */ +export function genStaticKeys (modules: Array<ModuleOptions>): string { + return modules.reduce((keys, m) => { + return keys.concat(m.staticKeys || []) + }, []).join(',') +} + +/** + * Check if two values are loosely equal - that is, + * if they are plain objects, do they have the same shape? + */ +export function looseEqual (a: any, b: any): boolean { + if (a === b) return true + const isObjectA = isObject(a) + const isObjectB = isObject(b) + if (isObjectA && isObjectB) { + try { + const isArrayA = Array.isArray(a) + const isArrayB = Array.isArray(b) + if (isArrayA && isArrayB) { + return a.length === b.length && a.every((e, i) => { + return looseEqual(e, b[i]) + }) + } else if (!isArrayA && !isArrayB) { + const keysA = Object.keys(a) + const keysB = Object.keys(b) + return keysA.length === keysB.length && keysA.every(key => { + return looseEqual(a[key], b[key]) + }) + } else { + /* istanbul ignore next */ + return false + } + } catch (e) { + /* istanbul ignore next */ + return false + } + } else if (!isObjectA && !isObjectB) { + return String(a) === String(b) + } else { + return false + } +} + +export function looseIndexOf (arr: Array<mixed>, val: mixed): number { + for (let i = 0; i < arr.length; i++) { + if (looseEqual(arr[i], val)) return i + } + return -1 +} + +/** + * Ensure a function is called only once. + */ +export function once (fn: Function): Function { + let called = false + return function () { + if (!called) { + called = true + fn.apply(this, arguments) + } + } +} |
