UNPKG

asia-weex-vue-render4light

Version:

Web renderer for weex project written in Vue DSL.

273 lines (270 loc) 6.69 kB
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import { isArray } from './type' /** * Mix properties into target object. * the rightest object's value has the highest priority. */ export function extend (to, ...args) { if (!args || args.length <= 0) { return to } args.forEach(from => { if (typeof from !== 'object') { return } for (const key in from) { to[key] = from[key] } }) return to } /** * Mix truthy or '' property values into target object. * mostly for merging styles. (that's why '' is falsy but still should be counted in.) * the rightest object's value has the highest priority. */ export function extendTruthy (to, ...args) { if (!args || args.length <= 0) { return to } args.forEach(from => { if (typeof from !== 'object') { return } let i for (const key in from) { if (((i = from[key]) || i === '' || i === 0) && i !== 'undefined') { to[key] = i } } }) return to } /** * Mix specified properties into target object. */ export function extendKeys (to, from = {}, keys) { (keys || []).forEach(key => { from && (to[key] = from[key]) }) return to } /** * Extract specified properties from src to target object. */ export function extractKeys (to, from = {}, keys) { if (!from) { return to } (keys || []).forEach(key => { from && (to[key] = from[key]) from && (delete from[key]) }) return to } /** * Simple bind, faster than native * * @param {Function} fn * @param {Object} ctx * @return {Function} */ export function bind (fn, ctx) { return function (a) { const l = arguments.length return l ? l > 1 ? fn.apply(ctx, arguments) : fn.call(ctx, a) : fn.call(ctx) } } /** * Only call the func the last time before it's not that frequently called. */ export function debounce (func, wait) { let timerId return function (...args) { clearTimeout(timerId) timerId = setTimeout(function later () { timerId = null func.apply(null, args) }, wait) } } /** * Only call the func the first time before a series frequently function calls happen. */ export function depress (func, wait) { let timerId function later () { timerId = null } return function () { if (!timerId) { func.apply() } clearTimeout(timerId) timerId = setTimeout(later, wait) } } /** * Only call the func every time after a wait milliseconds if it's too frequently called. */ export function throttle (func, wait, callLastTime) { let last = 0 let lastTimer = null const lastTimeDuration = wait + (wait > 25 ? wait : 25) // plus half wait time. return function (...args) { const context = this const time = new Date().getTime() if (time - last > wait) { if (callLastTime) { lastTimer && clearTimeout(lastTimer) lastTimer = setTimeout(function () { lastTimer = null func.apply(context, args) }, lastTimeDuration) } func.apply(context, args) last = time } } } // direction: 'l' | 'r', default is 'r' // num: how many times to loop, should be a positive integer export function loopArray (arr, num, direction) { if (!isArray(arr)) { return } let isLeft = (direction + '').toLowerCase() === 'l' const len = arr.length num = num % len if (num < 0) { num = -num isLeft = !isLeft } if (num === 0) { return arr } let lp, rp if (isLeft) { lp = arr.slice(0, num) rp = arr.slice(num) } else { lp = arr.slice(0, len - num) rp = arr.slice(len - num) } return rp.concat(lp) } /** * Create a cached version of a pure function. */ export function cached (fn) { const cache = Object.create(null) return function cachedFn (str) { const hit = cache[str] return hit || (cache[str] = fn(str)) } } /** * Camelize a hyphen-delmited string. */ const camelizeRE = /-(\w)/g export const camelize = cached(str => { return str.replace(camelizeRE, (_, c) => c.toUpperCase()) }) export function camelizeKeys (obj) { const res = {} for (const key in obj) { res[camelize(key)] = obj[key] } return res } /** * Capitalize a string. */ export const capitalize = cached(str => { return str.charAt(0).toUpperCase() + str.slice(1) }) /** * Hyphenate a camelCase string. */ const hyphenateRE = /([^-])([A-Z])/g export const hyphenate = cached(str => { return str.replace(hyphenateRE, '$1-$2').replace(hyphenateRE, '$1-$2').toLowerCase() }) export function hyphenateKeys (obj) { const res = {} for (const key in obj) { res[hyphenate(key)] = obj[key] } return res } const vendorsReg = /webkit-|moz-|o-|ms-/ export function hyphenateStyleKeys (obj) { const res = {} for (const key in obj) { const hk = hyphenate(key).replace(vendorsReg, function ($0) { return '-' + $0 }) res[hk] = obj[key] } return res } export function camelToKebab (name) { if (!name) { return '' } return name.replace(/([A-Z])/g, function (g, g1) { return `-${g1.toLowerCase()}` }) } export function appendCss (css, cssId, replace) { let style = document.getElementById(cssId) if (style && replace) { style.parentNode.removeChild(style) style = null } if (!style) { style = document.createElement('style') style.type = 'text/css' cssId && (style.id = cssId) document.getElementsByTagName('head')[0].appendChild(style) } style.appendChild(document.createTextNode(css)) } export function nextFrame (callback) { const runner = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || (cb => setTimeout(cb, 16)) runner(callback) } export function toCSSText (object) { if (!object) { return } const obj = hyphenateStyleKeys(object) let cssText = '' for (const key in obj) { cssText += `${key}:${obj[key]};` } return cssText }