UNPKG

@tarojs/taro-qq

Version:
255 lines (237 loc) 7.09 kB
import { onAndSyncApis, noPromiseApis, otherApis, initPxTransform, Link } from '@tarojs/taro' import { cacheDataSet, cacheDataGet } from './data-cache' import { queryToJson, getUniqueKey } from './util' const RequestQueue = { MAX_REQUEST: 10, queue: [], pendingQueue: [], request (options) { this.queue.push(options) return this.run() }, run () { if (!this.queue.length) return while (this.pendingQueue.length < this.MAX_REQUEST) { const options = this.queue.shift() let successFn = options.success let failFn = options.fail options.success = (...args) => { this.pendingQueue = this.pendingQueue.filter(item => item !== options) this.run() successFn && successFn.apply(options, args) } options.fail = (...args) => { this.pendingQueue = this.pendingQueue.filter(item => item !== options) this.run() failFn && failFn.apply(options, args) } this.pendingQueue.push(options) return qq.request(options) } } } function taroInterceptor (chain) { return request(chain.requestParams) } const link = new Link(taroInterceptor) function request (options) { options = options || {} if (typeof options === 'string') { options = { url: options } } const originSuccess = options['success'] const originFail = options['fail'] const originComplete = options['complete'] let requestTask const p = new Promise((resolve, reject) => { options['success'] = res => { originSuccess && originSuccess(res) resolve(res) } options['fail'] = res => { originFail && originFail(res) reject(res) } options['complete'] = res => { originComplete && originComplete(res) } requestTask = RequestQueue.request(options) }) p.abort = (cb) => { cb && cb() if (requestTask) { requestTask.abort() } return p } return p } function processApis (taro) { const weApis = Object.assign({ }, onAndSyncApis, noPromiseApis, otherApis) const useDataCacheApis = { 'navigateTo': true, 'redirectTo': true, 'reLaunch': true } const routerParamsPrivateKey = '__key_' const preloadPrivateKey = '__preload_' const preloadInitedComponent = '$preloadComponent' Object.keys(weApis).forEach(key => { if (!(key in qq)) { taro[key] = () => { console.warn(`QQ小程序暂不支持 ${key}`) } return } if (!onAndSyncApis[key] && !noPromiseApis[key]) { taro[key] = (options, ...args) => { options = options || {} let task = null let obj = Object.assign({}, options) if (typeof options === 'string') { if (args.length) { return qq[key](options, ...args) } return qq[key](options) } if (key === 'navigateTo' || key === 'redirectTo') { let url = obj['url'] ? obj['url'].replace(/^\//, '') : '' if (url.indexOf('?') > -1) url = url.split('?')[0] const Component = cacheDataGet(url) if (Component) { const component = new Component() if (component.componentWillPreload) { const cacheKey = getUniqueKey() const MarkIndex = obj.url.indexOf('?') const hasMark = MarkIndex > -1 const urlQueryStr = hasMark ? obj.url.substring(MarkIndex + 1, obj.url.length) : '' const params = queryToJson(urlQueryStr) obj.url += (hasMark ? '&' : '?') + `${preloadPrivateKey}=${cacheKey}` cacheDataSet(cacheKey, component.componentWillPreload(params)) cacheDataSet(preloadInitedComponent, component) } } } if (useDataCacheApis[key]) { const url = obj['url'] = obj['url'] || '' const MarkIndex = url.indexOf('?') const hasMark = MarkIndex > -1 const urlQueryStr = hasMark ? url.substring(MarkIndex + 1, url.length) : '' const params = queryToJson(urlQueryStr) const cacheKey = getUniqueKey() obj.url += (hasMark ? '&' : '?') + `${routerParamsPrivateKey}=${cacheKey}` cacheDataSet(cacheKey, params) } const p = new Promise((resolve, reject) => { ['fail', 'success', 'complete'].forEach((k) => { obj[k] = (res) => { options[k] && options[k](res) if (k === 'success') { if (key === 'connectSocket') { resolve( Promise.resolve().then(() => Object.assign(task, res)) ) } else { resolve(res) } } else if (k === 'fail') { reject(res) } } }) if (args.length) { task = qq[key](obj, ...args) } else { task = qq[key](obj) } }) if (key === 'uploadFile' || key === 'downloadFile') { p.progress = cb => { if (task) { task.onProgressUpdate(cb) } return p } p.abort = cb => { cb && cb() if (task) { task.abort() } return p } } return p } } else { taro[key] = (...args) => { const argsLen = args.length const newArgs = args.concat() const lastArg = newArgs[argsLen - 1] if (lastArg && lastArg.isTaroComponent && lastArg.$scope) { newArgs.splice(argsLen - 1, 1, lastArg.$scope) } return qq[key].apply(qq, newArgs) } } }) } function pxTransform (size) { const { designWidth = 750, deviceRatio = { '640': 2.34 / 2, '750': 1, '828': 1.81 / 2 } } = this.config || {} if (!(designWidth in deviceRatio)) { throw new Error(`deviceRatio 配置中不存在 ${designWidth} 的设置!`) } return parseInt(size, 10) / deviceRatio[designWidth] + 'rpx' } function canIUseWebp () { const { platform } = qq.getSystemInfoSync() const platformLower = platform.toLowerCase() if (platformLower === 'android' || platformLower === 'devtools') { return true } return false } function qqCloud (taro) { const qqC = qq.cloud || {} const qqcloud = {} const apiList = [ 'init', 'database', 'uploadFile', 'downloadFile', 'getTempFileURL', 'deleteFile', 'callFunction' ] apiList.forEach(v => { qqcloud[v] = qqC[v] }) taro.cloud = qqcloud } export default function initNativeApi (taro) { processApis(taro) taro.request = link.request.bind(link) taro.addInterceptor = link.addInterceptor.bind(link) taro.cleanInterceptors = link.cleanInterceptors.bind(link) taro.getCurrentPages = getCurrentPages taro.getApp = getApp taro.requirePlugin = requirePlugin taro.initPxTransform = initPxTransform.bind(taro) taro.pxTransform = pxTransform.bind(taro) taro.canIUseWebp = canIUseWebp qqCloud(taro) }