diff --git a/packages/uni-mp-kuaishou/dist/index.js b/packages/uni-mp-kuaishou/dist/index.js index 852bd5c15fca57962f7f9ea0f20247cc4e5c4489..830ba0af262ef9f857e44fd5ea6d0a2ecdf198fd 100644 --- a/packages/uni-mp-kuaishou/dist/index.js +++ b/packages/uni-mp-kuaishou/dist/index.js @@ -1,82 +1,82 @@ -import Vue from 'vue'; import { initVueI18n } from '@dcloudio/uni-i18n'; +import Vue from 'vue'; -let realAtob; - -const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; -const b64re = /^(?:[A-Za-z\d+/]{4})*?(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/; - -if (typeof atob !== 'function') { - realAtob = function (str) { - str = String(str).replace(/[\t\n\f\r ]+/g, ''); - if (!b64re.test(str)) { throw new Error("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.") } - - // Adding the padding if missing, for semplicity - str += '=='.slice(2 - (str.length & 3)); - var bitmap; var result = ''; var r1; var r2; var i = 0; - for (; i < str.length;) { - bitmap = b64.indexOf(str.charAt(i++)) << 18 | b64.indexOf(str.charAt(i++)) << 12 | - (r1 = b64.indexOf(str.charAt(i++))) << 6 | (r2 = b64.indexOf(str.charAt(i++))); - - result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255) - : r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255) - : String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255); - } - return result - }; -} else { - // 注意atob只能在全局对象上调用,例如:`const Base64 = {atob};Base64.atob('xxxx')`是错误的用法 - realAtob = atob; -} - -function b64DecodeUnicode (str) { - return decodeURIComponent(realAtob(str).split('').map(function (c) { - return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2) - }).join('')) -} - -function getCurrentUserInfo () { - const token = ( ks).getStorageSync('uni_id_token') || ''; - const tokenArr = token.split('.'); - if (!token || tokenArr.length !== 3) { - return { - uid: null, - role: [], - permission: [], - tokenExpired: 0 - } - } - let userInfo; - try { - userInfo = JSON.parse(b64DecodeUnicode(tokenArr[1])); - } catch (error) { - throw new Error('获取当前用户信息出错,详细错误信息为:' + error.message) - } - userInfo.tokenExpired = userInfo.exp * 1000; - delete userInfo.exp; - delete userInfo.iat; - return userInfo -} - -function uniIdMixin (Vue) { - Vue.prototype.uniIDHasRole = function (roleId) { - const { - role - } = getCurrentUserInfo(); - return role.indexOf(roleId) > -1 - }; - Vue.prototype.uniIDHasPermission = function (permissionId) { - const { - permission - } = getCurrentUserInfo(); - return this.uniIDHasRole('admin') || permission.indexOf(permissionId) > -1 - }; - Vue.prototype.uniIDTokenValid = function () { - const { - tokenExpired - } = getCurrentUserInfo(); - return tokenExpired > Date.now() - }; +let realAtob; + +const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; +const b64re = /^(?:[A-Za-z\d+/]{4})*?(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/; + +if (typeof atob !== 'function') { + realAtob = function (str) { + str = String(str).replace(/[\t\n\f\r ]+/g, ''); + if (!b64re.test(str)) { throw new Error("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.") } + + // Adding the padding if missing, for semplicity + str += '=='.slice(2 - (str.length & 3)); + var bitmap; var result = ''; var r1; var r2; var i = 0; + for (; i < str.length;) { + bitmap = b64.indexOf(str.charAt(i++)) << 18 | b64.indexOf(str.charAt(i++)) << 12 | + (r1 = b64.indexOf(str.charAt(i++))) << 6 | (r2 = b64.indexOf(str.charAt(i++))); + + result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255) + : r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255) + : String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255); + } + return result + }; +} else { + // 注意atob只能在全局对象上调用,例如:`const Base64 = {atob};Base64.atob('xxxx')`是错误的用法 + realAtob = atob; +} + +function b64DecodeUnicode (str) { + return decodeURIComponent(realAtob(str).split('').map(function (c) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2) + }).join('')) +} + +function getCurrentUserInfo () { + const token = ( ks).getStorageSync('uni_id_token') || ''; + const tokenArr = token.split('.'); + if (!token || tokenArr.length !== 3) { + return { + uid: null, + role: [], + permission: [], + tokenExpired: 0 + } + } + let userInfo; + try { + userInfo = JSON.parse(b64DecodeUnicode(tokenArr[1])); + } catch (error) { + throw new Error('获取当前用户信息出错,详细错误信息为:' + error.message) + } + userInfo.tokenExpired = userInfo.exp * 1000; + delete userInfo.exp; + delete userInfo.iat; + return userInfo +} + +function uniIdMixin (Vue) { + Vue.prototype.uniIDHasRole = function (roleId) { + const { + role + } = getCurrentUserInfo(); + return role.indexOf(roleId) > -1 + }; + Vue.prototype.uniIDHasPermission = function (permissionId) { + const { + permission + } = getCurrentUserInfo(); + return this.uniIDHasRole('admin') || permission.indexOf(permissionId) > -1 + }; + Vue.prototype.uniIDTokenValid = function () { + const { + tokenExpired + } = getCurrentUserInfo(); + return tokenExpired > Date.now() + }; } const _toString = Object.prototype.toString; @@ -98,7 +98,7 @@ function hasOwn (obj, key) { return hasOwnProperty.call(obj, key) } -function noop () {} +function noop () { } /** * Create a cached version of a pure function. @@ -314,7 +314,7 @@ const promiseInterceptor = { }; const SYNC_API_RE = - /^\$|Window$|WindowStyle$|sendHostEvent|sendNativeEvent|restoreGlobal|getCurrentSubNVue|getMenuButtonBoundingClientRect|^report|interceptors|Interceptor$|getSubNVueById|requireNativePlugin|upx2px|hideKeyboard|canIUse|^create|Sync$|Manager$|base64ToArrayBuffer|arrayBufferToBase64|getLocale|setLocale|invokePushCallback/; + /^\$|Window$|WindowStyle$|sendHostEvent|sendNativeEvent|restoreGlobal|requireGlobal|getCurrentSubNVue|getMenuButtonBoundingClientRect|^report|interceptors|Interceptor$|getSubNVueById|requireNativePlugin|upx2px|hideKeyboard|canIUse|^create|Sync$|Manager$|base64ToArrayBuffer|arrayBufferToBase64|getLocale|setLocale|invokePushCallback|getWindowInfo|getDeviceInfo|getAppBaseInfo|getSystemSetting|getAppAuthorizeSetting/; const CONTEXT_API_RE = /^create|Manager$/; @@ -322,7 +322,7 @@ const CONTEXT_API_RE = /^create|Manager$/; const CONTEXT_API_RE_EXC = ['createBLEConnection']; // 同步例外情况 -const ASYNC_API = ['createBLEConnection']; +const ASYNC_API = ['createBLEConnection', 'createPushMessage']; const CALLBACK_API_RE = /^on|^off/; @@ -427,7 +427,134 @@ function upx2px (number, newDeviceWidth) { return number < 0 ? -result : result } -function getLocale () { +const LOCALE_ZH_HANS = 'zh-Hans'; +const LOCALE_ZH_HANT = 'zh-Hant'; +const LOCALE_EN = 'en'; +const LOCALE_FR = 'fr'; +const LOCALE_ES = 'es'; + +const messages = {}; + +let locale; + +{ + locale = normalizeLocale(ks.getSystemInfoSync().language) || LOCALE_EN; +} + +function initI18nMessages () { + if (!isEnableLocale()) { + return + } + const localeKeys = Object.keys(__uniConfig.locales); + if (localeKeys.length) { + localeKeys.forEach((locale) => { + const curMessages = messages[locale]; + const userMessages = __uniConfig.locales[locale]; + if (curMessages) { + Object.assign(curMessages, userMessages); + } else { + messages[locale] = userMessages; + } + }); + } +} + +initI18nMessages(); + +const i18n = initVueI18n( + locale, + {} +); +const t = i18n.t; +const i18nMixin = (i18n.mixin = { + beforeCreate () { + const unwatch = i18n.i18n.watchLocale(() => { + this.$forceUpdate(); + }); + this.$once('hook:beforeDestroy', function () { + unwatch(); + }); + }, + methods: { + $$t (key, values) { + return t(key, values) + } + } +}); +const setLocale = i18n.setLocale; +const getLocale = i18n.getLocale; + +function initAppLocale (Vue, appVm, locale) { + const state = Vue.observable({ + locale: locale || i18n.getLocale() + }); + const localeWatchers = []; + appVm.$watchLocale = fn => { + localeWatchers.push(fn); + }; + Object.defineProperty(appVm, '$locale', { + get () { + return state.locale + }, + set (v) { + state.locale = v; + localeWatchers.forEach(watch => watch(v)); + } + }); +} + +function isEnableLocale () { + return typeof __uniConfig !== 'undefined' && __uniConfig.locales && !!Object.keys(__uniConfig.locales).length +} + +function include (str, parts) { + return !!parts.find((part) => str.indexOf(part) !== -1) +} + +function startsWith (str, parts) { + return parts.find((part) => str.indexOf(part) === 0) +} + +function normalizeLocale (locale, messages) { + if (!locale) { + return + } + locale = locale.trim().replace(/_/g, '-'); + if (messages && messages[locale]) { + return locale + } + locale = locale.toLowerCase(); + if (locale === 'chinese') { + // 支付宝 + return LOCALE_ZH_HANS + } + if (locale.indexOf('zh') === 0) { + if (locale.indexOf('-hans') > -1) { + return LOCALE_ZH_HANS + } + if (locale.indexOf('-hant') > -1) { + return LOCALE_ZH_HANT + } + if (include(locale, ['-tw', '-hk', '-mo', '-cht'])) { + return LOCALE_ZH_HANT + } + return LOCALE_ZH_HANS + } + const lang = startsWith(locale, [LOCALE_EN, LOCALE_FR, LOCALE_ES]); + if (lang) { + return lang + } +} +// export function initI18n() { +// const localeKeys = Object.keys(__uniConfig.locales || {}) +// if (localeKeys.length) { +// localeKeys.forEach((locale) => +// i18n.add(locale, __uniConfig.locales[locale]) +// ) +// } +// } + +function getLocale$1 () { // 优先使用 $locale const app = getApp({ allowDefault: true @@ -435,10 +562,10 @@ function getLocale () { if (app && app.$vm) { return app.$vm.$locale } - return ks.getSystemInfoSync().language || 'zh-Hans' + return normalizeLocale(ks.getSystemInfoSync().language) || LOCALE_EN } -function setLocale (locale) { +function setLocale$1 (locale) { const app = getApp(); if (!app) { return false @@ -462,7 +589,7 @@ function onLocaleChange (fn) { } if (typeof global !== 'undefined') { - global.getLocale = getLocale; + global.getLocale = getLocale$1; } const interceptors = { @@ -472,8 +599,8 @@ const interceptors = { var baseApi = /*#__PURE__*/Object.freeze({ __proto__: null, upx2px: upx2px, - getLocale: getLocale, - setLocale: setLocale, + getLocale: getLocale$1, + setLocale: setLocale$1, onLocaleChange: onLocaleChange, addInterceptor: addInterceptor, removeInterceptor: removeInterceptor, @@ -651,57 +778,187 @@ var previewImage = { } }; -const UUID_KEY = '__DC_STAT_UUID'; -let deviceId; -function addUuid (result) { - deviceId = deviceId || ks.getStorageSync(UUID_KEY); - if (!deviceId) { - deviceId = Date.now() + '' + Math.floor(Math.random() * 1e7); - ks.setStorage({ - key: UUID_KEY, - data: deviceId - }); - } - result.deviceId = deviceId; -} - -function addSafeAreaInsets (result) { - if (result.safeArea) { - const safeArea = result.safeArea; - result.safeAreaInsets = { - top: safeArea.top, - left: safeArea.left, - right: result.windowWidth - safeArea.right, - bottom: result.windowHeight - safeArea.bottom - }; - } +const UUID_KEY = '__DC_STAT_UUID'; +let deviceId; +function useDeviceId (result) { + deviceId = deviceId || ks.getStorageSync(UUID_KEY); + if (!deviceId) { + deviceId = Date.now() + '' + Math.floor(Math.random() * 1e7); + ks.setStorage({ + key: UUID_KEY, + data: deviceId + }); + } + result.deviceId = deviceId; +} + +function addSafeAreaInsets (result) { + if (result.safeArea) { + const safeArea = result.safeArea; + result.safeAreaInsets = { + top: safeArea.top, + left: safeArea.left, + right: result.windowWidth - safeArea.right, + bottom: result.screenHeight - safeArea.bottom + }; + } +} + +function populateParameters (result) { + const { + brand = '', model = '', system = '', + language = '', theme, version, + platform, fontSizeSetting, + SDKVersion, pixelRatio, deviceOrientation + } = result; + // const isQuickApp = "mp-kuaishou".indexOf('quickapp-webview') !== -1 + + // osName osVersion + let osName = ''; + let osVersion = ''; + { + osName = system.split(' ')[0] || ''; + osVersion = system.split(' ')[1] || ''; + } + let hostVersion = version; + + // deviceType + const deviceType = getGetDeviceType(result, model); + + // deviceModel + const deviceBrand = getDeviceBrand(brand); + + // hostName + const _hostName = getHostName(result); + + // deviceOrientation + let _deviceOrientation = deviceOrientation; // 仅 微信 百度 支持 + + // devicePixelRatio + let _devicePixelRatio = pixelRatio; + + // SDKVersion + let _SDKVersion = SDKVersion; + + // hostLanguage + const hostLanguage = language.replace(/_/g, '-'); + + // wx.getAccountInfoSync + + const parameters = { + appId: process.env.UNI_APP_ID, + appName: process.env.UNI_APP_NAME, + appVersion: process.env.UNI_APP_VERSION_NAME, + appVersionCode: process.env.UNI_APP_VERSION_CODE, + appLanguage: getAppLanguage(hostLanguage), + uniCompileVersion: process.env.UNI_COMPILER_VERSION, + uniRuntimeVersion: process.env.UNI_COMPILER_VERSION, + uniPlatform: process.env.UNI_SUB_PLATFORM || process.env.UNI_PLATFORM, + deviceBrand, + deviceModel: model, + deviceType, + devicePixelRatio: _devicePixelRatio, + deviceOrientation: _deviceOrientation, + osName: osName.toLocaleLowerCase(), + osVersion, + hostTheme: theme, + hostVersion, + hostLanguage, + hostName: _hostName, + hostSDKVersion: _SDKVersion, + hostFontSizeSetting: fontSizeSetting, + windowTop: 0, + windowBottom: 0, + // TODO + osLanguage: undefined, + osTheme: undefined, + ua: undefined, + hostPackageName: undefined, + browserName: undefined, + browserVersion: undefined + }; + + Object.assign(result, parameters); +} + +function getGetDeviceType (result, model) { + let deviceType = result.deviceType || 'phone'; + { + const deviceTypeMaps = { + ipad: 'pad', + windows: 'pc', + mac: 'pc' + }; + const deviceTypeMapsKeys = Object.keys(deviceTypeMaps); + const _model = model.toLocaleLowerCase(); + for (let index = 0; index < deviceTypeMapsKeys.length; index++) { + const _m = deviceTypeMapsKeys[index]; + if (_model.indexOf(_m) !== -1) { + deviceType = deviceTypeMaps[_m]; + break + } + } + } + return deviceType +} + +function getDeviceBrand (brand) { + let deviceBrand = brand; + if (deviceBrand) { + deviceBrand = brand.toLocaleLowerCase(); + } + return deviceBrand +} + +function getAppLanguage (defaultLanguage) { + return getLocale$1 + ? getLocale$1() + : defaultLanguage +} + +function getHostName (result) { + const _platform = "mp-kuaishou".split('-')[1]; + let _hostName = result.hostName || _platform; // mp-jd + { _hostName = result.host; } + + return _hostName } -var getSystemInfo = { - returnValue: function (result) { - addUuid(result); - addSafeAreaInsets(result); - } +var getSystemInfo = { + returnValue: function (result) { + useDeviceId(result); + addSafeAreaInsets(result); + populateParameters(result); + } }; -const oName = 'getUserInfo'; -const nName = 'getUserProfile'; - -var getUserProfile = { - name: ks.canIUse(nName) ? nName : oName +const oName = 'getUserInfo'; +const nName = 'getUserProfile'; + +var getUserProfile = { + name: ks.canIUse(nName) ? nName : oName }; -const protocols = { - navigateTo, - redirectTo, - previewImage, - getSystemInfo, - getSystemInfoSync: getSystemInfo, - getUserProfile -}; -const todos = [ - 'vibrate' -]; +const protocols = { + navigateTo, + redirectTo, + previewImage, + getSystemInfo, + getSystemInfoSync: getSystemInfo, + getUserProfile, + requestPayment: { + name: ks.pay ? 'pay' : 'requestPayment', + args(fromArgs) { + if (typeof fromArgs === 'object') { + // ks.pay 服务类型 id(固定值为 '1') + if (ks.pay && !fromArgs.serviceId) fromArgs.serviceId = '1'; + } + } + } +}; +const todos = [ + 'vibrate' +]; const canIUses = []; const CALLBACKS = ['success', 'fail', 'cancel', 'complete']; @@ -919,6 +1176,7 @@ function getApiCallbacks (params) { let cid; let cidErrMsg; +let enabled; function normalizePushMessage (message) { try { @@ -930,17 +1188,25 @@ function normalizePushMessage (message) { function invokePushCallback ( args ) { - if (args.type === 'clientId') { + if (args.type === 'enabled') { + enabled = true; + } else if (args.type === 'clientId') { cid = args.cid; cidErrMsg = args.errMsg; invokeGetPushCidCallbacks(cid, args.errMsg); } else if (args.type === 'pushMsg') { - onPushMessageCallbacks.forEach((callback) => { - callback({ - type: 'receive', - data: normalizePushMessage(args.message) - }); - }); + const message = { + type: 'receive', + data: normalizePushMessage(args.message) + }; + for (let i = 0; i < onPushMessageCallbacks.length; i++) { + const callback = onPushMessageCallbacks[i]; + callback(message); + // 该消息已被阻止 + if (message.stopped) { + break + } + } } else if (args.type === 'click') { onPushMessageCallbacks.forEach((callback) => { callback({ @@ -960,7 +1226,7 @@ function invokeGetPushCidCallbacks (cid, errMsg) { getPushCidCallbacks.length = 0; } -function getPushCid (args) { +function getPushClientId (args) { if (!isPlainObject(args)) { args = {}; } @@ -972,25 +1238,33 @@ function getPushCid (args) { const hasSuccess = isFn(success); const hasFail = isFn(fail); const hasComplete = isFn(complete); - getPushCidCallbacks.push((cid, errMsg) => { - let res; - if (cid) { - res = { - errMsg: 'getPushCid:ok', - cid - }; - hasSuccess && success(res); - } else { - res = { - errMsg: 'getPushCid:fail' + (errMsg ? ' ' + errMsg : '') - }; - hasFail && fail(res); + + Promise.resolve().then(() => { + if (typeof enabled === 'undefined') { + enabled = false; + cid = ''; + cidErrMsg = 'uniPush is not enabled'; + } + getPushCidCallbacks.push((cid, errMsg) => { + let res; + if (cid) { + res = { + errMsg: 'getPushClientId:ok', + cid + }; + hasSuccess && success(res); + } else { + res = { + errMsg: 'getPushClientId:fail' + (errMsg ? ' ' + errMsg : '') + }; + hasFail && fail(res); + } + hasComplete && complete(res); + }); + if (typeof cid !== 'undefined') { + invokeGetPushCidCallbacks(cid, cidErrMsg); } - hasComplete && complete(res); }); - if (typeof cid !== 'undefined') { - Promise.resolve().then(() => invokeGetPushCidCallbacks(cid, cidErrMsg)); - } } const onPushMessageCallbacks = []; @@ -998,7 +1272,7 @@ const onPushMessageCallbacks = []; const onPushMessage = (fn) => { if (onPushMessageCallbacks.indexOf(fn) === -1) { onPushMessageCallbacks.push(fn); - } + } }; const offPushMessage = (fn) => { @@ -1014,7 +1288,7 @@ const offPushMessage = (fn) => { var api = /*#__PURE__*/Object.freeze({ __proto__: null, - getPushCid: getPushCid, + getPushClientId: getPushClientId, onPushMessage: onPushMessage, offPushMessage: offPushMessage, invokePushCallback: invokePushCallback @@ -1032,7 +1306,11 @@ const customize = cached((str) => { function initTriggerEvent (mpInstance) { const oldTriggerEvent = mpInstance.triggerEvent; const newTriggerEvent = function (event, ...args) { - return oldTriggerEvent.apply(mpInstance, [customize(event), ...args]) + // 事件名统一转驼峰格式,仅处理:当前组件为 vue 组件、当前组件为 vue 组件子组件 + if (this.$vm || (this.dataset && this.dataset.comType)) { + event = customize(event); + } + return oldTriggerEvent.apply(this, [event, ...args]) }; try { // 京东小程序 triggerEvent 为只读 @@ -1131,6 +1409,29 @@ function initHooks (mpOptions, hooks, vueOptions) { }); } +function initUnknownHooks (mpOptions, vueOptions, excludes = []) { + findHooks(vueOptions).forEach((hook) => initHook$1(mpOptions, hook, excludes)); +} + +function findHooks (vueOptions, hooks = []) { + if (vueOptions) { + Object.keys(vueOptions).forEach((name) => { + if (name.indexOf('on') === 0 && isFn(vueOptions[name])) { + hooks.push(name); + } + }); + } + return hooks +} + +function initHook$1 (mpOptions, hook, excludes) { + if (excludes.indexOf(hook) === -1 && !hasOwn(mpOptions, hook)) { + mpOptions[hook] = function (args) { + return this.$vm && this.$vm.__call_hook(hook, args) + }; + } +} + function initVueComponent (Vue, vueOptions) { vueOptions = vueOptions.default || vueOptions; let VueComponent; @@ -1181,7 +1482,7 @@ function initData (vueOptions, context) { try { // 对 data 格式化 data = JSON.parse(JSON.stringify(data)); - } catch (e) {} + } catch (e) { } } if (!isPlainObject(data)) { @@ -1268,18 +1569,13 @@ function parsePropType (key, type, defaultValue, file) { return type } -function initProperties (props, isBehavior = false, file = '') { +function initProperties (props, isBehavior = false, file = '', options) { const properties = {}; if (!isBehavior) { properties.vueId = { type: String, value: '' }; - // 用于字节跳动小程序模拟抽象节点 - properties.generic = { - type: Object, - value: null - }; // scopedSlotsCompiler auto properties.scopedSlotsCompiler = { type: String, @@ -1338,7 +1634,7 @@ function wrapper$1 (event) { // TODO 又得兼容 mpvue 的 mp 对象 try { event.mp = JSON.parse(JSON.stringify(event)); - } catch (e) {} + } catch (e) { } event.stopPropagation = noop; event.preventDefault = noop; @@ -1409,7 +1705,7 @@ function getExtraValue (vm, dataPathsArray) { return context } -function processEventExtra (vm, extra, event) { +function processEventExtra (vm, extra, event, __args__) { const extraObj = {}; if (Array.isArray(extra) && extra.length) { @@ -1432,11 +1728,7 @@ function processEventExtra (vm, extra, event) { if (dataPath === '$event') { // $event extraObj['$' + index] = event; } else if (dataPath === 'arguments') { - if (event.detail && event.detail.__args__) { - extraObj['$' + index] = event.detail.__args__; - } else { - extraObj['$' + index] = [event]; - } + extraObj['$' + index] = event.detail ? event.detail.__args__ || __args__ : __args__; } else if (dataPath.indexOf('$event.') === 0) { // $event.target.value extraObj['$' + index] = vm.__get_value(dataPath.replace('$event.', ''), event); } else { @@ -1463,6 +1755,12 @@ function getObjByArray (arr) { function processEventArgs (vm, event, args = [], extra = [], isCustom, methodName) { let isCustomMPEvent = false; // wxcomponent 组件,传递原始 event 对象 + + // fixed 用户直接触发 mpInstance.triggerEvent + const __args__ = isPlainObject(event.detail) + ? event.detail.__args__ || [event.detail] + : [event.detail]; + if (isCustom) { // 自定义事件 isCustomMPEvent = event.currentTarget && event.currentTarget.dataset && @@ -1471,11 +1769,11 @@ function processEventArgs (vm, event, args = [], extra = [], isCustom, methodNam if (isCustomMPEvent) { return [event] } - return event.detail.__args__ || event.detail + return __args__ } } - const extraObj = processEventExtra(vm, extra, event); + const extraObj = processEventExtra(vm, extra, event, __args__); const ret = []; args.forEach(arg => { @@ -1484,7 +1782,7 @@ function processEventArgs (vm, event, args = [], extra = [], isCustom, methodNam ret.push(event.target.value); } else { if (isCustom && !isCustomMPEvent) { - ret.push(event.detail.__args__[0]); + ret.push(__args__[0]); } else { // wxcomponent 组件或内置组件 ret.push(event); } @@ -1575,7 +1873,9 @@ function handleEvent (event) { } const handler = handlerCtx[methodName]; if (!isFn(handler)) { - throw new Error(` _vm.${methodName} is not a function`) + const type = this.$vm.mpType === 'page' ? 'Page' : 'Component'; + const path = this.route || this.is; + throw new Error(`${type} "${path}" does not have a method "${methodName}"`) } if (isOnce) { if (handler.once) { @@ -1612,250 +1912,168 @@ function handleEvent (event) { } } -const messages = {}; - -let locale; +const hooks = [ + 'onShow', + 'onHide', + 'onError', + 'onPageNotFound', + 'onThemeChange', + 'onUnhandledRejection' +]; -{ - locale = ks.getSystemInfoSync().language; +function initEventChannel$1 () { + Vue.prototype.getOpenerEventChannel = function () { + if (!this.__eventChannel__) { + this.__eventChannel__ = new EventChannel(); + } + return this.__eventChannel__ + }; + const callHook = Vue.prototype.__call_hook; + Vue.prototype.__call_hook = function (hook, args) { + if (hook === 'onLoad' && args && args.__id__) { + this.__eventChannel__ = getEventChannel(args.__id__); + delete args.__id__; + } + return callHook.call(this, hook, args) + }; } -function initI18nMessages () { - if (!isEnableLocale()) { - return - } - const localeKeys = Object.keys(__uniConfig.locales); - if (localeKeys.length) { - localeKeys.forEach((locale) => { - const curMessages = messages[locale]; - const userMessages = __uniConfig.locales[locale]; - if (curMessages) { - Object.assign(curMessages, userMessages); - } else { - messages[locale] = userMessages; - } - }); - } -} +function initScopedSlotsParams () { + const center = {}; + const parents = {}; -initI18nMessages(); + Vue.prototype.$hasScopedSlotsParams = function (vueId) { + const has = center[vueId]; + if (!has) { + parents[vueId] = this; + this.$on('hook:destroyed', () => { + delete parents[vueId]; + }); + } + return has + }; -const i18n = initVueI18n( - locale, - {} -); -const t = i18n.t; -const i18nMixin = (i18n.mixin = { - beforeCreate () { - const unwatch = i18n.i18n.watchLocale(() => { - this.$forceUpdate(); - }); - this.$once('hook:beforeDestroy', function () { - unwatch(); - }); - }, - methods: { - $$t (key, values) { - return t(key, values) + Vue.prototype.$getScopedSlotsParams = function (vueId, name, key) { + const data = center[vueId]; + if (data) { + const object = data[name] || {}; + return key ? object[key] : object + } else { + parents[vueId] = this; + this.$on('hook:destroyed', () => { + delete parents[vueId]; + }); } - } -}); -const setLocale$1 = i18n.setLocale; -const getLocale$1 = i18n.getLocale; + }; -function initAppLocale (Vue, appVm, locale) { - const state = Vue.observable({ - locale: locale || i18n.getLocale() - }); - const localeWatchers = []; - appVm.$watchLocale = fn => { - localeWatchers.push(fn); + Vue.prototype.$setScopedSlotsParams = function (name, value) { + const vueIds = this.$options.propsData.vueId; + if (vueIds) { + const vueId = vueIds.split(',')[0]; + const object = center[vueId] = center[vueId] || {}; + object[name] = value; + if (parents[vueId]) { + parents[vueId].$forceUpdate(); + } + } }; - Object.defineProperty(appVm, '$locale', { - get () { - return state.locale - }, - set (v) { - state.locale = v; - localeWatchers.forEach(watch => watch(v)); + + Vue.mixin({ + destroyed () { + const propsData = this.$options.propsData; + const vueId = propsData && propsData.vueId; + if (vueId) { + delete center[vueId]; + delete parents[vueId]; + } } }); } -function isEnableLocale () { - return typeof __uniConfig !== 'undefined' && __uniConfig.locales && !!Object.keys(__uniConfig.locales).length -} +function parseBaseApp (vm, { + mocks, + initRefs +}) { + initEventChannel$1(); + { + initScopedSlotsParams(); + } + if (vm.$options.store) { + Vue.prototype.$store = vm.$options.store; + } + uniIdMixin(Vue); -// export function initI18n() { -// const localeKeys = Object.keys(__uniConfig.locales || {}) -// if (localeKeys.length) { -// localeKeys.forEach((locale) => -// i18n.add(locale, __uniConfig.locales[locale]) -// ) -// } -// } - -const hooks = [ - 'onShow', - 'onHide', - 'onError', - 'onPageNotFound', - 'onThemeChange', - 'onUnhandledRejection' -]; - -function initEventChannel$1 () { - Vue.prototype.getOpenerEventChannel = function () { - if (!this.__eventChannel__) { - this.__eventChannel__ = new EventChannel(); - } - return this.__eventChannel__ - }; - const callHook = Vue.prototype.__call_hook; - Vue.prototype.__call_hook = function (hook, args) { - if (hook === 'onLoad' && args && args.__id__) { - this.__eventChannel__ = getEventChannel(args.__id__); - delete args.__id__; - } - return callHook.call(this, hook, args) - }; -} - -function initScopedSlotsParams () { - const center = {}; - const parents = {}; - - Vue.prototype.$hasScopedSlotsParams = function (vueId) { - const has = center[vueId]; - if (!has) { - parents[vueId] = this; - this.$on('hook:destroyed', () => { - delete parents[vueId]; - }); - } - return has - }; - - Vue.prototype.$getScopedSlotsParams = function (vueId, name, key) { - const data = center[vueId]; - if (data) { - const object = data[name] || {}; - return key ? object[key] : object - } else { - parents[vueId] = this; - this.$on('hook:destroyed', () => { - delete parents[vueId]; - }); - } - }; - - Vue.prototype.$setScopedSlotsParams = function (name, value) { - const vueIds = this.$options.propsData.vueId; - if (vueIds) { - const vueId = vueIds.split(',')[0]; - const object = center[vueId] = center[vueId] || {}; - object[name] = value; - if (parents[vueId]) { - parents[vueId].$forceUpdate(); - } - } - }; - - Vue.mixin({ - destroyed () { - const propsData = this.$options.propsData; - const vueId = propsData && propsData.vueId; - if (vueId) { - delete center[vueId]; - delete parents[vueId]; - } - } - }); -} - -function parseBaseApp (vm, { - mocks, - initRefs -}) { - initEventChannel$1(); - { - initScopedSlotsParams(); - } - if (vm.$options.store) { - Vue.prototype.$store = vm.$options.store; - } - uniIdMixin(Vue); - - Vue.prototype.mpHost = "mp-kuaishou"; - - Vue.mixin({ - beforeCreate () { - if (!this.$options.mpType) { - return - } - - this.mpType = this.$options.mpType; - - this.$mp = { - data: {}, - [this.mpType]: this.$options.mpInstance - }; - - this.$scope = this.$options.mpInstance; - - delete this.$options.mpType; - delete this.$options.mpInstance; - if (this.mpType === 'page' && typeof getApp === 'function') { // hack vue-i18n - const app = getApp(); - if (app.$vm && app.$vm.$i18n) { - this._i18n = app.$vm.$i18n; - } - } - if (this.mpType !== 'app') { - initRefs(this); - initMocks(this, mocks); - } - } - }); - - const appOptions = { - onLaunch (args) { - if (this.$vm) { // 已经初始化过了,主要是为了百度,百度 onShow 在 onLaunch 之前 - return - } - - this.$vm = vm; - - this.$vm.$mp = { - app: this - }; - - this.$vm.$scope = this; - // vm 上也挂载 globalData - this.$vm.globalData = this.globalData; - - this.$vm._isMounted = true; - this.$vm.__call_hook('mounted', args); - - this.$vm.__call_hook('onLaunch', args); - } - }; - - // 兼容旧版本 globalData - appOptions.globalData = vm.$options.globalData || {}; - // 将 methods 中的方法挂在 getApp() 中 - const methods = vm.$options.methods; - if (methods) { - Object.keys(methods).forEach(name => { - appOptions[name] = methods[name]; - }); - } - - initAppLocale(Vue, vm, ks.getSystemInfoSync().language || 'zh-Hans'); - - initHooks(appOptions, hooks); - - return appOptions + Vue.prototype.mpHost = "mp-kuaishou"; + + Vue.mixin({ + beforeCreate () { + if (!this.$options.mpType) { + return + } + + this.mpType = this.$options.mpType; + + this.$mp = { + data: {}, + [this.mpType]: this.$options.mpInstance + }; + + this.$scope = this.$options.mpInstance; + + delete this.$options.mpType; + delete this.$options.mpInstance; + if (this.mpType === 'page' && typeof getApp === 'function') { // hack vue-i18n + const app = getApp(); + if (app.$vm && app.$vm.$i18n) { + this._i18n = app.$vm.$i18n; + } + } + if (this.mpType !== 'app') { + initRefs(this); + initMocks(this, mocks); + } + } + }); + + const appOptions = { + onLaunch (args) { + if (this.$vm) { // 已经初始化过了,主要是为了百度,百度 onShow 在 onLaunch 之前 + return + } + + this.$vm = vm; + + this.$vm.$mp = { + app: this + }; + + this.$vm.$scope = this; + // vm 上也挂载 globalData + this.$vm.globalData = this.globalData; + + this.$vm._isMounted = true; + this.$vm.__call_hook('mounted', args); + + this.$vm.__call_hook('onLaunch', args); + } + }; + + // 兼容旧版本 globalData + appOptions.globalData = vm.$options.globalData || {}; + // 将 methods 中的方法挂在 getApp() 中 + const methods = vm.$options.methods; + if (methods) { + Object.keys(methods).forEach(name => { + appOptions[name] = methods[name]; + }); + } + + initAppLocale(Vue, vm, normalizeLocale(ks.getSystemInfoSync().language) || LOCALE_EN); + + initHooks(appOptions, hooks); + initUnknownHooks(appOptions, vm.$options); + + return appOptions } const mocks = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__']; @@ -2096,42 +2314,42 @@ function parseComponent (vueComponentOptions) { }) } -/** - * 用于延迟调用 setData - * 在 setData 真实调用的时机需执行 fixSetDataEnd - * @param {*} mpInstance - */ -function fixSetDataStart (mpInstance) { - const setData = mpInstance.setData; - const setDataArgs = []; - mpInstance.setData = function () { - setDataArgs.push(arguments); - }; - mpInstance.__fixInitData = function () { - this.setData = setData; - const fn = () => { - setDataArgs.forEach(args => { - setData.apply(this, args); - }); - }; - if (setDataArgs.length) { - if (this.groupSetData) { - this.groupSetData(fn); - } else { - fn(); - } - } - }; -} -/** - * 恢复真实的 setData 方法 - * @param {*} mpInstance - */ -function fixSetDataEnd (mpInstance) { - if (mpInstance.__fixInitData) { - mpInstance.__fixInitData(); - delete mpInstance.__fixInitData; - } +/** + * 用于延迟调用 setData + * 在 setData 真实调用的时机需执行 fixSetDataEnd + * @param {*} mpInstance + */ +function fixSetDataStart (mpInstance) { + const setData = mpInstance.setData; + const setDataArgs = []; + mpInstance.setData = function () { + setDataArgs.push(arguments); + }; + mpInstance.__fixInitData = function () { + this.setData = setData; + const fn = () => { + setDataArgs.forEach(args => { + setData.apply(this, args); + }); + }; + if (setDataArgs.length) { + if (this.groupSetData) { + this.groupSetData(fn); + } else { + fn(); + } + } + }; +} +/** + * 恢复真实的 setData 方法 + * @param {*} mpInstance + */ +function fixSetDataEnd (mpInstance) { + if (mpInstance.__fixInitData) { + mpInstance.__fixInitData(); + delete mpInstance.__fixInitData; + } } function parseComponent$1 (vueComponentOptions) { @@ -2166,6 +2384,7 @@ function parseBasePage (vuePageOptions, { const pageOptions = parseComponent$1(vuePageOptions); initHooks(pageOptions.methods, hooks$1, vuePageOptions); + initUnknownHooks(pageOptions.methods, vuePageOptions); pageOptions.methods.onLoad = function (query) { this.options = query; @@ -2192,10 +2411,10 @@ function parsePage$1 (vuePageOptions) { return parsePage(vuePageOptions) } -function createPage (vuePageOptions) { - { - return Component(parsePage$1(vuePageOptions)) - } +function createPage (vuePageOptions) { + { + return Component(parsePage$1(vuePageOptions)) + } } function createComponent (vueOptions) { @@ -2240,23 +2459,23 @@ function createSubpackageApp (vm) { return vm } -function createPlugin (vm) { - const appOptions = parseApp$1(vm); - if (isFn(appOptions.onShow) && ks.onAppShow) { - ks.onAppShow((...args) => { - vm.__call_hook('onShow', args); - }); - } - if (isFn(appOptions.onHide) && ks.onAppHide) { - ks.onAppHide((...args) => { - vm.__call_hook('onHide', args); - }); - } - if (isFn(appOptions.onLaunch)) { - const args = ks.getLaunchOptionsSync && ks.getLaunchOptionsSync(); - vm.__call_hook('onLaunch', args); - } - return vm +function createPlugin (vm) { + const appOptions = parseApp$1(vm); + if (isFn(appOptions.onShow) && ks.onAppShow) { + ks.onAppShow((...args) => { + vm.__call_hook('onShow', args); + }); + } + if (isFn(appOptions.onHide) && ks.onAppHide) { + ks.onAppHide((...args) => { + vm.__call_hook('onHide', args); + }); + } + if (isFn(appOptions.onLaunch)) { + const args = ks.getLaunchOptionsSync && ks.getLaunchOptionsSync(); + vm.__call_hook('onLaunch', args); + } + return vm } todos.forEach(todoApi => { @@ -2296,7 +2515,7 @@ if (typeof Proxy !== 'undefined' && "mp-kuaishou" !== 'app-plus') { if (eventApi[name]) { return eventApi[name] } - if (!hasOwn(ks, name) && !hasOwn(protocols, name)) { + if (typeof ks[name] !== 'function' && !hasOwn(protocols, name)) { return } return promisify(name, wrapper(name, ks[name])) diff --git a/src/platforms/mp-kuaishou/runtime/api/protocols.js b/src/platforms/mp-kuaishou/runtime/api/protocols.js index fd596f57ee81d449adf33a95c783a2358c07d688..e45cc3de4f97522b4ef34172856b7eda1ff62d2c 100644 --- a/src/platforms/mp-kuaishou/runtime/api/protocols.js +++ b/src/platforms/mp-kuaishou/runtime/api/protocols.js @@ -10,7 +10,16 @@ export const protocols = { previewImage, getSystemInfo, getSystemInfoSync: getSystemInfo, - getUserProfile + getUserProfile, + requestPayment: { + name: ks.pay ? 'pay' : 'requestPayment', + args(fromArgs) { + if (typeof fromArgs === 'object') { + // ks.pay 服务类型 id(固定值为 '1') + if (ks.pay && !fromArgs.serviceId) fromArgs.serviceId = '1' + } + } + } } export const todos = [ 'vibrate'