diff --git a/packages/uni-mp-kuaishou/dist/index.js b/packages/uni-mp-kuaishou/dist/index.js index 22578bf2b36bb50d8a79c124db5d9b593640843d..5a5bcc306b725ed37dbba050893eb20a679ee976 100644 --- a/packages/uni-mp-kuaishou/dist/index.js +++ b/packages/uni-mp-kuaishou/dist/index.js @@ -192,7 +192,7 @@ function queue (hooks, data) { } if (res === false) { return { - then () {} + then () { } } } } @@ -240,15 +240,15 @@ function getApiInterceptorHooks (method) { if (hook !== 'returnValue') { interceptor[hook] = globalInterceptors[hook].slice(); } - }); - const scopedInterceptor = scopedInterceptors[method]; - if (scopedInterceptor) { - Object.keys(scopedInterceptor).forEach(hook => { - if (hook !== 'returnValue') { - interceptor[hook] = (interceptor[hook] || []).concat(scopedInterceptor[hook]); - } - }); - } + }); + const scopedInterceptor = scopedInterceptors[method]; + if (scopedInterceptor) { + Object.keys(scopedInterceptor).forEach(hook => { + if (hook !== 'returnValue') { + interceptor[hook] = (interceptor[hook] || []).concat(scopedInterceptor[hook]); + } + }); + } return interceptor } @@ -272,10 +272,14 @@ const promiseInterceptor = { if (!isPromise(res)) { return res } - return res.then(res => { - return res[1] - }).catch(res => { - return res[0] + return new Promise((resolve, reject) => { + res.then(res => { + if (res[0]) { + reject(res[0]); + } else { + resolve(res[1]); + } + }); }) } }; @@ -1803,8 +1807,59 @@ 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; + } +} + function parseComponent$1 (vueComponentOptions) { - return parseComponent(vueComponentOptions) + const componentOptions = parseComponent(vueComponentOptions); + const oldAttached = componentOptions.lifetimes.attached; + componentOptions.lifetimes.attached = function attached () { + // 暂不区分版本 + if (isPage.call(this)) { + // 解决快手小程序页面 attached 生命周期 setData 导致数据同步异常的问题 + fixSetDataStart(this); + setTimeout(() => { + fixSetDataEnd(this); + }, 0); + } + oldAttached.call(this); + }; + return componentOptions } const hooks$1 = [ diff --git a/packages/uni-mp-kuaishou/dist/uni.api.esm.js b/packages/uni-mp-kuaishou/dist/uni.api.esm.js new file mode 100644 index 0000000000000000000000000000000000000000..a1d2da6ccb1188e0738edc5b2f45dbfb661b0cc3 --- /dev/null +++ b/packages/uni-mp-kuaishou/dist/uni.api.esm.js @@ -0,0 +1,845 @@ +import { isArray, hasOwn, isString, isPlainObject, isObject, capitalize, toRawType, makeMap, isPromise, isFunction, extend } from '@vue/shared'; + +const eventChannels = {}; +const eventChannelStack = []; +let id = 0; +function initEventChannel(events, cache = true) { + id++; + const eventChannel = new ks.EventChannel(id, events); + if (cache) { + eventChannels[id] = eventChannel; + eventChannelStack.push(eventChannel); + } + return eventChannel; +} +function getEventChannel(id) { + if (id) { + const eventChannel = eventChannels[id]; + delete eventChannels[id]; + return eventChannel; + } + return eventChannelStack.shift(); +} +const navigateTo = { + args(fromArgs) { + const id = initEventChannel(fromArgs.events).id; + if (fromArgs.url) { + fromArgs.url = + fromArgs.url + + (fromArgs.url.indexOf('?') === -1 ? '?' : '&') + + '__id__=' + + id; + } + }, + returnValue(fromRes) { + fromRes.eventChannel = getEventChannel(); + }, +}; + +function getBaseSystemInfo() { + return ks.getSystemInfoSync() +} + +function validateProtocolFail(name, msg) { + console.warn(`${name}: ${msg}`); +} +function validateProtocol(name, data, protocol, onFail) { + if (!onFail) { + onFail = validateProtocolFail; + } + for (const key in protocol) { + const errMsg = validateProp(key, data[key], protocol[key], !hasOwn(data, key)); + if (isString(errMsg)) { + onFail(name, errMsg); + } + } +} +function validateProtocols(name, args, protocol, onFail) { + if (!protocol) { + return; + } + if (!isArray(protocol)) { + return validateProtocol(name, args[0] || Object.create(null), protocol, onFail); + } + const len = protocol.length; + const argsLen = args.length; + for (let i = 0; i < len; i++) { + const opts = protocol[i]; + const data = Object.create(null); + if (argsLen > i) { + data[opts.name] = args[i]; + } + validateProtocol(name, data, { [opts.name]: opts }, onFail); + } +} +function validateProp(name, value, prop, isAbsent) { + if (!isPlainObject(prop)) { + prop = { type: prop }; + } + const { type, required, validator } = prop; + // required! + if (required && isAbsent) { + return 'Missing required args: "' + name + '"'; + } + // missing but optional + if (value == null && !required) { + return; + } + // type check + if (type != null) { + let isValid = false; + const types = isArray(type) ? type : [type]; + const expectedTypes = []; + // value is valid as long as one of the specified types match + for (let i = 0; i < types.length && !isValid; i++) { + const { valid, expectedType } = assertType(value, types[i]); + expectedTypes.push(expectedType || ''); + isValid = valid; + } + if (!isValid) { + return getInvalidTypeMessage(name, value, expectedTypes); + } + } + // custom validator + if (validator) { + return validator(value); + } +} +const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol'); +function assertType(value, type) { + let valid; + const expectedType = getType(type); + if (isSimpleType(expectedType)) { + const t = typeof value; + valid = t === expectedType.toLowerCase(); + // for primitive wrapper objects + if (!valid && t === 'object') { + valid = value instanceof type; + } + } + else if (expectedType === 'Object') { + valid = isObject(value); + } + else if (expectedType === 'Array') { + valid = isArray(value); + } + else { + { + valid = value instanceof type; + } + } + return { + valid, + expectedType, + }; +} +function getInvalidTypeMessage(name, value, expectedTypes) { + let message = `Invalid args: type check failed for args "${name}".` + + ` Expected ${expectedTypes.map(capitalize).join(', ')}`; + const expectedType = expectedTypes[0]; + const receivedType = toRawType(value); + const expectedValue = styleValue(value, expectedType); + const receivedValue = styleValue(value, receivedType); + // check if we need to specify expected value + if (expectedTypes.length === 1 && + isExplicable(expectedType) && + !isBoolean(expectedType, receivedType)) { + message += ` with value ${expectedValue}`; + } + message += `, got ${receivedType} `; + // check if we need to specify received value + if (isExplicable(receivedType)) { + message += `with value ${receivedValue}.`; + } + return message; +} +function getType(ctor) { + const match = ctor && ctor.toString().match(/^\s*function (\w+)/); + return match ? match[1] : ''; +} +function styleValue(value, type) { + if (type === 'String') { + return `"${value}"`; + } + else if (type === 'Number') { + return `${Number(value)}`; + } + else { + return `${value}`; + } +} +function isExplicable(type) { + const explicitTypes = ['string', 'number', 'boolean']; + return explicitTypes.some((elem) => type.toLowerCase() === elem); +} +function isBoolean(...args) { + return args.some((elem) => elem.toLowerCase() === 'boolean'); +} + +const HOOK_SUCCESS = 'success'; +const HOOK_FAIL = 'fail'; +const HOOK_COMPLETE = 'complete'; +const globalInterceptors = {}; +const scopedInterceptors = {}; +function wrapperHook(hook) { + return function (data) { + return hook(data) || data; + }; +} +function queue(hooks, data) { + let promise = false; + for (let i = 0; i < hooks.length; i++) { + const hook = hooks[i]; + if (promise) { + promise = Promise.resolve(wrapperHook(hook)); + } + else { + const res = hook(data); + if (isPromise(res)) { + promise = Promise.resolve(res); + } + if (res === false) { + return { + then() { }, + catch() { }, + }; + } + } + } + return (promise || { + then(callback) { + return callback(data); + }, + catch() { }, + }); +} +function wrapperOptions(interceptors, options = {}) { + [HOOK_SUCCESS, HOOK_FAIL, HOOK_COMPLETE].forEach((name) => { + const hooks = interceptors[name]; + if (!isArray(hooks)) { + return; + } + const oldCallback = options[name]; + options[name] = function callbackInterceptor(res) { + queue(hooks, res).then((res) => { + return (isFunction(oldCallback) && oldCallback(res)) || res; + }); + }; + }); + return options; +} +function wrapperReturnValue(method, returnValue) { + const returnValueHooks = []; + if (isArray(globalInterceptors.returnValue)) { + returnValueHooks.push(...globalInterceptors.returnValue); + } + const interceptor = scopedInterceptors[method]; + if (interceptor && isArray(interceptor.returnValue)) { + returnValueHooks.push(...interceptor.returnValue); + } + returnValueHooks.forEach((hook) => { + returnValue = hook(returnValue) || returnValue; + }); + return returnValue; +} +function getApiInterceptorHooks(method) { + const interceptor = Object.create(null); + Object.keys(globalInterceptors).forEach((hook) => { + if (hook !== 'returnValue') { + interceptor[hook] = globalInterceptors[hook].slice(); + } + }); + const scopedInterceptor = scopedInterceptors[method]; + if (scopedInterceptor) { + Object.keys(scopedInterceptor).forEach((hook) => { + if (hook !== 'returnValue') { + interceptor[hook] = (interceptor[hook] || []).concat(scopedInterceptor[hook]); + } + }); + } + return interceptor; +} +function invokeApi(method, api, options, ...params) { + const interceptor = getApiInterceptorHooks(method); + if (interceptor && Object.keys(interceptor).length) { + if (isArray(interceptor.invoke)) { + const res = queue(interceptor.invoke, options); + return res.then((options) => { + return api(wrapperOptions(interceptor, options), ...params); + }); + } + else { + return api(wrapperOptions(interceptor, options), ...params); + } + } + return api(options, ...params); +} + +function handlePromise(promise) { + if (__UNI_FEATURE_PROMISE__) { + return promise + .then((data) => { + return [null, data]; + }) + .catch((err) => [err]); + } + return promise; +} + +function formatApiArgs(args, options) { + const params = args[0]; + if (!options || + (!isPlainObject(options.formatArgs) && isPlainObject(params))) { + return; + } + const formatArgs = options.formatArgs; + const keys = Object.keys(formatArgs); + for (let i = 0; i < keys.length; i++) { + const name = keys[i]; + const formatterOrDefaultValue = formatArgs[name]; + if (isFunction(formatterOrDefaultValue)) { + const errMsg = formatterOrDefaultValue(args[0][name], params); + if (isString(errMsg)) { + return errMsg; + } + } + else { + // defaultValue + if (!hasOwn(params, name)) { + params[name] = formatterOrDefaultValue; + } + } + } +} +function beforeInvokeApi(name, args, protocol, options) { + if ((process.env.NODE_ENV !== 'production')) { + validateProtocols(name, args, protocol); + } + if (options && options.beforeInvoke) { + const errMsg = options.beforeInvoke(args); + if (isString(errMsg)) { + return errMsg; + } + } + const errMsg = formatApiArgs(args, options); + if (errMsg) { + return errMsg; + } +} +function wrapperSyncApi(name, fn, protocol, options) { + return (...args) => { + const errMsg = beforeInvokeApi(name, args, protocol, options); + if (errMsg) { + throw new Error(errMsg); + } + return fn.apply(null, args); + }; +} +function defineSyncApi(name, fn, protocol, options) { + return wrapperSyncApi(name, fn, (process.env.NODE_ENV !== 'production') ? protocol : undefined, options); +} + +const API_UPX2PX = 'upx2px'; +const Upx2pxProtocol = [ + { + name: 'upx', + type: [Number, String], + required: true, + }, +]; + +const EPS = 1e-4; +const BASE_DEVICE_WIDTH = 750; +let isIOS = false; +let deviceWidth = 0; +let deviceDPR = 0; +function checkDeviceWidth() { + const { platform, pixelRatio, windowWidth } = getBaseSystemInfo(); + deviceWidth = windowWidth; + deviceDPR = pixelRatio; + isIOS = platform === 'ios'; +} +const upx2px = defineSyncApi(API_UPX2PX, (number, newDeviceWidth) => { + if (deviceWidth === 0) { + checkDeviceWidth(); + } + number = Number(number); + if (number === 0) { + return 0; + } + let width = newDeviceWidth || deviceWidth; + let result = (number / BASE_DEVICE_WIDTH) * width; + if (result < 0) { + result = -result; + } + result = Math.floor(result + EPS); + if (result === 0) { + if (deviceDPR === 1 || !isIOS) { + result = 1; + } + else { + result = 0.5; + } + } + return number < 0 ? -result : result; +}, Upx2pxProtocol); + +const API_ADD_INTERCEPTOR = 'addInterceptor'; +const API_REMOVE_INTERCEPTOR = 'removeInterceptor'; +const AddInterceptorProtocol = [ + { + name: 'method', + type: [String, Object], + required: true, + }, +]; +const RemoveInterceptorProtocol = AddInterceptorProtocol; + +function mergeInterceptorHook(interceptors, interceptor) { + Object.keys(interceptor).forEach((hook) => { + if (isFunction(interceptor[hook])) { + interceptors[hook] = mergeHook(interceptors[hook], interceptor[hook]); + } + }); +} +function removeInterceptorHook(interceptors, interceptor) { + if (!interceptors || !interceptor) { + return; + } + Object.keys(interceptor).forEach((hook) => { + if (isFunction(interceptor[hook])) { + removeHook(interceptors[hook], interceptor[hook]); + } + }); +} +function mergeHook(parentVal, childVal) { + const res = childVal + ? parentVal + ? parentVal.concat(childVal) + : isArray(childVal) + ? childVal + : [childVal] + : parentVal; + return res ? dedupeHooks(res) : res; +} +function dedupeHooks(hooks) { + const res = []; + for (let i = 0; i < hooks.length; i++) { + if (res.indexOf(hooks[i]) === -1) { + res.push(hooks[i]); + } + } + return res; +} +function removeHook(hooks, hook) { + if (!hooks) { + return; + } + const index = hooks.indexOf(hook); + if (index !== -1) { + hooks.splice(index, 1); + } +} +const addInterceptor = defineSyncApi(API_ADD_INTERCEPTOR, (method, interceptor) => { + if (typeof method === 'string' && isPlainObject(interceptor)) { + mergeInterceptorHook(scopedInterceptors[method] || (scopedInterceptors[method] = {}), interceptor); + } + else if (isPlainObject(method)) { + mergeInterceptorHook(globalInterceptors, method); + } +}, AddInterceptorProtocol); +const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interceptor) => { + if (typeof method === 'string') { + if (isPlainObject(interceptor)) { + removeInterceptorHook(scopedInterceptors[method], interceptor); + } + else { + delete scopedInterceptors[method]; + } + } + else if (isPlainObject(method)) { + removeInterceptorHook(globalInterceptors, method); + } +}, RemoveInterceptorProtocol); + +const API_ON = '$on'; +const OnProtocol = [ + { + name: 'event', + type: String, + required: true, + }, + { + name: 'callback', + type: Function, + required: true, + }, +]; +const API_ONCE = '$once'; +const OnceProtocol = OnProtocol; +const API_OFF = '$off'; +const OffProtocol = [ + { + name: 'event', + type: [String, Array], + }, + { + name: 'callback', + type: Function, + }, +]; +const API_EMIT = '$emit'; +const EmitProtocol = [ + { + name: 'event', + type: String, + required: true, + }, +]; + +const E = function () { + // Keep this empty so it's easier to inherit from + // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) +}; +E.prototype = { + on: function (name, callback, ctx) { + var e = this.e || (this.e = {}); + (e[name] || (e[name] = [])).push({ + fn: callback, + ctx: ctx, + }); + return this; + }, + once: function (name, callback, ctx) { + var self = this; + function listener() { + self.off(name, listener); + callback.apply(ctx, arguments); + } + listener._ = callback; + return this.on(name, listener, ctx); + }, + emit: function (name) { + var data = [].slice.call(arguments, 1); + var evtArr = ((this.e || (this.e = {}))[name] || []).slice(); + var i = 0; + var len = evtArr.length; + for (i; i < len; i++) { + evtArr[i].fn.apply(evtArr[i].ctx, data); + } + return this; + }, + off: function (name, callback) { + var e = this.e || (this.e = {}); + var evts = e[name]; + var liveEvents = []; + if (evts && callback) { + for (var i = 0, len = evts.length; i < len; i++) { + if (evts[i].fn !== callback && evts[i].fn._ !== callback) + liveEvents.push(evts[i]); + } + } + // Remove event from queue to prevent memory leak + // Suggested by https://github.com/lazd + // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910 + liveEvents.length ? (e[name] = liveEvents) : delete e[name]; + return this; + }, +}; +var Emitter = E; + +const emitter = new Emitter(); +const $on = defineSyncApi(API_ON, (name, callback) => { + emitter.on(name, callback); + return () => emitter.off(name, callback); +}, OnProtocol); +const $once = defineSyncApi(API_ONCE, (name, callback) => { + emitter.once(name, callback); + return () => emitter.off(name, callback); +}, OnceProtocol); +const $off = defineSyncApi(API_OFF, (name, callback) => { + if (!name) { + emitter.e = {}; + return; + } + if (!Array.isArray(name)) + name = [name]; + name.forEach((n) => emitter.off(n, callback)); +}, OffProtocol); +const $emit = defineSyncApi(API_EMIT, (name, ...args) => { + emitter.emit(name, ...args); +}, EmitProtocol); + +const SYNC_API_RE = /^\$|sendNativeEvent|restoreGlobal|getCurrentSubNVue|getMenuButtonBoundingClientRect|^report|interceptors|Interceptor$|getSubNVueById|requireNativePlugin|upx2px|hideKeyboard|canIUse|^create|Sync$|Manager$|base64ToArrayBuffer|arrayBufferToBase64/; +const CONTEXT_API_RE = /^create|Manager$/; +// Context例外情况 +const CONTEXT_API_RE_EXC = ['createBLEConnection']; +// 同步例外情况 +const ASYNC_API = ['createBLEConnection']; +const CALLBACK_API_RE = /^on|^off/; +function isContextApi(name) { + return CONTEXT_API_RE.test(name) && CONTEXT_API_RE_EXC.indexOf(name) === -1; +} +function isSyncApi(name) { + return SYNC_API_RE.test(name) && ASYNC_API.indexOf(name) === -1; +} +function isCallbackApi(name) { + return CALLBACK_API_RE.test(name) && name !== 'onPush'; +} +function shouldPromise(name) { + if (isContextApi(name) || isSyncApi(name) || isCallbackApi(name)) { + return false; + } + return true; +} +/* eslint-disable no-extend-native */ +if (!Promise.prototype.finally) { + Promise.prototype.finally = function (onfinally) { + const promise = this.constructor; + return this.then((value) => promise.resolve(onfinally && onfinally()).then(() => value), (reason) => promise.resolve(onfinally && onfinally()).then(() => { + throw reason; + })); + }; +} +function promisify(name, api) { + if (!shouldPromise(name)) { + return api; + } + if (!isFunction(api)) { + return api; + } + return function promiseApi(options = {}) { + if (isFunction(options.success) || + isFunction(options.fail) || + isFunction(options.complete)) { + return wrapperReturnValue(name, invokeApi(name, api, options)); + } + return wrapperReturnValue(name, handlePromise(new Promise((resolve, reject) => { + invokeApi(name, api, extend({}, options, { + success: resolve, + fail: reject, + })); + }))); + }; +} + +const CALLBACKS = ['success', 'fail', 'cancel', 'complete']; +function initWrapper(protocols) { + function processCallback(methodName, method, returnValue) { + return function (res) { + return method(processReturnValue(methodName, res, returnValue)); + }; + } + function processArgs(methodName, fromArgs, argsOption = {}, returnValue = {}, keepFromArgs = false) { + if (isPlainObject(fromArgs)) { + // 一般 api 的参数解析 + const toArgs = (keepFromArgs === true ? fromArgs : {}); // returnValue 为 false 时,说明是格式化返回值,直接在返回值对象上修改赋值 + if (isFunction(argsOption)) { + argsOption = argsOption(fromArgs, toArgs) || {}; + } + for (const key in fromArgs) { + if (hasOwn(argsOption, key)) { + let keyOption = argsOption[key]; + if (isFunction(keyOption)) { + keyOption = keyOption(fromArgs[key], fromArgs, toArgs); + } + if (!keyOption) { + // 不支持的参数 + console.warn(`快手小程序 ${methodName} 暂不支持 ${key}`); + } + else if (isString(keyOption)) { + // 重写参数 key + toArgs[keyOption] = fromArgs[key]; + } + else if (isPlainObject(keyOption)) { + // {name:newName,value:value}可重新指定参数 key:value + toArgs[keyOption.name ? keyOption.name : key] = keyOption.value; + } + } + else if (CALLBACKS.indexOf(key) !== -1) { + const callback = fromArgs[key]; + if (isFunction(callback)) { + toArgs[key] = processCallback(methodName, callback, returnValue); + } + } + else { + if (!keepFromArgs && !hasOwn(toArgs, key)) { + toArgs[key] = fromArgs[key]; + } + } + } + return toArgs; + } + else if (isFunction(fromArgs)) { + fromArgs = processCallback(methodName, fromArgs, returnValue); + } + return fromArgs; + } + function processReturnValue(methodName, res, returnValue, keepReturnValue = false) { + if (isFunction(protocols.returnValue)) { + // 处理通用 returnValue + res = protocols.returnValue(methodName, res); + } + return processArgs(methodName, res, returnValue, {}, keepReturnValue); + } + return function wrapper(methodName, method) { + if (!hasOwn(protocols, methodName)) { + return method; + } + const protocol = protocols[methodName]; + if (!protocol) { + // 暂不支持的 api + return function () { + console.error(`快手小程序 暂不支持${methodName}`); + }; + } + return function (arg1, arg2) { + // 目前 api 最多两个参数 + let options = protocol; + if (isFunction(protocol)) { + options = protocol(arg1); + } + arg1 = processArgs(methodName, arg1, options.args, options.returnValue); + const args = [arg1]; + if (typeof arg2 !== 'undefined') { + args.push(arg2); + } + const returnValue = ks[options.name || methodName].apply(ks, args); + if (isSyncApi(methodName)) { + // 同步 api + return processReturnValue(methodName, returnValue, options.returnValue, isContextApi(methodName)); + } + return returnValue; + }; + }; +} + +const baseApis = { + $on, + $off, + $once, + $emit, + upx2px, + addInterceptor, + removeInterceptor, +}; +function initUni(api, protocols) { + const wrapper = initWrapper(protocols); + const UniProxyHandlers = { + get(target, key) { + if (hasOwn(target, key)) { + return target[key]; + } + if (hasOwn(api, key)) { + return promisify(key, api[key]); + } + if (hasOwn(baseApis, key)) { + return promisify(key, baseApis[key]); + } + // event-api + // provider-api? + return promisify(key, wrapper(key, ks[key])); + }, + }; + return new Proxy({}, UniProxyHandlers); +} + +function initGetProvider(providers) { + return function getProvider({ service, success, fail, complete, }) { + let res; + if (providers[service]) { + res = { + errMsg: 'getProvider:ok', + service, + provider: providers[service], + }; + isFunction(success) && success(res); + } + else { + res = { + errMsg: 'getProvider:fail:服务[' + service + ']不存在', + }; + isFunction(fail) && fail(res); + } + isFunction(complete) && complete(res); + }; +} + +function addSafeAreaInsets(fromRes, toRes) { + if (fromRes.safeArea) { + const safeArea = fromRes.safeArea; + toRes.safeAreaInsets = { + top: safeArea.top, + left: safeArea.left, + right: fromRes.windowWidth - safeArea.right, + bottom: fromRes.windowHeight - safeArea.bottom, + }; + } +} + +const getSystemInfo = { + returnValue: addSafeAreaInsets, +}; + +const getSystemInfoSync = getSystemInfo; + +const redirectTo = {}; + +const previewImage = { + args(fromArgs, toArgs) { + let currentIndex = parseInt(fromArgs.current); + if (isNaN(currentIndex)) { + return; + } + const urls = fromArgs.urls; + if (!isArray(urls)) { + return; + } + const len = urls.length; + if (!len) { + return; + } + if (currentIndex < 0) { + currentIndex = 0; + } + else if (currentIndex >= len) { + currentIndex = len - 1; + } + if (currentIndex > 0) { + toArgs.current = urls[currentIndex]; + toArgs.urls = urls.filter((item, index) => index < currentIndex ? item !== urls[currentIndex] : true); + } + else { + toArgs.current = urls[0]; + } + return { + indicator: false, + loop: false, + }; + }, +}; + +const getProvider = initGetProvider({ + oauth: ['kuaishou'], + share: ['kuaishou'], + payment: ['kuaishoupay'], + push: ['kuaishou'], +}); + +var shims = /*#__PURE__*/Object.freeze({ + __proto__: null, + getProvider: getProvider +}); + +var protocols = /*#__PURE__*/Object.freeze({ + __proto__: null, + redirectTo: redirectTo, + navigateTo: navigateTo, + previewImage: previewImage, + getSystemInfo: getSystemInfo, + getSystemInfoSync: getSystemInfoSync +}); + +var index = initUni(shims, protocols); + +export { index as default }; diff --git a/packages/uni-mp-kuaishou/dist/uni.mp.esm.js b/packages/uni-mp-kuaishou/dist/uni.mp.esm.js new file mode 100644 index 0000000000000000000000000000000000000000..ac16bd244bd821cd83e309df7d465fc218d42b06 --- /dev/null +++ b/packages/uni-mp-kuaishou/dist/uni.mp.esm.js @@ -0,0 +1,1231 @@ +import { isPlainObject, hasOwn, isArray, extend, hyphenate, isObject, toNumber, isFunction, NOOP, camelize } from '@vue/shared'; + +const encode = encodeURIComponent; +function stringifyQuery(obj, encodeStr = encode) { + const res = obj + ? Object.keys(obj) + .map((key) => { + let val = obj[key]; + if (typeof val === undefined || val === null) { + val = ''; + } + else if (isPlainObject(val)) { + val = JSON.stringify(val); + } + return encodeStr(key) + '=' + encodeStr(val); + }) + .filter((x) => x.length > 0) + .join('&') + : null; + return res ? `?${res}` : ''; +} + +function cache(fn) { + const cache = Object.create(null); + return (str) => { + const hit = cache[str]; + return hit || (cache[str] = fn(str)); + }; +} +const invokeArrayFns = (fns, arg) => { + let ret; + for (let i = 0; i < fns.length; i++) { + ret = fns[i](arg); + } + return ret; +}; +// lifecycle +// App and Page +const ON_SHOW = 'onShow'; +const ON_HIDE = 'onHide'; +//App +const ON_LAUNCH = 'onLaunch'; +const ON_ERROR = 'onError'; +const ON_THEME_CHANGE = 'onThemeChange'; +const ON_PAGE_NOT_FOUND = 'onPageNotFound'; +const ON_UNHANDLE_REJECTION = 'onUnhandledRejection'; +//Page +const ON_LOAD = 'onLoad'; +const ON_READY = 'onReady'; +const ON_UNLOAD = 'onUnload'; +const ON_RESIZE = 'onResize'; +const ON_TAB_ITEM_TAP = 'onTabItemTap'; +const ON_REACH_BOTTOM = 'onReachBottom'; +const ON_PULL_DOWN_REFRESH = 'onPullDownRefresh'; +const ON_ADD_TO_FAVORITES = 'onAddToFavorites'; + +class EventChannel { + constructor(id, events) { + this.id = id; + this.listener = {}; + this.emitCache = {}; + if (events) { + Object.keys(events).forEach((name) => { + this.on(name, events[name]); + }); + } + } + emit(eventName, ...args) { + const fns = this.listener[eventName]; + if (!fns) { + return (this.emitCache[eventName] || (this.emitCache[eventName] = [])).push(args); + } + fns.forEach((opt) => { + opt.fn.apply(opt.fn, args); + }); + this.listener[eventName] = fns.filter((opt) => opt.type !== 'once'); + } + on(eventName, fn) { + this._addListener(eventName, 'on', fn); + this._clearCache(eventName); + } + once(eventName, fn) { + this._addListener(eventName, 'once', fn); + this._clearCache(eventName); + } + off(eventName, fn) { + const fns = this.listener[eventName]; + if (!fns) { + return; + } + if (fn) { + for (let i = 0; i < fns.length;) { + if (fns[i].fn === fn) { + fns.splice(i, 1); + i--; + } + i++; + } + } + else { + delete this.listener[eventName]; + } + } + _clearCache(eventName) { + const cacheArgs = this.emitCache[eventName]; + if (cacheArgs) { + for (; cacheArgs.length > 0;) { + this.emit.apply(this, [eventName, ...cacheArgs.shift()]); + } + } + } + _addListener(eventName, type, fn) { + (this.listener[eventName] || (this.listener[eventName] = [])).push({ + fn, + type, + }); + } +} + +const eventChannels = {}; +const eventChannelStack = []; +function getEventChannel(id) { + if (id) { + const eventChannel = eventChannels[id]; + delete eventChannels[id]; + return eventChannel; + } + return eventChannelStack.shift(); +} + +function initBehavior(options) { + return Behavior(options); +} +function initVueIds(vueIds, mpInstance) { + if (!vueIds) { + return; + } + const ids = vueIds.split(','); + const len = ids.length; + if (len === 1) { + mpInstance._$vueId = ids[0]; + } + else if (len === 2) { + mpInstance._$vueId = ids[0]; + mpInstance._$vuePid = ids[1]; + } +} +const EXTRAS = ['externalClasses']; +function initExtraOptions(miniProgramComponentOptions, vueOptions) { + EXTRAS.forEach((name) => { + if (hasOwn(vueOptions, name)) { + miniProgramComponentOptions[name] = vueOptions[name]; + } + }); +} +function initWxsCallMethods(methods, wxsCallMethods) { + if (!isArray(wxsCallMethods)) { + return; + } + wxsCallMethods.forEach((callMethod) => { + methods[callMethod] = function (args) { + return this.$vm[callMethod](args); + }; + }); +} +function selectAllComponents(mpInstance, selector, $refs) { + const components = mpInstance.selectAllComponents(selector); + components.forEach((component) => { + const ref = component.dataset.ref; + $refs[ref] = component.$vm || component; + }); +} +function initRefs(instance, mpInstance) { + Object.defineProperty(instance, 'refs', { + get() { + const $refs = {}; + selectAllComponents(mpInstance, '.vue-ref', $refs); + const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for'); + forComponents.forEach((component) => { + const ref = component.dataset.ref; + if (!$refs[ref]) { + $refs[ref] = []; + } + $refs[ref].push(component.$vm || component); + }); + return $refs; + }, + }); +} +function findVmByVueId(instance, vuePid) { + // 标准 vue3 中 没有 $children,定制了内核 + const $children = instance.$children; + // 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200) + for (let i = $children.length - 1; i >= 0; i--) { + const childVm = $children[i]; + if (childVm.$scope._$vueId === vuePid) { + return childVm; + } + } + // 反向递归查找 + let parentVm; + for (let i = $children.length - 1; i >= 0; i--) { + parentVm = findVmByVueId($children[i], vuePid); + if (parentVm) { + return parentVm; + } + } +} +function getTarget(obj, path) { + const parts = path.split('.'); + let key = parts[0]; + if (key.indexOf('__$n') === 0) { + //number index + key = parseInt(key.replace('__$n', '')); + } + if (!obj) { + obj = {}; + } + if (parts.length === 1) { + return obj[key]; + } + return getTarget(obj[key], parts.slice(1).join('.')); +} + +function getValue(dataPath, target) { + return getTarget(target || this, dataPath); +} +function getClass(dynamicClass, staticClass) { + return renderClass(staticClass, dynamicClass); +} +function getStyle(dynamicStyle, staticStyle) { + if (!dynamicStyle && !staticStyle) { + return ''; + } + var dynamicStyleObj = normalizeStyleBinding(dynamicStyle); + var styleObj = staticStyle + ? extend(staticStyle, dynamicStyleObj) + : dynamicStyleObj; + return Object.keys(styleObj) + .map(function (name) { + return hyphenate(name) + ':' + styleObj[name]; + }) + .join(';'); +} +function toObject(arr) { + var res = {}; + for (var i = 0; i < arr.length; i++) { + if (arr[i]) { + extend(res, arr[i]); + } + } + return res; +} +function normalizeStyleBinding(bindingStyle) { + if (Array.isArray(bindingStyle)) { + return toObject(bindingStyle); + } + if (typeof bindingStyle === 'string') { + return parseStyleText(bindingStyle); + } + return bindingStyle; +} +var parseStyleText = cache(function parseStyleText(cssText) { + var res = {}; + var listDelimiter = /;(?![^(]*\))/g; + var propertyDelimiter = /:(.+)/; + cssText.split(listDelimiter).forEach(function (item) { + if (item) { + var tmp = item.split(propertyDelimiter); + tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim()); + } + }); + return res; +}); +function isDef(v) { + return v !== undefined && v !== null; +} +function renderClass(staticClass, dynamicClass) { + if (isDef(staticClass) || isDef(dynamicClass)) { + return concat(staticClass, stringifyClass(dynamicClass)); + } + /* istanbul ignore next */ + return ''; +} +function concat(a, b) { + return a ? (b ? a + ' ' + b : a) : b || ''; +} +function stringifyClass(value) { + if (Array.isArray(value)) { + return stringifyArray(value); + } + if (isObject(value)) { + return stringifyObject(value); + } + if (typeof value === 'string') { + return value; + } + /* istanbul ignore next */ + return ''; +} +function stringifyArray(value) { + var res = ''; + var stringified; + for (var i = 0, l = value.length; i < l; i++) { + if (isDef((stringified = stringifyClass(value[i]))) && stringified !== '') { + if (res) { + res += ' '; + } + res += stringified; + } + } + return res; +} +function stringifyObject(value) { + var res = ''; + for (var key in value) { + if (value[key]) { + if (res) { + res += ' '; + } + res += key; + } + } + return res; +} + +function setModel(target, key, value, modifiers) { + if (isArray(modifiers)) { + if (modifiers.indexOf('trim') !== -1) { + value = value.trim(); + } + if (modifiers.indexOf('number') !== -1) { + value = toNumber(value); + } + } + if (!target) { + target = this; + } + target[key] = value; +} +function setSync(target, key, value) { + if (!target) { + target = this; + } + target[key] = value; +} +function getOrig(data) { + if (isPlainObject(data)) { + return data.$orig || data; + } + return data; +} +function map(val, iteratee) { + let ret, i, l, keys, key; + if (isArray(val)) { + ret = new Array(val.length); + for (i = 0, l = val.length; i < l; i++) { + ret[i] = iteratee(val[i], i); + } + return ret; + } + else if (isObject(val)) { + keys = Object.keys(val); + ret = Object.create(null); + for (i = 0, l = keys.length; i < l; i++) { + key = keys[i]; + ret[key] = iteratee(val[key], key, i); + } + return ret; + } + return []; +} +const MP_METHODS = [ + 'createSelectorQuery', + 'createIntersectionObserver', + 'selectAllComponents', + 'selectComponent', +]; +function createEmitFn(oldEmit, ctx) { + return function emit(event, ...args) { + if (ctx.$scope && event) { + ctx.$scope.triggerEvent(event, { __args__: args }); + } + return oldEmit.apply(this, [event, ...args]); + }; +} +function initBaseInstance(instance, options) { + const ctx = instance.ctx; + // mp + ctx.mpType = options.mpType; // @deprecated + ctx.$mpType = options.mpType; + ctx.$scope = options.mpInstance; + // TODO @deprecated + ctx.$mp = {}; + if (__VUE_OPTIONS_API__) { + ctx._self = {}; + } + // $vm + ctx.$scope.$vm = instance.proxy; + // slots + { + instance.slots = {}; + if (isArray(options.slots) && options.slots.length) { + options.slots.forEach((name) => { + instance.slots[name] = true; + }); + } + } + ctx.getOpenerEventChannel = function () { + if (!this.__eventChannel__) { + this.__eventChannel__ = new EventChannel(); + } + return this.__eventChannel__; + }; + ctx.$hasHook = hasHook; + ctx.$callHook = callHook; + // $emit + instance.emit = createEmitFn(instance.emit, ctx); +} +function initComponentInstance(instance, options) { + initBaseInstance(instance, options); + const ctx = instance.ctx; + MP_METHODS.forEach((method) => { + ctx[method] = function (...args) { + const mpInstance = ctx.$scope; + if (mpInstance && mpInstance[method]) { + return mpInstance[method].apply(mpInstance, args); + } + }; + }); + // TODO other + ctx.__set_model = setModel; + ctx.__set_sync = setSync; + ctx.__get_orig = getOrig; + // TODO + ctx.__get_value = getValue; + ctx.__get_class = getClass; + ctx.__get_style = getStyle; + ctx.__map = map; +} +function initMocks(instance, mpInstance, mocks) { + const ctx = instance.ctx; + mocks.forEach((mock) => { + if (hasOwn(mpInstance, mock)) { + ctx[mock] = mpInstance[mock]; + } + }); +} +function hasHook(name) { + const hooks = this.$[name]; + if (hooks && hooks.length) { + return true; + } + return false; +} +function callHook(name, args) { + if (name === 'mounted') { + callHook.call(this, 'bm'); // beforeMount + this.$.isMounted = true; + name = 'm'; + } + else if (name === 'onLoad' && args && args.__id__) { + this.__eventChannel__ = getEventChannel(args.__id__); + delete args.__id__; + } + const hooks = this.$[name]; + return hooks && invokeArrayFns(hooks, args); +} + +const PAGE_HOOKS = [ + ON_LOAD, + ON_SHOW, + ON_HIDE, + ON_UNLOAD, + ON_RESIZE, + ON_TAB_ITEM_TAP, + ON_REACH_BOTTOM, + ON_PULL_DOWN_REFRESH, + ON_ADD_TO_FAVORITES, + // 'onReady', // lifetimes.ready + // 'onPageScroll', // 影响性能,开发者手动注册 + // 'onShareTimeline', // 右上角菜单,开发者手动注册 + // 'onShareAppMessage' // 右上角菜单,开发者手动注册 +]; +function findHooks(vueOptions, hooks = new Set()) { + if (vueOptions) { + Object.keys(vueOptions).forEach((name) => { + if (name.indexOf('on') === 0 && isFunction(vueOptions[name])) { + hooks.add(name); + } + }); + if (__VUE_OPTIONS_API__) { + const { extends: extendsOptions, mixins } = vueOptions; + if (mixins) { + mixins.forEach((mixin) => findHooks(mixin, hooks)); + } + if (extendsOptions) { + findHooks(extendsOptions, hooks); + } + } + } + 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.$callHook(hook, args); + }; + } +} +const EXCLUDE_HOOKS = [ON_READY]; +function initHooks(mpOptions, hooks, excludes = EXCLUDE_HOOKS) { + hooks.forEach((hook) => initHook$1(mpOptions, hook, excludes)); +} +function initUnknownHooks(mpOptions, vueOptions, excludes = EXCLUDE_HOOKS) { + findHooks(vueOptions).forEach((hook) => initHook$1(mpOptions, hook, excludes)); +} + +const HOOKS = [ + ON_SHOW, + ON_HIDE, + ON_ERROR, + ON_THEME_CHANGE, + ON_PAGE_NOT_FOUND, + ON_UNHANDLE_REJECTION, +]; +function parseApp(instance, parseAppOptions) { + const internalInstance = instance.$; + const appOptions = { + globalData: (instance.$options && instance.$options.globalData) || {}, + $vm: instance, + onLaunch(options) { + const ctx = internalInstance.ctx; + if (this.$vm && ctx.$scope) { + // 已经初始化过了,主要是为了百度,百度 onShow 在 onLaunch 之前 + return; + } + initBaseInstance(internalInstance, { + mpType: 'app', + mpInstance: this, + slots: [], + }); + ctx.globalData = this.globalData; + instance.$callHook(ON_LAUNCH, options); + }, + }; + const vueOptions = instance.$.type; + initHooks(appOptions, HOOKS); + initUnknownHooks(appOptions, vueOptions); + if (__VUE_OPTIONS_API__) { + const methods = vueOptions.methods; + methods && extend(appOptions, methods); + } + if (parseAppOptions) { + parseAppOptions.parse(appOptions); + } + return appOptions; +} +function initCreateApp(parseAppOptions) { + return function createApp(vm) { + return App(parseApp(vm, parseAppOptions)); + }; +} + +const PROP_TYPES = [String, Number, Boolean, Object, Array, null]; +function createObserver(name) { + return function observer(newVal) { + if (this.$vm) { + this.$vm.$.props[name] = newVal; // 为了触发其他非 render watcher + } + }; +} +function parsePropType(key, type, defaultValue) { + // [String]=>String + if (isArray(type) && type.length === 1) { + return type[0]; + } + return type; +} +function initDefaultProps(isBehavior = false) { + const properties = {}; + if (!isBehavior) { + properties.vueId = { + type: String, + value: '', + }; + // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots + properties.vueSlots = { + type: null, + value: [], + observer: function (newVal) { + const $slots = Object.create(null); + newVal.forEach((slotName) => { + $slots[slotName] = true; + }); + this.setData({ + $slots, + }); + }, + }; + } + return properties; +} +function createProperty(key, prop) { + prop.observer = createObserver(key); + return prop; +} +function initProps(mpComponentOptions, rawProps, isBehavior = false) { + const properties = initDefaultProps(isBehavior); + if (isArray(rawProps)) { + rawProps.forEach((key) => { + properties[key] = createProperty(key, { + type: null, + }); + }); + } + else if (isPlainObject(rawProps)) { + Object.keys(rawProps).forEach((key) => { + const opts = rawProps[key]; + if (isPlainObject(opts)) { + // title:{type:String,default:''} + let value = opts.default; + if (isFunction(value)) { + value = value(); + } + const type = opts.type; + opts.type = parsePropType(key, type); + properties[key] = createProperty(key, { + type: PROP_TYPES.indexOf(type) !== -1 ? type : null, + value, + }); + } + else { + // content:String + const type = parsePropType(key, opts); + properties[key] = createProperty(key, { + type: PROP_TYPES.indexOf(type) !== -1 ? type : null, + }); + } + }); + } + mpComponentOptions.properties = properties; +} + +function initData(vueOptions) { + let data = vueOptions.data || {}; + if (typeof data === 'function') { + try { + const appConfig = getApp().$vm.$.appContext.config; + data = data.call(appConfig.globalProperties); + } + catch (e) { + if (process.env.VUE_APP_DEBUG) { + console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data, e); + } + } + } + else { + try { + // 对 data 格式化 + data = JSON.parse(JSON.stringify(data)); + } + catch (e) { } + } + if (!isPlainObject(data)) { + data = {}; + } + return data; +} +function initBehaviors(vueOptions, initBehavior) { + const vueBehaviors = vueOptions.behaviors; + const vueExtends = vueOptions.extends; + const vueMixins = vueOptions.mixins; + let vueProps = vueOptions.props; + if (!vueProps) { + vueOptions.props = vueProps = []; + } + const behaviors = []; + if (isArray(vueBehaviors)) { + vueBehaviors.forEach((behavior) => { + behaviors.push(behavior.replace('uni://', `${__PLATFORM_PREFIX__}://`)); + if (behavior === 'uni://form-field') { + if (isArray(vueProps)) { + vueProps.push('name'); + vueProps.push('value'); + } + else { + vueProps.name = { + type: String, + default: '', + }; + vueProps.value = { + type: [String, Number, Boolean, Array, Object, Date], + default: '', + }; + } + } + }); + } + if (vueExtends && vueExtends.props) { + const behavior = {}; + initProps(behavior, vueExtends.props, true); + behaviors.push(initBehavior(behavior)); + } + if (isArray(vueMixins)) { + vueMixins.forEach((vueMixin) => { + if (vueMixin.props) { + const behavior = {}; + initProps(behavior, vueMixin.props, true); + behaviors.push(initBehavior(behavior)); + } + }); + } + return behaviors; +} +function applyOptions(componentOptions, vueOptions, initBehavior) { + componentOptions.data = initData(vueOptions); + componentOptions.behaviors = initBehaviors(vueOptions, initBehavior); +} + +function getExtraValue(instance, dataPathsArray) { + let context = instance; + dataPathsArray.forEach((dataPathArray) => { + const dataPath = dataPathArray[0]; + const value = dataPathArray[2]; + if (dataPath || typeof value !== 'undefined') { + // ['','',index,'disable'] + const propPath = dataPathArray[1]; + const valuePath = dataPathArray[3]; + let vFor; + if (Number.isInteger(dataPath)) { + vFor = dataPath; + } + else if (!dataPath) { + vFor = context; + } + else if (typeof dataPath === 'string' && dataPath) { + if (dataPath.indexOf('#s#') === 0) { + vFor = dataPath.substr(3); + } + else { + vFor = getTarget(context, dataPath); + } + } + if (Number.isInteger(vFor)) { + context = value; + } + else if (!propPath) { + context = vFor[value]; + } + else { + if (isArray(vFor)) { + context = vFor.find((vForItem) => { + return getTarget(vForItem, propPath) === value; + }); + } + else if (isPlainObject(vFor)) { + context = Object.keys(vFor).find((vForKey) => { + return getTarget(vFor[vForKey], propPath) === value; + }); + } + else { + console.error('v-for 暂不支持循环数据:', vFor); + } + } + if (valuePath) { + context = getTarget(context, valuePath); + } + } + }); + return context; +} +function processEventExtra(instance, extra, event) { + const extraObj = {}; + if (isArray(extra) && extra.length) { + /** + *[ + * ['data.items', 'data.id', item.data.id], + * ['metas', 'id', meta.id] + *], + *[ + * ['data.items', 'data.id', item.data.id], + * ['metas', 'id', meta.id] + *], + *'test' + */ + extra.forEach((dataPath, index) => { + if (typeof dataPath === 'string') { + if (!dataPath) { + // model,prop.sync + extraObj['$' + index] = instance; + } + else { + 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]; + } + } + else if (dataPath.indexOf('$event.') === 0) { + // $event.target.value + extraObj['$' + index] = getTarget(event, dataPath.replace('$event.', '')); + } + else { + extraObj['$' + index] = getTarget(instance, dataPath); + } + } + } + else { + extraObj['$' + index] = getExtraValue(instance, dataPath); + } + }); + } + return extraObj; +} +function getObjByArray(arr) { + const obj = {}; + for (let i = 1; i < arr.length; i++) { + const element = arr[i]; + obj[element[0]] = element[1]; + } + return obj; +} +function processEventArgs(instance, event, args = [], extra = [], isCustom, methodName) { + let isCustomMPEvent = false; // wxcomponent 组件,传递原始 event 对象 + if (isCustom) { + // 自定义事件 + isCustomMPEvent = + event.currentTarget && + event.currentTarget.dataset && + event.currentTarget.dataset.comType === 'wx'; + if (!args.length) { + // 无参数,直接传入 event 或 detail 数组 + if (isCustomMPEvent) { + return [event]; + } + return event.detail.__args__ || event.detail; + } + } + const extraObj = processEventExtra(instance, extra, event); + const ret = []; + args.forEach((arg) => { + if (arg === '$event') { + if (methodName === '__set_model' && !isCustom) { + // input v-model value + ret.push(event.target.value); + } + else { + if (isCustom && !isCustomMPEvent) { + ret.push(event.detail.__args__[0]); + } + else { + // wxcomponent 组件或内置组件 + ret.push(event); + } + } + } + else { + if (isArray(arg) && arg[0] === 'o') { + ret.push(getObjByArray(arg)); + } + else if (typeof arg === 'string' && hasOwn(extraObj, arg)) { + ret.push(extraObj[arg]); + } + else { + ret.push(arg); + } + } + }); + return ret; +} +function wrapper(event) { + event.stopPropagation = NOOP; + event.preventDefault = NOOP; + event.target = event.target || {}; + if (!hasOwn(event, 'detail')) { + event.detail = {}; + } + if (hasOwn(event, 'markerId')) { + event.detail = typeof event.detail === 'object' ? event.detail : {}; + event.detail.markerId = event.markerId; + } + if (isPlainObject(event.detail)) { + event.target = extend({}, event.target, event.detail); + } + return event; +} +const ONCE = '~'; +const CUSTOM = '^'; +function matchEventType(eventType, optType) { + return (eventType === optType || + (optType === 'regionchange' && + (eventType === 'begin' || eventType === 'end'))); +} +function handleEvent(event) { + event = wrapper(event); + // [['tap',[['handle',[1,2,a]],['handle1',[1,2,a]]]]] + const dataset = (event.currentTarget || event.target).dataset; + if (!dataset) { + return console.warn('事件信息不存在'); + } + const eventOpts = (dataset.eventOpts || + dataset['event-opts']); // 支付宝 web-view 组件 dataset 非驼峰 + if (!eventOpts) { + return console.warn('事件信息不存在'); + } + // [['handle',[1,2,a]],['handle1',[1,2,a]]] + const eventType = event.type; + const ret = []; + eventOpts.forEach((eventOpt) => { + let type = eventOpt[0]; + const eventsArray = eventOpt[1]; + const isCustom = type.charAt(0) === CUSTOM; + type = isCustom ? type.slice(1) : type; + const isOnce = type.charAt(0) === ONCE; + type = isOnce ? type.slice(1) : type; + if (eventsArray && matchEventType(eventType, type)) { + eventsArray.forEach((eventArray) => { + const methodName = eventArray[0]; + if (methodName) { + let handlerCtx = this.$vm; + if (handlerCtx.$options.generic && + handlerCtx.$parent && + handlerCtx.$parent.$parent) { + // mp-weixin,mp-toutiao 抽象节点模拟 scoped slots + handlerCtx = handlerCtx.$parent.$parent; + } + if (methodName === '$emit') { + handlerCtx.$emit.apply(handlerCtx, processEventArgs(this.$vm, event, eventArray[1], eventArray[2], isCustom, methodName)); + return; + } + const handler = handlerCtx[methodName]; + if (!isFunction(handler)) { + throw new Error(` _vm.${methodName} is not a function`); + } + if (isOnce) { + if (handler.once) { + return; + } + handler.once = true; + } + let params = processEventArgs(this.$vm, event, eventArray[1], eventArray[2], isCustom, methodName); + params = Array.isArray(params) ? params : []; + // 参数尾部增加原始事件对象用于复杂表达式内获取额外数据 + if (/=\s*\S+\.eventParams\s*\|\|\s*\S+\[['"]event-params['"]\]/.test(handler.toString())) { + // eslint-disable-next-line no-sparse-arrays + params = params.concat([, , , , , , , , , , event]); + } + ret.push(handler.apply(handlerCtx, params)); + } + }); + } + }); + if (eventType === 'input' && + ret.length === 1 && + typeof ret[0] !== 'undefined') { + return ret[0]; + } +} + +function parseComponent(vueOptions, { parse, mocks, isPage, initRelation, handleLink, initLifetimes, }) { + vueOptions = vueOptions.default || vueOptions; + const options = { + multipleSlots: true, + addGlobalClass: true, + }; + if (vueOptions.options) { + extend(options, vueOptions.options); + } + const mpComponentOptions = { + options, + lifetimes: initLifetimes({ mocks, isPage, initRelation, vueOptions }), + pageLifetimes: { + show() { + this.$vm && this.$vm.$callHook('onPageShow'); + }, + hide() { + this.$vm && this.$vm.$callHook('onPageHide'); + }, + resize(size) { + this.$vm && this.$vm.$callHook('onPageResize', size); + }, + }, + methods: { + __l: handleLink, + __e: handleEvent, + }, + }; + if (__VUE_OPTIONS_API__) { + applyOptions(mpComponentOptions, vueOptions, initBehavior); + } + initProps(mpComponentOptions, vueOptions.props, false); + initExtraOptions(mpComponentOptions, vueOptions); + initWxsCallMethods(mpComponentOptions.methods, vueOptions.wxsCallMethods); + if (parse) { + parse(mpComponentOptions, { handleLink }); + } + return mpComponentOptions; +} +function initCreateComponent(parseOptions) { + return function createComponent(vueComponentOptions) { + return Component(parseComponent(vueComponentOptions, parseOptions)); + }; +} +let $createComponentFn; +let $destroyComponentFn; +function $createComponent(initialVNode, options) { + if (!$createComponentFn) { + $createComponentFn = getApp().$vm.$createComponent; + } + return $createComponentFn(initialVNode, options); +} +function $destroyComponent(instance) { + if (!$destroyComponentFn) { + $destroyComponentFn = getApp().$vm.$destroyComponent; + } + return $destroyComponentFn(instance); +} + +function parsePage(vueOptions, parseOptions) { + const { parse, mocks, isPage, initRelation, handleLink, initLifetimes } = parseOptions; + const miniProgramPageOptions = parseComponent(vueOptions, { + mocks, + isPage, + initRelation, + handleLink, + initLifetimes, + }); + const methods = miniProgramPageOptions.methods; + methods.onLoad = function (query) { + this.options = query; + this.$page = { + fullPath: '/' + this.route + stringifyQuery(query), + }; + return this.$vm && this.$vm.$callHook(ON_LOAD, query); + }; + initHooks(methods, PAGE_HOOKS); + initUnknownHooks(methods, vueOptions); + parse && parse(miniProgramPageOptions, { handleLink }); + return miniProgramPageOptions; +} +function initCreatePage(parseOptions) { + return function createPage(vuePageOptions) { + return Component(parsePage(vuePageOptions, parseOptions)); + }; +} + +const MPPage = Page; +const MPComponent = Component; +const customizeRE = /:/g; +function customize(str) { + return camelize(str.replace(customizeRE, '-')); +} +function initTriggerEvent(mpInstance) { + const oldTriggerEvent = mpInstance.triggerEvent; + mpInstance.triggerEvent = function (event, ...args) { + return oldTriggerEvent.apply(mpInstance, [customize(event), ...args]); + }; +} +function initHook(name, options) { + const oldHook = options[name]; + if (!oldHook) { + options[name] = function () { + initTriggerEvent(this); + }; + } + else { + options[name] = function (...args) { + initTriggerEvent(this); + return oldHook.apply(this, args); + }; + } +} +Page = function (options) { + initHook(ON_LOAD, options); + return MPPage(options); +}; +Component = function (options) { + initHook('created', options); + return MPComponent(options); +}; + +function initLifetimes({ mocks, isPage, initRelation, vueOptions, }) { + return { + attached() { + const properties = this.properties; + initVueIds(properties.vueId, this); + const relationOptions = { + vuePid: this._$vuePid, + }; + // 处理父子关系 + initRelation(this, relationOptions); + // 初始化 vue 实例 + const mpInstance = this; + this.$vm = $createComponent({ + type: vueOptions, + props: properties, + }, { + mpType: isPage(mpInstance) ? 'page' : 'component', + mpInstance, + slots: properties.vueSlots, + parentComponent: relationOptions.parent && relationOptions.parent.$, + onBeforeSetup(instance, options) { + initRefs(instance, mpInstance); + initMocks(instance, mpInstance, mocks); + initComponentInstance(instance, options); + }, + }); + }, + ready() { + // 当组件 props 默认值为 true,初始化时传入 false 会导致 created,ready 触发, 但 attached 不触发 + // https://developers.weixin.qq.com/community/develop/doc/00066ae2844cc0f8eb883e2a557800 + if (this.$vm) { + this.$vm.$callHook('mounted'); + this.$vm.$callHook(ON_READY); + } + }, + detached() { + this.$vm && $destroyComponent(this.$vm); + }, + }; +} + +const mocks = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__']; +function isPage(mpInstance) { + return !!mpInstance.route; +} +function initRelation(mpInstance, detail) { + mpInstance.triggerEvent('__l', detail); +} +function handleLink(event) { + // detail 是微信,value 是百度(dipatch) + const detail = (event.detail || + event.value); + const vuePid = detail.vuePid; + let parentVm; + if (vuePid) { + parentVm = findVmByVueId(this.$vm, vuePid); + } + if (!parentVm) { + parentVm = this.$vm; + } + detail.parent = parentVm; +} + +var baseParseOptions = /*#__PURE__*/Object.freeze({ + __proto__: null, + mocks: mocks, + isPage: isPage, + initRelation: initRelation, + handleLink: handleLink, + initLifetimes: initLifetimes +}); + +const createApp = initCreateApp(); +const createPage = initCreatePage(baseParseOptions); +const createComponent$1 = initCreateComponent(baseParseOptions); +wx.createApp = createApp; +wx.createPage = createPage; +wx.createComponent = createComponent$1; + +/** + * 用于延迟调用 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 parse(componentOptions) { + const oldAttached = componentOptions.lifetimes.attached; + componentOptions.lifetimes.attached = function attached() { + // 暂不区分版本 + if (isPage(this)) { + // 解决快手小程序页面 attached 生命周期 setData 导致数据同步异常的问题 + fixSetDataStart(this); + setTimeout(() => { + fixSetDataEnd(this); + }, 0); + } + oldAttached.call(this); + }; +} +var parseComponentOptions = extend({}, baseParseOptions, { + parse +}); + +const createComponent = initCreateComponent(parseComponentOptions); +ks.EventChannel = EventChannel; +ks.createApp = createApp; +ks.createPage = createPage; +ks.createComponent = createComponent; + +export { createApp, createComponent, createPage };