From a99e666bca498ebcc5b994133f3c863ba0b71920 Mon Sep 17 00:00:00 2001 From: fxy060608 Date: Thu, 1 Apr 2021 20:02:30 +0800 Subject: [PATCH] feat(api): format args --- packages/global.d.ts | 6 +- packages/shims-uni-app.d.ts | 11 + packages/uni-api/src/helpers/api/index.ts | 19 +- .../uni-api/src/{service => helpers}/utils.ts | 0 packages/uni-api/src/index.ts | 3 + packages/uni-api/src/protocols/base/base64.ts | 2 + .../uni-api/src/protocols/base/canIUse.ts | 2 + .../uni-api/src/protocols/base/interceptor.ts | 2 + packages/uni-api/src/protocols/base/upx2px.ts | 2 +- .../src/protocols/device/makePhoneCall.ts | 4 +- .../src/protocols/file/openDocument.ts | 1 + .../src/protocols/media/getImageInfo.ts | 2 + .../src/protocols/route/encodeQueryString.ts | 25 ++ packages/uni-api/src/protocols/route/route.js | 209 -------------- packages/uni-api/src/protocols/route/route.ts | 199 ++++++++++++++ packages/uni-api/src/service/base/base64.ts | 6 +- .../uni-api/src/service/base/interceptor.ts | 8 +- packages/uni-api/src/service/base/upx2px.ts | 4 +- .../service/ui/createIntersectionObserver.ts | 6 +- packages/uni-core/src/helpers/getRealRoute.ts | 2 +- packages/uni-h5/dist/uni-h5.esm.js | 257 +++++++++++++++--- .../framework/components/app/layout/index.tsx | 2 +- .../uni-h5/src/framework/plugin/router.ts | 5 +- .../uni-h5/src/service/api/base/canIUse.ts | 8 +- .../src/service/api/device/makePhoneCall.ts | 8 +- .../src/service/api/file/openDocument.ts | 8 +- .../src/service/api/media/getImageInfo.ts | 7 +- .../src/service/api/route/navigateBack.ts | 26 +- .../src/service/api/route/navigateTo.ts | 36 ++- .../uni-h5/src/service/api/route/reLaunch.ts | 14 +- .../src/service/api/route/redirectTo.ts | 14 +- .../uni-h5/src/service/api/route/switchTab.ts | 14 +- packages/uni-mp-alipay/dist/uni.api.esm.js | 35 ++- packages/uni-mp-baidu/dist/uni.api.esm.js | 35 ++- packages/uni-mp-qq/dist/uni.api.esm.js | 35 ++- packages/uni-mp-toutiao/dist/uni.api.esm.js | 35 ++- packages/uni-mp-weixin/dist/uni.api.esm.js | 35 ++- .../uni-quickapp-webview/dist/uni.api.esm.js | 35 ++- 38 files changed, 783 insertions(+), 339 deletions(-) rename packages/uni-api/src/{service => helpers}/utils.ts (100%) create mode 100644 packages/uni-api/src/protocols/route/encodeQueryString.ts delete mode 100644 packages/uni-api/src/protocols/route/route.js create mode 100644 packages/uni-api/src/protocols/route/route.ts diff --git a/packages/global.d.ts b/packages/global.d.ts index f683b1ebc..efabe4045 100644 --- a/packages/global.d.ts +++ b/packages/global.d.ts @@ -32,7 +32,11 @@ declare var __UNI_FEATURE_NAVIGATIONBAR_BUTTONS__: boolean declare var __UNI_FEATURE_NAVIGATIONBAR_SEARCHINPUT__: boolean declare var __UNI_FEATURE_NAVIGATIONBAR_TRANSPARENT__: boolean // TODO -declare var __uniRoutes: any +declare var __uniRoutes: UniApp.UniRoutes declare var __uniConfig: UniApp.UniConfig declare var UniViewJSBridge: any declare var UniServiceJSBridge: any + +declare const getCurrentPages: ( + isAll?: boolean +) => Array & T> diff --git a/packages/shims-uni-app.d.ts b/packages/shims-uni-app.d.ts index 94e4ec5bf..43b1aacd0 100644 --- a/packages/shims-uni-app.d.ts +++ b/packages/shims-uni-app.d.ts @@ -22,6 +22,7 @@ declare namespace UniApp { } interface UniConfig { + ready?: boolean router: { strict: boolean base: string @@ -35,6 +36,15 @@ declare namespace UniApp { rightWindow?: LayoutWindowOptions } + interface UniRoute { + path: string + redirect?: string + meta: PageRouteMeta + component?: any + } + + type UniRoutes = UniRoute[] + interface PageNavigationBarButton { type: | 'none' @@ -115,6 +125,7 @@ declare namespace UniApp { } interface PageRouteMeta extends PagesJsonPageStyle { id: number + isNVue?: boolean isQuit?: boolean isEntry?: boolean isTabBar?: boolean diff --git a/packages/uni-api/src/helpers/api/index.ts b/packages/uni-api/src/helpers/api/index.ts index b43edda72..94c922bf6 100644 --- a/packages/uni-api/src/helpers/api/index.ts +++ b/packages/uni-api/src/helpers/api/index.ts @@ -1,3 +1,4 @@ +import { isPlainObject } from '@vue/shared' import { ApiOptions, ApiProtocols } from '../../protocols/type' import { API_TYPE_ON_PROTOCOLS, validateProtocols } from '../protocol' import { @@ -19,6 +20,17 @@ type API_TYPES = | typeof API_TYPE_ASYNC function formatApiArgs(args: any[], options?: ApiOptions) { + const params = args[0] + if ( + !options || + (!isPlainObject(options.formatArgs) && isPlainObject(params)) + ) { + return args + } + const formatArgs = options.formatArgs! + Object.keys(formatArgs).forEach((name) => { + formatArgs[name](args[0][name], params) + }) return args } @@ -39,7 +51,12 @@ function wrapperSyncApi(fn: Function) { function wrapperAsyncApi(name: string, fn: Function, options?: ApiOptions) { return (args: Record) => { const callbackId = createAsyncApiCallback(name, args, options) - const res = fn.apply(null, [args, callbackId]) + const res = fn.apply(null, [ + args, + (res: unknown) => { + invokeCallback(callbackId, res) + }, + ]) if (res) { invokeCallback(callbackId, res) } diff --git a/packages/uni-api/src/service/utils.ts b/packages/uni-api/src/helpers/utils.ts similarity index 100% rename from packages/uni-api/src/service/utils.ts rename to packages/uni-api/src/helpers/utils.ts diff --git a/packages/uni-api/src/index.ts b/packages/uni-api/src/index.ts index 43f5ea4df..9a4a23db6 100644 --- a/packages/uni-api/src/index.ts +++ b/packages/uni-api/src/index.ts @@ -20,6 +20,7 @@ export * from './protocols/location/openLocation' export * from './protocols/media/chooseImage' export * from './protocols/media/chooseVideo' export * from './protocols/media/getImageInfo' +export * from './protocols/route/route' // helpers export { @@ -29,5 +30,7 @@ export { defineAsyncApi, } from './helpers/api' +export { getCurrentPageVm } from './helpers/utils' + export { handlePromise } from './helpers/api/promise' export { invokeApi, wrapperReturnValue } from './helpers/interceptor' diff --git a/packages/uni-api/src/protocols/base/base64.ts b/packages/uni-api/src/protocols/base/base64.ts index aa92f5119..1c95661a0 100644 --- a/packages/uni-api/src/protocols/base/base64.ts +++ b/packages/uni-api/src/protocols/base/base64.ts @@ -1,5 +1,7 @@ import { ProtocolOptions } from '../type' +export const API_BASE64_TO_ARRAY_BUFFER = 'base64ToArrayBuffer' +export const API_ARRAY_BUFFER_TO_BASE64 = 'arrayBufferToBase64' export const Base64ToArrayBufferProtocol: ProtocolOptions[] = [ { name: 'base64', diff --git a/packages/uni-api/src/protocols/base/canIUse.ts b/packages/uni-api/src/protocols/base/canIUse.ts index fdc4e6767..fcf96def9 100644 --- a/packages/uni-api/src/protocols/base/canIUse.ts +++ b/packages/uni-api/src/protocols/base/canIUse.ts @@ -1,5 +1,7 @@ import { ProtocolOptions } from '../type' +export const API_CAN_I_USE = 'canIUse' + export const CanIUseProtocol: ProtocolOptions[] = [ { name: 'schema', diff --git a/packages/uni-api/src/protocols/base/interceptor.ts b/packages/uni-api/src/protocols/base/interceptor.ts index 9812de1f0..cf904f123 100644 --- a/packages/uni-api/src/protocols/base/interceptor.ts +++ b/packages/uni-api/src/protocols/base/interceptor.ts @@ -1,4 +1,6 @@ import { ProtocolOptions } from '../type' +export const API_ADD_INTERCEPTOR = 'addInterceptor' +export const API_REMOVE_INTERCEPTOR = 'removeInterceptor' export const AddInterceptorProtocol: ProtocolOptions[] = [ { name: 'method', diff --git a/packages/uni-api/src/protocols/base/upx2px.ts b/packages/uni-api/src/protocols/base/upx2px.ts index 214d4e664..50986e26a 100644 --- a/packages/uni-api/src/protocols/base/upx2px.ts +++ b/packages/uni-api/src/protocols/base/upx2px.ts @@ -1,5 +1,5 @@ import { ProtocolOptions } from '../type' - +export const API_UPX2PX = 'upx2px' export const Upx2pxProtocol: ProtocolOptions[] = [ { name: 'upx', diff --git a/packages/uni-api/src/protocols/device/makePhoneCall.ts b/packages/uni-api/src/protocols/device/makePhoneCall.ts index 0c2b825e0..b645b98cb 100644 --- a/packages/uni-api/src/protocols/device/makePhoneCall.ts +++ b/packages/uni-api/src/protocols/device/makePhoneCall.ts @@ -1,12 +1,14 @@ import { ApiProtocol } from '../type' +export const API_MAKE_PHONE_CALL = 'makePhoneCall' + export const MakePhoneCallProtocol: ApiProtocol = { phoneNumber: { type: String, required: true, validator(phoneNumber: string) { if (!phoneNumber) { - return 'makePhoneCall:fail parameter error: parameter.phoneNumber should not be empty String;' + return 'parameter error: parameter.phoneNumber should not be empty String;' } }, }, diff --git a/packages/uni-api/src/protocols/file/openDocument.ts b/packages/uni-api/src/protocols/file/openDocument.ts index 5df19ab7b..dce3ceba9 100644 --- a/packages/uni-api/src/protocols/file/openDocument.ts +++ b/packages/uni-api/src/protocols/file/openDocument.ts @@ -1,4 +1,5 @@ import { ApiProtocol } from '../type' +export const API_OPEN_DOCUMENT = 'openDocument' export const OpenDocumentProtocol: ApiProtocol = { filePath: { diff --git a/packages/uni-api/src/protocols/media/getImageInfo.ts b/packages/uni-api/src/protocols/media/getImageInfo.ts index fcac89027..0dd18104e 100644 --- a/packages/uni-api/src/protocols/media/getImageInfo.ts +++ b/packages/uni-api/src/protocols/media/getImageInfo.ts @@ -1,6 +1,8 @@ import { getRealPath } from '@dcloudio/uni-platform' import { ApiOptions, ApiProtocol } from '../type' +export const API_GET_IMAGE_INFO = 'getImageInfo' + export const GetImageInfoOptions: ApiOptions = { formatArgs: { src(src, params) { diff --git a/packages/uni-api/src/protocols/route/encodeQueryString.ts b/packages/uni-api/src/protocols/route/encodeQueryString.ts new file mode 100644 index 000000000..358385dc2 --- /dev/null +++ b/packages/uni-api/src/protocols/route/encodeQueryString.ts @@ -0,0 +1,25 @@ +export function encodeQueryString(url: string) { + if (typeof url !== 'string') { + return url + } + const index = url.indexOf('?') + if (index === -1) { + return url + } + const query = url + .substr(index + 1) + .trim() + .replace(/^(\?|#|&)/, '') + if (!query) { + return url + } + url = url.substr(0, index) + const params: string[] = [] + query.split('&').forEach((param) => { + const parts = param.replace(/\+/g, ' ').split('=') + const key = parts.shift() + const val = parts.length > 0 ? parts.join('=') : '' + params.push(key + '=' + encodeURIComponent(val)) + }) + return params.length ? url + '?' + params.join('&') : url +} diff --git a/packages/uni-api/src/protocols/route/route.js b/packages/uni-api/src/protocols/route/route.js deleted file mode 100644 index 80404b7f9..000000000 --- a/packages/uni-api/src/protocols/route/route.js +++ /dev/null @@ -1,209 +0,0 @@ -import getRealRoute from '../../get-real-route' - -function encodeQueryString(url) { - if (typeof url !== 'string') { - return url - } - const index = url.indexOf('?') - - if (index === -1) { - return url - } - - const query = url - .substr(index + 1) - .trim() - .replace(/^(\?|#|&)/, '') - - if (!query) { - return url - } - - url = url.substr(0, index) - - const params = [] - - query.split('&').forEach(param => { - const parts = param.replace(/\+/g, ' ').split('=') - const key = parts.shift() - const val = parts.length > 0 ? parts.join('=') : '' - - params.push(key + '=' + encodeURIComponent(val)) - }) - - return params.length ? url + '?' + params.join('&') : url -} - -function createValidator(type) { - return function validator(url, params) { - // 格式化为绝对路径路由 - url = getRealRoute(url) - - const pagePath = url.split('?')[0] - // 匹配路由是否存在 - const routeOptions = __uniRoutes.find( - ({ path, alias }) => path === pagePath || alias === pagePath - ) - - if (!routeOptions) { - return 'page `' + url + '` is not found' - } - - // 检测不同类型跳转 - if (type === 'navigateTo' || type === 'redirectTo') { - if (routeOptions.meta.isTabBar) { - return `can not ${type} a tabbar page` - } - } else if (type === 'switchTab') { - if (!routeOptions.meta.isTabBar) { - return 'can not switch to no-tabBar page' - } - } - - // switchTab不允许传递参数,reLaunch到一个tabBar页面是可以的 - if ( - (type === 'switchTab' || type === 'preloadPage') && - routeOptions.meta.isTabBar && - params.openType !== 'appLaunch' - ) { - url = pagePath - } - - // 首页自动格式化为`/` - if (routeOptions.meta.isEntry) { - url = url.replace(routeOptions.alias, '/') - } - - // 参数格式化 - params.url = encodeQueryString(url) - if (type === 'unPreloadPage') { - return - } else if (type === 'preloadPage') { - if (__PLATFORM__ === 'app-plus') { - if (!routeOptions.meta.isNVue) { - return 'can not preload vue page' - } - } - if (routeOptions.meta.isTabBar) { - const pages = getCurrentPages(true) - const tabBarPagePath = (routeOptions.alias || routeOptions.path).substr( - 1 - ) - if (pages.find(page => page.route === tabBarPagePath)) { - return 'tabBar page `' + tabBarPagePath + '` already exists' - } - } - return - } - - // 主要拦截目标为用户快速点击时触发的多次跳转,该情况,通常前后 url 是一样的 - if (navigatorLock === url) { - return `${navigatorLock} locked` - } - // 至少 onLaunch 之后,再启用lock逻辑(onLaunch之前可能开发者手动调用路由API,来提前跳转) - // enableNavigatorLock 临时开关(不对外开放),避免该功能上线后,有部分情况异常,可以让开发者临时关闭 lock 功能 - if (__uniConfig.ready && __uniConfig.enableNavigatorLock !== false) { - navigatorLock = url - } - } -} - -let navigatorLock - -function createProtocol(type, extras = {}) { - return Object.assign( - { - url: { - type: String, - required: true, - validator: createValidator(type) - }, - beforeAll() { - navigatorLock = '' - } - }, - extras - ) -} - -function createAnimationProtocol(animationTypes) { - return { - animationType: { - type: String, - validator(type) { - if (type && animationTypes.indexOf(type) === -1) { - return ( - '`' + - type + - '` is not supported for `animationType` (supported values are: `' + - animationTypes.join('`|`') + - '`)' - ) - } - } - }, - animationDuration: { - type: Number - } - } -} - -export const redirectTo = createProtocol('redirectTo') - -export const reLaunch = createProtocol('reLaunch') - -export const navigateTo = createProtocol( - 'navigateTo', - createAnimationProtocol([ - 'slide-in-right', - 'slide-in-left', - 'slide-in-top', - 'slide-in-bottom', - 'fade-in', - 'zoom-out', - 'zoom-fade-out', - 'pop-in', - 'none' - ]) -) - -export const switchTab = createProtocol('switchTab') - -export const navigateBack = Object.assign( - { - delta: { - type: Number, - validator(delta, params) { - delta = parseInt(delta) || 1 - params.delta = Math.min(getCurrentPages().length - 1, delta) - } - } - }, - createAnimationProtocol([ - 'slide-out-right', - 'slide-out-left', - 'slide-out-top', - 'slide-out-bottom', - 'fade-out', - 'zoom-in', - 'zoom-fade-in', - 'pop-out', - 'none' - ]) -) - -export const preloadPage = { - url: { - type: String, - required: true, - validator: createValidator('preloadPage') - } -} - -export const unPreloadPage = { - url: { - type: String, - required: true, - validator: createValidator('unPreloadPage') - } -} diff --git a/packages/uni-api/src/protocols/route/route.ts b/packages/uni-api/src/protocols/route/route.ts new file mode 100644 index 000000000..bdd6fce5c --- /dev/null +++ b/packages/uni-api/src/protocols/route/route.ts @@ -0,0 +1,199 @@ +import { extend } from '@vue/shared' +import { getRealRoute } from '@dcloudio/uni-core' +import { ApiOptions, ApiProtocol } from '../type' +import { encodeQueryString } from './encodeQueryString' + +const ANIMATION_IN = [ + 'slide-in-right', + 'slide-in-left', + 'slide-in-top', + 'slide-in-bottom', + 'fade-in', + 'zoom-out', + 'zoom-fade-out', + 'pop-in', + 'none', +] + +const ANIMATION_OUT = [ + 'slide-out-right', + 'slide-out-left', + 'slide-out-top', + 'slide-out-bottom', + 'fade-out', + 'zoom-in', + 'zoom-fade-in', + 'pop-out', + 'none', +] + +const BaseRouteProtocol: ApiProtocol = { + url: { + type: String, + required: true, + }, +} + +export const API_NAVIGATE_TO = 'navigateTo' +export const API_REDIRECT_TO = 'redirectTo' +export const API_RE_LAUNCH = 'reLaunch' +export const API_SWITCH_TAB = 'switchTab' +export const API_NAVIGATE_BACK = 'navigateBack' + +export const API_PRELOAD_PAGE = 'preloadPage' +export const API_UN_PRELOAD_PAGE = 'unPreloadPage' + +export const NavigateToProtocol: ApiProtocol = extend( + {}, + BaseRouteProtocol, + createAnimationProtocol(ANIMATION_IN) +) + +export const NavigateBackProtocol: ApiProtocol = extend( + { + delta: { + type: Number, + }, + }, + createAnimationProtocol(ANIMATION_OUT) +) + +export const RedirectToProtocol = BaseRouteProtocol + +export const ReLaunchProtocol = BaseRouteProtocol + +export const SwitchTabProtocol = BaseRouteProtocol + +export const PreloadPageProtocol = BaseRouteProtocol + +export const UnPreloadPageProtocol = BaseRouteProtocol + +export const NavigateToOptions: ApiOptions = /*#__PURE__*/ createRouteOptions( + API_NAVIGATE_TO +) +export const RedirectToOptions: ApiOptions = /*#__PURE__*/ createRouteOptions( + API_REDIRECT_TO +) +export const ReLaunchOptions: ApiOptions = /*#__PURE__*/ createRouteOptions( + API_RE_LAUNCH +) +export const SwitchTabOptions: ApiOptions = /*#__PURE__*/ createRouteOptions( + API_SWITCH_TAB +) + +export const NavigateBackOptions: ApiOptions = { + formatArgs: { + delta(delta, params) { + delta = parseInt(delta) || 1 + params.delta = Math.min(getCurrentPages().length - 1, delta) + }, + }, +} + +function createAnimationProtocol(animationTypes: string[]) { + return { + animationType: { + type: String, + validator(type: string) { + if (type && animationTypes.indexOf(type) === -1) { + return ( + '`' + + type + + '` is not supported for `animationType` (supported values are: `' + + animationTypes.join('`|`') + + '`)' + ) + } + }, + }, + animationDuration: { + type: Number, + }, + } +} + +let navigatorLock: string + +function beforeRoute() { + navigatorLock = '' +} + +function createRouteOptions(type: string): ApiOptions { + return { + formatArgs: { + url: createNormalizeUrl(type), + }, + beforeAll: beforeRoute, + } +} + +function createNormalizeUrl(type: string) { + return function normalizeUrl(url: string, params: Record) { + // 格式化为绝对路径路由 + url = getRealRoute(url) + const pagePath = url.split('?')[0] + // 匹配路由是否存在 + const routeOptions = __uniRoutes.find( + ({ path, redirect }) => path === pagePath || redirect === pagePath + ) + + if (!routeOptions) { + return 'page `' + url + '` is not found' + } + + // 检测不同类型跳转 + if (type === API_NAVIGATE_TO || type === API_REDIRECT_TO) { + if (routeOptions.meta.isTabBar) { + return `can not ${type} a tabbar page` + } + } else if (type === API_SWITCH_TAB) { + if (!routeOptions.meta.isTabBar) { + return 'can not switch to no-tabBar page' + } + } + + // switchTab不允许传递参数,reLaunch到一个tabBar页面是可以的 + if ( + (type === API_SWITCH_TAB || type === API_PRELOAD_PAGE) && + routeOptions.meta.isTabBar && + params.openType !== 'appLaunch' + ) { + url = pagePath + } + + // 首页自动格式化为`/` + if (routeOptions.meta.isEntry) { + url = url.replace(routeOptions.path, '/') + } + + // 参数格式化 + params.url = encodeQueryString(url) + if (type === API_UN_PRELOAD_PAGE) { + return + } else if (type === API_PRELOAD_PAGE) { + if (__PLATFORM__ === 'app-plus') { + if (!routeOptions.meta.isNVue) { + return 'can not preload vue page' + } + } + if (routeOptions.meta.isTabBar) { + const pages = getCurrentPages(true) + const tabBarPagePath = routeOptions.path.substr(1) + if (pages.find((page) => page.route === tabBarPagePath)) { + return 'tabBar page `' + tabBarPagePath + '` already exists' + } + } + return + } + + // 主要拦截目标为用户快速点击时触发的多次跳转,该情况,通常前后 url 是一样的 + if (navigatorLock === url && params.openType !== 'appLaunch') { + return `${navigatorLock} locked` + } + // 至少 onLaunch 之后,再启用lock逻辑(onLaunch之前可能开发者手动调用路由API,来提前跳转) + // enableNavigatorLock 临时开关(不对外开放),避免该功能上线后,有部分情况异常,可以让开发者临时关闭 lock 功能 + if (__uniConfig.ready) { + navigatorLock = url + } + } +} diff --git a/packages/uni-api/src/service/base/base64.ts b/packages/uni-api/src/service/base/base64.ts index 6b3b26f58..97fa3d56c 100644 --- a/packages/uni-api/src/service/base/base64.ts +++ b/packages/uni-api/src/service/base/base64.ts @@ -6,12 +6,14 @@ import { defineSyncApi } from '../../helpers/api' import { Base64ToArrayBufferProtocol, ArrayBufferToBase64Protocol, + API_BASE64_TO_ARRAY_BUFFER, + API_ARRAY_BUFFER_TO_BASE64, } from '../../protocols/base/base64' export const base64ToArrayBuffer = defineSyncApi< typeof uni.base64ToArrayBuffer >( - 'base64ToArrayBuffer', + API_BASE64_TO_ARRAY_BUFFER, (base64) => { return decode(base64) as ArrayBuffer }, @@ -21,7 +23,7 @@ export const base64ToArrayBuffer = defineSyncApi< export const arrayBufferToBase64 = defineSyncApi< typeof uni.arrayBufferToBase64 >( - 'arrayBufferToBase64', + API_ARRAY_BUFFER_TO_BASE64, (arrayBuffer) => { return encode(arrayBuffer) as string }, diff --git a/packages/uni-api/src/service/base/interceptor.ts b/packages/uni-api/src/service/base/interceptor.ts index 72d0cace6..919d7f59f 100644 --- a/packages/uni-api/src/service/base/interceptor.ts +++ b/packages/uni-api/src/service/base/interceptor.ts @@ -1,16 +1,18 @@ import { isArray, isFunction, isPromise, isPlainObject } from '@vue/shared' import { + HOOKS, Interceptor, scopedInterceptors, globalInterceptors, Interceptors, - HOOKS, } from '../../helpers/interceptor' import { defineSyncApi } from '../../helpers/api' import { + API_ADD_INTERCEPTOR, + API_REMOVE_INTERCEPTOR, AddInterceptorProtocol, RemoveInterceptorProtocol, } from '../../protocols/base/interceptor' @@ -81,7 +83,7 @@ function removeHook(hooks: Function[] | undefined, hook: Function) { } export const addInterceptor = defineSyncApi( - 'addInterceptor', + API_ADD_INTERCEPTOR, (method: string | Interceptor, interceptor: Interceptor | undefined) => { if (typeof method === 'string' && isPlainObject(interceptor)) { mergeInterceptorHook( @@ -96,7 +98,7 @@ export const addInterceptor = defineSyncApi( ) export const removeInterceptor = defineSyncApi( - 'removeInterceptor', + API_REMOVE_INTERCEPTOR, (method: string | Interceptor, interceptor: Interceptor | undefined) => { if (typeof method === 'string') { if (isPlainObject(interceptor)) { diff --git a/packages/uni-api/src/service/base/upx2px.ts b/packages/uni-api/src/service/base/upx2px.ts index 76eda56e4..61c0abd47 100644 --- a/packages/uni-api/src/service/base/upx2px.ts +++ b/packages/uni-api/src/service/base/upx2px.ts @@ -1,6 +1,6 @@ import { getBaseSystemInfo } from '@dcloudio/uni-platform' import { defineSyncApi } from '../../helpers/api' -import { Upx2pxProtocol } from '../../protocols/base/upx2px' +import { API_UPX2PX, Upx2pxProtocol } from '../../protocols/base/upx2px' const EPS = 1e-4 const BASE_DEVICE_WIDTH = 750 @@ -16,7 +16,7 @@ function checkDeviceWidth() { } export const upx2px = defineSyncApi( - 'upx2px', + API_UPX2PX, (number, newDeviceWidth?: number) => { if (deviceWidth === 0) { checkDeviceWidth() diff --git a/packages/uni-api/src/service/ui/createIntersectionObserver.ts b/packages/uni-api/src/service/ui/createIntersectionObserver.ts index 28f05ddae..937270910 100644 --- a/packages/uni-api/src/service/ui/createIntersectionObserver.ts +++ b/packages/uni-api/src/service/ui/createIntersectionObserver.ts @@ -3,7 +3,7 @@ import { extend } from '@vue/shared' import { ServiceJSBridge } from '@dcloudio/uni-core' import { defineSyncApi } from '../../helpers/api' -import { getCurrentPageVm } from '../utils' +import { getCurrentPageVm } from '../../helpers/utils' const defaultOptions = { thresholds: [0], @@ -35,6 +35,8 @@ let reqComponentObserverId = 1 const reqComponentObserverCallbacks: Record = {} +export const API_CREATE_INTERSECTION_OBSERVER = 'createIntersectionObserver' + ServiceJSBridge.subscribe( 'requestComponentObserver', ({ reqId, reqEnd, res }: requestComponentObserver) => { @@ -122,7 +124,7 @@ class ServiceIntersectionObserver { export const createIntersectionObserver = defineSyncApi< typeof uni.createIntersectionObserver ->('createIntersectionObserver', (context?, options?) => { +>(API_CREATE_INTERSECTION_OBSERVER, (context?, options?) => { if (!context) { context = getCurrentPageVm() } diff --git a/packages/uni-core/src/helpers/getRealRoute.ts b/packages/uni-core/src/helpers/getRealRoute.ts index 1caf63444..82e45ddbb 100644 --- a/packages/uni-core/src/helpers/getRealRoute.ts +++ b/packages/uni-core/src/helpers/getRealRoute.ts @@ -1,4 +1,4 @@ -export function getRealRoute(fromRoute: string, toRoute: string): string { +export function getRealRoute(fromRoute: string, toRoute?: string): string { if (!toRoute) { toRoute = fromRoute if (toRoute.indexOf('/') === 0) { diff --git a/packages/uni-h5/dist/uni-h5.esm.js b/packages/uni-h5/dist/uni-h5.esm.js index dd3a5a5ad..25b8a110c 100644 --- a/packages/uni-h5/dist/uni-h5.esm.js +++ b/packages/uni-h5/dist/uni-h5.esm.js @@ -1,7 +1,7 @@ import {isFunction, extend, isPlainObject, hasOwn as hasOwn$1, hyphenate, isArray, isObject as isObject$1, capitalize, toRawType, makeMap as makeMap$1, isPromise} from "@vue/shared"; import {injectHook, createVNode, defineComponent, inject, provide, reactive, computed, nextTick, withDirectives, vShow, withCtx, openBlock, createBlock, KeepAlive, resolveDynamicComponent, resolveComponent, onMounted, ref, mergeProps, toDisplayString, toHandlers, renderSlot, createCommentVNode, withModifiers, vModelDynamic, Fragment, renderList, vModelText} from "vue"; import {NAVBAR_HEIGHT, COMPONENT_NAME_PREFIX, isCustomElement, plusReady, debounce, PRIMARY_COLOR} from "@dcloudio/uni-shared"; -import {createRouter, createWebHistory, createWebHashHistory, useRoute, RouterView} from "vue-router"; +import {createRouter, createWebHistory, createWebHashHistory, useRoute, RouterView, isNavigationFailure} from "vue-router"; function applyOptions(options, instance2, publicThis) { Object.keys(options).forEach((name) => { if (name.indexOf("on") === 0) { @@ -757,7 +757,10 @@ function createRouterOptions() { return { history: initHistory(), strict: !!__uniConfig.router.strict, - routes: __uniRoutes, + routes: [ + {path: __uniRoutes[0].path, redirect: "/"}, + ...__uniRoutes + ], scrollBehavior }; } @@ -994,7 +997,7 @@ function createTabBarTsx(route) { return withDirectives(createVNode(TabBar, null, null, 512), [[vShow, route.meta.isTabBar]]); } function createPageVNode() { - return createVNode(__uniRoutes[1].component); + return createVNode(__uniRoutes[0].component); } function createRouterViewVNode(keepAliveRoute) { return createVNode(RouterView, null, { @@ -7738,6 +7741,14 @@ const API_TYPE_TASK = 1; const API_TYPE_SYNC = 2; const API_TYPE_ASYNC = 3; function formatApiArgs(args, options) { + const params = args[0]; + if (!options || !isPlainObject(options.formatArgs) && isPlainObject(params)) { + return args; + } + const formatArgs = options.formatArgs; + Object.keys(formatArgs).forEach((name) => { + formatArgs[name](args[0][name], params); + }); return args; } function wrapperOnApi(name, fn) { @@ -7752,7 +7763,12 @@ function wrapperSyncApi(fn) { function wrapperAsyncApi(name, fn, options) { return (args) => { const callbackId = createAsyncApiCallback(name, args, options); - const res = fn.apply(null, [args, callbackId]); + const res = fn.apply(null, [ + args, + (res2) => { + invokeCallback(callbackId, res2); + } + ]); if (res) { invokeCallback(callbackId, res); } @@ -7766,7 +7782,7 @@ function wrapperApi(fn, name, protocol, options) { return errMsg; } } - return fn.apply(null, formatApiArgs(args)); + return fn.apply(null, formatApiArgs(args, options)); }; } function defineSyncApi(name, fn, protocol, options) { @@ -7778,15 +7794,17 @@ function defineAsyncApi(name, fn, protocol, options) { function defineApi(type, name, fn, protocol, options) { switch (type) { case API_TYPE_ON: - return wrapperApi(wrapperOnApi(name, fn), name, protocol); + return wrapperApi(wrapperOnApi(name, fn), name, protocol, options); case API_TYPE_TASK: - return wrapperApi(wrapperTaskApi(name, fn), name, protocol); + return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options); case API_TYPE_SYNC: - return wrapperApi(wrapperSyncApi(fn), name, protocol); + return wrapperApi(wrapperSyncApi(fn), name, protocol, options); case API_TYPE_ASYNC: - return wrapperApi(wrapperAsyncApi(name, fn, options), name, protocol); + return wrapperApi(wrapperAsyncApi(name, fn, options), name, protocol, options); } } +const API_BASE64_TO_ARRAY_BUFFER = "base64ToArrayBuffer"; +const API_ARRAY_BUFFER_TO_BASE64 = "arrayBufferToBase64"; const Base64ToArrayBufferProtocol = [ { name: "base64", @@ -7801,12 +7819,13 @@ const ArrayBufferToBase64Protocol = [ required: true } ]; -const base64ToArrayBuffer = defineSyncApi("base64ToArrayBuffer", (base64) => { +const base64ToArrayBuffer = defineSyncApi(API_BASE64_TO_ARRAY_BUFFER, (base64) => { return decode(base64); }, Base64ToArrayBufferProtocol); -const arrayBufferToBase64 = defineSyncApi("arrayBufferToBase64", (arrayBuffer) => { +const arrayBufferToBase64 = defineSyncApi(API_ARRAY_BUFFER_TO_BASE64, (arrayBuffer) => { return encode(arrayBuffer); }, ArrayBufferToBase64Protocol); +const API_UPX2PX = "upx2px"; const Upx2pxProtocol = [ { name: "upx", @@ -7825,7 +7844,7 @@ function checkDeviceWidth() { deviceDPR = pixelRatio2; isIOS = platform === "ios"; } -const upx2px = defineSyncApi("upx2px", (number, newDeviceWidth) => { +const upx2px = defineSyncApi(API_UPX2PX, (number, newDeviceWidth) => { if (deviceWidth === 0) { checkDeviceWidth(); } @@ -7857,6 +7876,8 @@ var HOOKS; })(HOOKS || (HOOKS = {})); const globalInterceptors = {}; const scopedInterceptors = {}; +const API_ADD_INTERCEPTOR = "addInterceptor"; +const API_REMOVE_INTERCEPTOR = "removeInterceptor"; const AddInterceptorProtocol = [ { name: "method", @@ -7904,14 +7925,14 @@ function removeHook(hooks, hook) { hooks.splice(index2, 1); } } -const addInterceptor = defineSyncApi("addInterceptor", (method, interceptor) => { +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("removeInterceptor", (method, interceptor) => { +const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interceptor) => { if (typeof method === "string") { if (isPlainObject(interceptor)) { removeInterceptorHook(scopedInterceptors[method], interceptor); @@ -7947,6 +7968,7 @@ const defaultOptions = { }; let reqComponentObserverId = 1; const reqComponentObserverCallbacks = {}; +const API_CREATE_INTERSECTION_OBSERVER = "createIntersectionObserver"; ServiceJSBridge.subscribe("requestComponentObserver", ({reqId, reqEnd, res}) => { const callback = reqComponentObserverCallbacks[reqId]; if (callback) { @@ -7999,7 +8021,7 @@ class ServiceIntersectionObserver { }, this._pageId); } } -const createIntersectionObserver = defineSyncApi("createIntersectionObserver", (context, options) => { +const createIntersectionObserver = defineSyncApi(API_CREATE_INTERSECTION_OBSERVER, (context, options) => { if (!context) { context = getCurrentPageVm(); } @@ -8007,6 +8029,7 @@ const createIntersectionObserver = defineSyncApi("createIntersectionObserver", ( }); const createSelectorQuery = () => { }; +const API_CAN_I_USE = "canIUse"; const CanIUseProtocol = [ { name: "schema", @@ -8014,17 +8037,19 @@ const CanIUseProtocol = [ required: true } ]; +const API_MAKE_PHONE_CALL = "makePhoneCall"; const MakePhoneCallProtocol = { phoneNumber: { type: String, required: true, validator(phoneNumber) { if (!phoneNumber) { - return "makePhoneCall:fail parameter error: parameter.phoneNumber should not be empty String;"; + return "parameter error: parameter.phoneNumber should not be empty String;"; } } } }; +const API_OPEN_DOCUMENT = "openDocument"; const OpenDocumentProtocol = { filePath: { type: String, @@ -8034,6 +8059,7 @@ const OpenDocumentProtocol = { type: String } }; +const API_GET_IMAGE_INFO = "getImageInfo"; const GetImageInfoOptions = { formatArgs: { src(src, params) { @@ -8047,6 +8073,155 @@ const GetImageInfoProtocol = { required: true } }; +function encodeQueryString(url) { + if (typeof url !== "string") { + return url; + } + const index2 = url.indexOf("?"); + if (index2 === -1) { + return url; + } + const query = url.substr(index2 + 1).trim().replace(/^(\?|#|&)/, ""); + if (!query) { + return url; + } + url = url.substr(0, index2); + const params = []; + query.split("&").forEach((param) => { + const parts = param.replace(/\+/g, " ").split("="); + const key = parts.shift(); + const val = parts.length > 0 ? parts.join("=") : ""; + params.push(key + "=" + encodeURIComponent(val)); + }); + return params.length ? url + "?" + params.join("&") : url; +} +const ANIMATION_IN = [ + "slide-in-right", + "slide-in-left", + "slide-in-top", + "slide-in-bottom", + "fade-in", + "zoom-out", + "zoom-fade-out", + "pop-in", + "none" +]; +const ANIMATION_OUT = [ + "slide-out-right", + "slide-out-left", + "slide-out-top", + "slide-out-bottom", + "fade-out", + "zoom-in", + "zoom-fade-in", + "pop-out", + "none" +]; +const BaseRouteProtocol = { + url: { + type: String, + required: true + } +}; +const API_NAVIGATE_TO = "navigateTo"; +const API_REDIRECT_TO = "redirectTo"; +const API_RE_LAUNCH = "reLaunch"; +const API_SWITCH_TAB = "switchTab"; +const API_NAVIGATE_BACK = "navigateBack"; +const API_PRELOAD_PAGE = "preloadPage"; +const API_UN_PRELOAD_PAGE = "unPreloadPage"; +const NavigateToProtocol = extend({}, BaseRouteProtocol, createAnimationProtocol(ANIMATION_IN)); +const NavigateBackProtocol = extend({ + delta: { + type: Number + } +}, createAnimationProtocol(ANIMATION_OUT)); +const RedirectToProtocol = BaseRouteProtocol; +const ReLaunchProtocol = BaseRouteProtocol; +const SwitchTabProtocol = BaseRouteProtocol; +const NavigateToOptions = /* @__PURE__ */ createRouteOptions(API_NAVIGATE_TO); +const RedirectToOptions = /* @__PURE__ */ createRouteOptions(API_REDIRECT_TO); +const ReLaunchOptions = /* @__PURE__ */ createRouteOptions(API_RE_LAUNCH); +const SwitchTabOptions = /* @__PURE__ */ createRouteOptions(API_SWITCH_TAB); +const NavigateBackOptions = { + formatArgs: { + delta(delta, params) { + delta = parseInt(delta) || 1; + params.delta = Math.min(getCurrentPages().length - 1, delta); + } + } +}; +function createAnimationProtocol(animationTypes) { + return { + animationType: { + type: String, + validator(type) { + if (type && animationTypes.indexOf(type) === -1) { + return "`" + type + "` is not supported for `animationType` (supported values are: `" + animationTypes.join("`|`") + "`)"; + } + } + }, + animationDuration: { + type: Number + } + }; +} +let navigatorLock; +function beforeRoute() { + navigatorLock = ""; +} +function createRouteOptions(type) { + return { + formatArgs: { + url: createNormalizeUrl(type) + }, + beforeAll: beforeRoute + }; +} +function createNormalizeUrl(type) { + return function normalizeUrl(url, params) { + url = getRealRoute(url); + const pagePath = url.split("?")[0]; + const routeOptions = __uniRoutes.find(({path, redirect}) => path === pagePath || redirect === pagePath); + if (!routeOptions) { + return "page `" + url + "` is not found"; + } + if (type === API_NAVIGATE_TO || type === API_REDIRECT_TO) { + if (routeOptions.meta.isTabBar) { + return `can not ${type} a tabbar page`; + } + } else if (type === API_SWITCH_TAB) { + if (!routeOptions.meta.isTabBar) { + return "can not switch to no-tabBar page"; + } + } + if ((type === API_SWITCH_TAB || type === API_PRELOAD_PAGE) && routeOptions.meta.isTabBar && params.openType !== "appLaunch") { + url = pagePath; + } + if (routeOptions.meta.isEntry) { + url = url.replace(routeOptions.path, "/"); + } + params.url = encodeQueryString(url); + if (type === API_UN_PRELOAD_PAGE) { + return; + } else if (type === API_PRELOAD_PAGE) { + if (routeOptions.meta.isTabBar) { + const pages = getCurrentPages(true); + const tabBarPagePath = routeOptions.path.substr(1); + if (pages.find((page) => page.route === tabBarPagePath)) { + return "tabBar page `" + tabBarPagePath + "` already exists"; + } + } + return; + } + if (navigatorLock === url && params.openType !== "appLaunch") { + return `${navigatorLock} locked`; + } + if (__uniConfig.ready) { + navigatorLock = url; + } + }; +} function cssSupports(css) { return window.CSS && window.CSS.supports && window.CSS.supports(css); } @@ -8055,13 +8230,13 @@ const SCHEMA_CSS = { "css.env": cssSupports("top:env(a)"), "css.constant": cssSupports("top:constant(a)") }; -const canIUse = defineSyncApi("canIUse", (schema) => { +const canIUse = defineSyncApi(API_CAN_I_USE, (schema) => { if (hasOwn$1(SCHEMA_CSS, schema)) { return SCHEMA_CSS[schema]; } return true; }, CanIUseProtocol); -const makePhoneCall = defineAsyncApi("makePhoneCall", (option) => { +const makePhoneCall = defineAsyncApi(API_MAKE_PHONE_CALL, (option) => { window.location.href = `tel:${option.phoneNumber}`; }, MakePhoneCallProtocol); const getSystemInfoSync = defineSyncApi("getSystemInfoSync", () => { @@ -8167,17 +8342,17 @@ const getSystemInfoSync = defineSyncApi("getSystemInfoSync", () => { const getSystemInfo = defineAsyncApi("getSystemInfo", () => { return getSystemInfoSync(); }); -const openDocument = defineAsyncApi("openDocument", (option) => { +const openDocument = defineAsyncApi(API_OPEN_DOCUMENT, (option) => { window.open(option.filePath); }, OpenDocumentProtocol); function _getServiceAddress() { return window.location.protocol + "//" + window.location.host; } -const getImageInfo = defineAsyncApi("getImageInfo", ({src}, callback) => { +const getImageInfo = defineAsyncApi(API_GET_IMAGE_INFO, ({src}, callback) => { const img = new Image(); img.onload = function() { callback({ - errMsg: "getImageInfo:ok", + errMsg: `${API_GET_IMAGE_INFO}:ok`, width: img.naturalWidth, height: img.naturalHeight, path: src.indexOf("/") === 0 ? _getServiceAddress() + src : src @@ -8185,27 +8360,45 @@ const getImageInfo = defineAsyncApi("getImageInfo", ({src}, callback) => { }; img.onerror = function() { callback({ - errMsg: "getImageInfo:fail" + errMsg: `${API_GET_IMAGE_INFO}:fail` }); }; img.src = src; }, GetImageInfoProtocol, GetImageInfoOptions); -const navigateBack = defineAsyncApi("navigateBack", () => { -}); -const navigateTo = defineAsyncApi("navigateTo", (options) => { +const navigateBack = defineAsyncApi(API_NAVIGATE_BACK, (options) => { + let canBack = true; + const vm = getCurrentPageVm(); + if (vm && vm.$callHook("onBackPress") === true) { + canBack = false; + } + if (!canBack) { + return { + errMsg: `${API_NAVIGATE_BACK}:fail onBackPress` + }; + } + getApp().$router.go(-options.delta); +}, NavigateBackProtocol, NavigateBackOptions); +const navigateTo = defineAsyncApi(API_NAVIGATE_TO, (options, callback) => { const router = getApp().$router; router.push({ path: options.url, force: true, state: createPageState("navigateTo") + }).then((failure) => { + if (isNavigationFailure(failure)) { + return callback({ + errMsg: `${API_NAVIGATE_TO}:fail ${failure.message}` + }); + } + callback(); }); -}); -const redirectTo = defineAsyncApi("redirectTo", () => { -}); -const reLaunch = defineAsyncApi("reLaunch", () => { -}); -const switchTab = defineAsyncApi("switchTab", () => { -}); +}, NavigateToProtocol, NavigateToOptions); +const redirectTo = defineAsyncApi(API_REDIRECT_TO, () => { +}, RedirectToProtocol, RedirectToOptions); +const reLaunch = defineAsyncApi(API_RE_LAUNCH, () => { +}, ReLaunchProtocol, ReLaunchOptions); +const switchTab = defineAsyncApi(API_SWITCH_TAB, () => { +}, SwitchTabProtocol, SwitchTabOptions); var api = /* @__PURE__ */ Object.freeze({ __proto__: null, [Symbol.toStringTag]: "Module", diff --git a/packages/uni-h5/src/framework/components/app/layout/index.tsx b/packages/uni-h5/src/framework/components/app/layout/index.tsx index a4de19f8d..3206b8b6b 100644 --- a/packages/uni-h5/src/framework/components/app/layout/index.tsx +++ b/packages/uni-h5/src/framework/components/app/layout/index.tsx @@ -87,7 +87,7 @@ function createTabBarTsx(route: RouteLocationNormalizedLoaded) { } function createPageVNode() { - return createVNode(__uniRoutes[1].component) + return createVNode(__uniRoutes[0].component) } function createRouterViewVNode( diff --git a/packages/uni-h5/src/framework/plugin/router.ts b/packages/uni-h5/src/framework/plugin/router.ts index 73fe1e318..8f7992a93 100644 --- a/packages/uni-h5/src/framework/plugin/router.ts +++ b/packages/uni-h5/src/framework/plugin/router.ts @@ -31,7 +31,10 @@ function createRouterOptions(): RouterOptions { return { history: initHistory(), strict: !!__uniConfig.router.strict, - routes: __uniRoutes as RouteRecordRaw[], + routes: [ + { path: __uniRoutes[0].path, redirect: '/' }, + ...__uniRoutes, + ] as RouteRecordRaw[], scrollBehavior, } } diff --git a/packages/uni-h5/src/service/api/base/canIUse.ts b/packages/uni-h5/src/service/api/base/canIUse.ts index 6c06e7507..d9414053d 100644 --- a/packages/uni-h5/src/service/api/base/canIUse.ts +++ b/packages/uni-h5/src/service/api/base/canIUse.ts @@ -1,6 +1,10 @@ import { hasOwn } from '@vue/shared' -import { CanIUseProtocol, defineSyncApi } from '@dcloudio/uni-api' +import { + API_CAN_I_USE, + CanIUseProtocol, + defineSyncApi, +} from '@dcloudio/uni-api' function cssSupports(css: string) { return window.CSS && window.CSS.supports && window.CSS.supports(css) @@ -13,7 +17,7 @@ const SCHEMA_CSS = { } export const canIUse = defineSyncApi( - 'canIUse', + API_CAN_I_USE, (schema: string) => { if (hasOwn(SCHEMA_CSS, schema)) { return SCHEMA_CSS[schema] diff --git a/packages/uni-h5/src/service/api/device/makePhoneCall.ts b/packages/uni-h5/src/service/api/device/makePhoneCall.ts index ddc73aedf..1fe1f0e04 100644 --- a/packages/uni-h5/src/service/api/device/makePhoneCall.ts +++ b/packages/uni-h5/src/service/api/device/makePhoneCall.ts @@ -1,7 +1,11 @@ -import { defineAsyncApi, MakePhoneCallProtocol } from '@dcloudio/uni-api' +import { + API_MAKE_PHONE_CALL, + defineAsyncApi, + MakePhoneCallProtocol, +} from '@dcloudio/uni-api' export const makePhoneCall = defineAsyncApi( - 'makePhoneCall', + API_MAKE_PHONE_CALL, (option) => { window.location.href = `tel:${option.phoneNumber}` }, diff --git a/packages/uni-h5/src/service/api/file/openDocument.ts b/packages/uni-h5/src/service/api/file/openDocument.ts index c6ea15cec..3d556ce24 100644 --- a/packages/uni-h5/src/service/api/file/openDocument.ts +++ b/packages/uni-h5/src/service/api/file/openDocument.ts @@ -1,7 +1,11 @@ -import { defineAsyncApi, OpenDocumentProtocol } from '@dcloudio/uni-api' +import { + API_OPEN_DOCUMENT, + defineAsyncApi, + OpenDocumentProtocol, +} from '@dcloudio/uni-api' export const openDocument = defineAsyncApi( - 'openDocument', + API_OPEN_DOCUMENT, (option) => { window.open(option.filePath) }, diff --git a/packages/uni-h5/src/service/api/media/getImageInfo.ts b/packages/uni-h5/src/service/api/media/getImageInfo.ts index 2fe590112..fe7f1de7a 100644 --- a/packages/uni-h5/src/service/api/media/getImageInfo.ts +++ b/packages/uni-h5/src/service/api/media/getImageInfo.ts @@ -1,4 +1,5 @@ import { + API_GET_IMAGE_INFO, defineAsyncApi, GetImageInfoOptions, GetImageInfoProtocol, @@ -9,12 +10,12 @@ function _getServiceAddress() { } export const getImageInfo = defineAsyncApi( - 'getImageInfo', + API_GET_IMAGE_INFO, ({ src }, callback?: Function) => { const img = new Image() img.onload = function () { callback!({ - errMsg: 'getImageInfo:ok', + errMsg: `${API_GET_IMAGE_INFO}:ok`, width: img.naturalWidth, height: img.naturalHeight, path: src.indexOf('/') === 0 ? _getServiceAddress() + src : src, @@ -22,7 +23,7 @@ export const getImageInfo = defineAsyncApi( } img.onerror = function () { callback!({ - errMsg: 'getImageInfo:fail', + errMsg: `${API_GET_IMAGE_INFO}:fail`, }) } img.src = src diff --git a/packages/uni-h5/src/service/api/route/navigateBack.ts b/packages/uni-h5/src/service/api/route/navigateBack.ts index c1f5ca3f6..66beb912b 100644 --- a/packages/uni-h5/src/service/api/route/navigateBack.ts +++ b/packages/uni-h5/src/service/api/route/navigateBack.ts @@ -1,6 +1,26 @@ -import { defineAsyncApi } from '@dcloudio/uni-api' +import { + API_NAVIGATE_BACK, + defineAsyncApi, + getCurrentPageVm, + NavigateBackOptions, + NavigateBackProtocol, +} from '@dcloudio/uni-api' export const navigateBack = defineAsyncApi( - 'navigateBack', - () => {} + API_NAVIGATE_BACK, + (options) => { + let canBack = true + const vm = getCurrentPageVm() + if (vm && vm.$callHook('onBackPress') === true) { + canBack = false + } + if (!canBack) { + return { + errMsg: `${API_NAVIGATE_BACK}:fail onBackPress`, + } + } + getApp().$router.go(-options.delta!) + }, + NavigateBackProtocol, + NavigateBackOptions ) diff --git a/packages/uni-h5/src/service/api/route/navigateTo.ts b/packages/uni-h5/src/service/api/route/navigateTo.ts index 6cb4a69ee..c500b8f14 100644 --- a/packages/uni-h5/src/service/api/route/navigateTo.ts +++ b/packages/uni-h5/src/service/api/route/navigateTo.ts @@ -1,15 +1,31 @@ -import { Router } from 'vue-router' -import { defineAsyncApi } from '@dcloudio/uni-api' +import { isNavigationFailure, Router } from 'vue-router' +import { + API_NAVIGATE_TO, + defineAsyncApi, + NavigateToOptions, + NavigateToProtocol, +} from '@dcloudio/uni-api' import { createPageState } from '../../../framework/plugin/page' export const navigateTo = defineAsyncApi( - 'navigateTo', - (options) => { + API_NAVIGATE_TO, + (options, callback?: Function) => { const router = getApp().$router as Router - router.push({ - path: options.url, - force: true, - state: createPageState('navigateTo'), - }) - } + router + .push({ + path: options.url, + force: true, + state: createPageState('navigateTo'), + }) + .then((failure) => { + if (isNavigationFailure(failure)) { + return callback!({ + errMsg: `${API_NAVIGATE_TO}:fail ${failure.message}`, + }) + } + callback!() + }) + }, + NavigateToProtocol, + NavigateToOptions ) diff --git a/packages/uni-h5/src/service/api/route/reLaunch.ts b/packages/uni-h5/src/service/api/route/reLaunch.ts index e1dfb0664..bb0258f25 100644 --- a/packages/uni-h5/src/service/api/route/reLaunch.ts +++ b/packages/uni-h5/src/service/api/route/reLaunch.ts @@ -1,3 +1,13 @@ -import { defineAsyncApi } from '@dcloudio/uni-api' +import { + API_RE_LAUNCH, + defineAsyncApi, + ReLaunchOptions, + ReLaunchProtocol, +} from '@dcloudio/uni-api' -export const reLaunch = defineAsyncApi('reLaunch', () => {}) +export const reLaunch = defineAsyncApi( + API_RE_LAUNCH, + () => {}, + ReLaunchProtocol, + ReLaunchOptions +) diff --git a/packages/uni-h5/src/service/api/route/redirectTo.ts b/packages/uni-h5/src/service/api/route/redirectTo.ts index 6f1ddfd10..ff2d32328 100644 --- a/packages/uni-h5/src/service/api/route/redirectTo.ts +++ b/packages/uni-h5/src/service/api/route/redirectTo.ts @@ -1,3 +1,13 @@ -import { defineAsyncApi } from '@dcloudio/uni-api' +import { + API_REDIRECT_TO, + defineAsyncApi, + RedirectToOptions, + RedirectToProtocol, +} from '@dcloudio/uni-api' -export const redirectTo = defineAsyncApi('redirectTo', () => {}) +export const redirectTo = defineAsyncApi( + API_REDIRECT_TO, + () => {}, + RedirectToProtocol, + RedirectToOptions +) diff --git a/packages/uni-h5/src/service/api/route/switchTab.ts b/packages/uni-h5/src/service/api/route/switchTab.ts index 6430d3a1b..1280aac8a 100644 --- a/packages/uni-h5/src/service/api/route/switchTab.ts +++ b/packages/uni-h5/src/service/api/route/switchTab.ts @@ -1,3 +1,13 @@ -import { defineAsyncApi } from '@dcloudio/uni-api' +import { + API_SWITCH_TAB, + defineAsyncApi, + SwitchTabOptions, + SwitchTabProtocol, +} from '@dcloudio/uni-api' -export const switchTab = defineAsyncApi('switchTab', () => {}) +export const switchTab = defineAsyncApi( + API_SWITCH_TAB, + () => {}, + SwitchTabProtocol, + SwitchTabOptions +) diff --git a/packages/uni-mp-alipay/dist/uni.api.esm.js b/packages/uni-mp-alipay/dist/uni.api.esm.js index 742069884..6d37b9899 100644 --- a/packages/uni-mp-alipay/dist/uni.api.esm.js +++ b/packages/uni-mp-alipay/dist/uni.api.esm.js @@ -254,6 +254,15 @@ const API_TYPE_TASK = 1; const API_TYPE_SYNC = 2; const API_TYPE_ASYNC = 3; function formatApiArgs(args, options) { + const params = args[0]; + if (!options || + (!isPlainObject(options.formatArgs) && isPlainObject(params))) { + return args; + } + const formatArgs = options.formatArgs; + Object.keys(formatArgs).forEach((name) => { + formatArgs[name](args[0][name], params); + }); return args; } function wrapperOnApi(name, fn) { @@ -268,7 +277,12 @@ function wrapperSyncApi(fn) { function wrapperAsyncApi(name, fn, options) { return (args) => { const callbackId = createAsyncApiCallback(name, args, options); - const res = fn.apply(null, [args, callbackId]); + const res = fn.apply(null, [ + args, + (res) => { + invokeCallback(callbackId, res); + }, + ]); if (res) { invokeCallback(callbackId, res); } @@ -282,7 +296,7 @@ function wrapperApi(fn, name, protocol, options) { return errMsg; } } - return fn.apply(null, formatApiArgs(args)); + return fn.apply(null, formatApiArgs(args, options)); }; } function defineSyncApi(name, fn, protocol, options) { @@ -291,13 +305,13 @@ function defineSyncApi(name, fn, protocol, options) { function defineApi(type, name, fn, protocol, options) { switch (type) { case API_TYPE_ON: - return wrapperApi(wrapperOnApi(name, fn), name, protocol); + return wrapperApi(wrapperOnApi(name, fn), name, protocol, options); case API_TYPE_TASK: - return wrapperApi(wrapperTaskApi(name, fn), name, protocol); + return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options); case API_TYPE_SYNC: - return wrapperApi(wrapperSyncApi(fn), name, protocol); + return wrapperApi(wrapperSyncApi(fn), name, protocol, options); case API_TYPE_ASYNC: - return wrapperApi(wrapperAsyncApi(name, fn, options), name, protocol); + return wrapperApi(wrapperAsyncApi(name, fn, options), name, protocol, options); } } @@ -305,6 +319,7 @@ function getBaseSystemInfo() { return my.getSystemInfoSync() } +const API_UPX2PX = 'upx2px'; const Upx2pxProtocol = [ { name: 'upx', @@ -324,7 +339,7 @@ function checkDeviceWidth() { deviceDPR = pixelRatio; isIOS = platform === 'ios'; } -const upx2px = defineSyncApi('upx2px', (number, newDeviceWidth) => { +const upx2px = defineSyncApi(API_UPX2PX, (number, newDeviceWidth) => { if (deviceWidth === 0) { checkDeviceWidth(); } @@ -452,6 +467,8 @@ function invokeApi(method, api, options, ...params) { return api(options, ...params); } +const API_ADD_INTERCEPTOR = 'addInterceptor'; +const API_REMOVE_INTERCEPTOR = 'removeInterceptor'; const AddInterceptorProtocol = [ { name: 'method', @@ -506,7 +523,7 @@ function removeHook(hooks, hook) { hooks.splice(index, 1); } } -const addInterceptor = defineSyncApi('addInterceptor', (method, interceptor) => { +const addInterceptor = defineSyncApi(API_ADD_INTERCEPTOR, (method, interceptor) => { if (typeof method === 'string' && isPlainObject(interceptor)) { mergeInterceptorHook(scopedInterceptors[method] || (scopedInterceptors[method] = {}), interceptor); } @@ -514,7 +531,7 @@ const addInterceptor = defineSyncApi('addInterceptor', (method, interceptor) => mergeInterceptorHook(globalInterceptors, method); } }, AddInterceptorProtocol); -const removeInterceptor = defineSyncApi('removeInterceptor', (method, interceptor) => { +const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interceptor) => { if (typeof method === 'string') { if (isPlainObject(interceptor)) { removeInterceptorHook(scopedInterceptors[method], interceptor); diff --git a/packages/uni-mp-baidu/dist/uni.api.esm.js b/packages/uni-mp-baidu/dist/uni.api.esm.js index 5c61058f2..43f9a1ceb 100644 --- a/packages/uni-mp-baidu/dist/uni.api.esm.js +++ b/packages/uni-mp-baidu/dist/uni.api.esm.js @@ -254,6 +254,15 @@ const API_TYPE_TASK = 1; const API_TYPE_SYNC = 2; const API_TYPE_ASYNC = 3; function formatApiArgs(args, options) { + const params = args[0]; + if (!options || + (!isPlainObject(options.formatArgs) && isPlainObject(params))) { + return args; + } + const formatArgs = options.formatArgs; + Object.keys(formatArgs).forEach((name) => { + formatArgs[name](args[0][name], params); + }); return args; } function wrapperOnApi(name, fn) { @@ -268,7 +277,12 @@ function wrapperSyncApi(fn) { function wrapperAsyncApi(name, fn, options) { return (args) => { const callbackId = createAsyncApiCallback(name, args, options); - const res = fn.apply(null, [args, callbackId]); + const res = fn.apply(null, [ + args, + (res) => { + invokeCallback(callbackId, res); + }, + ]); if (res) { invokeCallback(callbackId, res); } @@ -282,7 +296,7 @@ function wrapperApi(fn, name, protocol, options) { return errMsg; } } - return fn.apply(null, formatApiArgs(args)); + return fn.apply(null, formatApiArgs(args, options)); }; } function defineSyncApi(name, fn, protocol, options) { @@ -291,13 +305,13 @@ function defineSyncApi(name, fn, protocol, options) { function defineApi(type, name, fn, protocol, options) { switch (type) { case API_TYPE_ON: - return wrapperApi(wrapperOnApi(name, fn), name, protocol); + return wrapperApi(wrapperOnApi(name, fn), name, protocol, options); case API_TYPE_TASK: - return wrapperApi(wrapperTaskApi(name, fn), name, protocol); + return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options); case API_TYPE_SYNC: - return wrapperApi(wrapperSyncApi(fn), name, protocol); + return wrapperApi(wrapperSyncApi(fn), name, protocol, options); case API_TYPE_ASYNC: - return wrapperApi(wrapperAsyncApi(name, fn, options), name, protocol); + return wrapperApi(wrapperAsyncApi(name, fn, options), name, protocol, options); } } @@ -305,6 +319,7 @@ function getBaseSystemInfo() { return swan.getSystemInfoSync() } +const API_UPX2PX = 'upx2px'; const Upx2pxProtocol = [ { name: 'upx', @@ -324,7 +339,7 @@ function checkDeviceWidth() { deviceDPR = pixelRatio; isIOS = platform === 'ios'; } -const upx2px = defineSyncApi('upx2px', (number, newDeviceWidth) => { +const upx2px = defineSyncApi(API_UPX2PX, (number, newDeviceWidth) => { if (deviceWidth === 0) { checkDeviceWidth(); } @@ -452,6 +467,8 @@ function invokeApi(method, api, options, ...params) { return api(options, ...params); } +const API_ADD_INTERCEPTOR = 'addInterceptor'; +const API_REMOVE_INTERCEPTOR = 'removeInterceptor'; const AddInterceptorProtocol = [ { name: 'method', @@ -506,7 +523,7 @@ function removeHook(hooks, hook) { hooks.splice(index, 1); } } -const addInterceptor = defineSyncApi('addInterceptor', (method, interceptor) => { +const addInterceptor = defineSyncApi(API_ADD_INTERCEPTOR, (method, interceptor) => { if (typeof method === 'string' && isPlainObject(interceptor)) { mergeInterceptorHook(scopedInterceptors[method] || (scopedInterceptors[method] = {}), interceptor); } @@ -514,7 +531,7 @@ const addInterceptor = defineSyncApi('addInterceptor', (method, interceptor) => mergeInterceptorHook(globalInterceptors, method); } }, AddInterceptorProtocol); -const removeInterceptor = defineSyncApi('removeInterceptor', (method, interceptor) => { +const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interceptor) => { if (typeof method === 'string') { if (isPlainObject(interceptor)) { removeInterceptorHook(scopedInterceptors[method], interceptor); diff --git a/packages/uni-mp-qq/dist/uni.api.esm.js b/packages/uni-mp-qq/dist/uni.api.esm.js index ee900f0a0..03b5ac5c7 100644 --- a/packages/uni-mp-qq/dist/uni.api.esm.js +++ b/packages/uni-mp-qq/dist/uni.api.esm.js @@ -254,6 +254,15 @@ const API_TYPE_TASK = 1; const API_TYPE_SYNC = 2; const API_TYPE_ASYNC = 3; function formatApiArgs(args, options) { + const params = args[0]; + if (!options || + (!isPlainObject(options.formatArgs) && isPlainObject(params))) { + return args; + } + const formatArgs = options.formatArgs; + Object.keys(formatArgs).forEach((name) => { + formatArgs[name](args[0][name], params); + }); return args; } function wrapperOnApi(name, fn) { @@ -268,7 +277,12 @@ function wrapperSyncApi(fn) { function wrapperAsyncApi(name, fn, options) { return (args) => { const callbackId = createAsyncApiCallback(name, args, options); - const res = fn.apply(null, [args, callbackId]); + const res = fn.apply(null, [ + args, + (res) => { + invokeCallback(callbackId, res); + }, + ]); if (res) { invokeCallback(callbackId, res); } @@ -282,7 +296,7 @@ function wrapperApi(fn, name, protocol, options) { return errMsg; } } - return fn.apply(null, formatApiArgs(args)); + return fn.apply(null, formatApiArgs(args, options)); }; } function defineSyncApi(name, fn, protocol, options) { @@ -291,13 +305,13 @@ function defineSyncApi(name, fn, protocol, options) { function defineApi(type, name, fn, protocol, options) { switch (type) { case API_TYPE_ON: - return wrapperApi(wrapperOnApi(name, fn), name, protocol); + return wrapperApi(wrapperOnApi(name, fn), name, protocol, options); case API_TYPE_TASK: - return wrapperApi(wrapperTaskApi(name, fn), name, protocol); + return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options); case API_TYPE_SYNC: - return wrapperApi(wrapperSyncApi(fn), name, protocol); + return wrapperApi(wrapperSyncApi(fn), name, protocol, options); case API_TYPE_ASYNC: - return wrapperApi(wrapperAsyncApi(name, fn, options), name, protocol); + return wrapperApi(wrapperAsyncApi(name, fn, options), name, protocol, options); } } @@ -305,6 +319,7 @@ function getBaseSystemInfo() { return qq.getSystemInfoSync() } +const API_UPX2PX = 'upx2px'; const Upx2pxProtocol = [ { name: 'upx', @@ -324,7 +339,7 @@ function checkDeviceWidth() { deviceDPR = pixelRatio; isIOS = platform === 'ios'; } -const upx2px = defineSyncApi('upx2px', (number, newDeviceWidth) => { +const upx2px = defineSyncApi(API_UPX2PX, (number, newDeviceWidth) => { if (deviceWidth === 0) { checkDeviceWidth(); } @@ -452,6 +467,8 @@ function invokeApi(method, api, options, ...params) { return api(options, ...params); } +const API_ADD_INTERCEPTOR = 'addInterceptor'; +const API_REMOVE_INTERCEPTOR = 'removeInterceptor'; const AddInterceptorProtocol = [ { name: 'method', @@ -506,7 +523,7 @@ function removeHook(hooks, hook) { hooks.splice(index, 1); } } -const addInterceptor = defineSyncApi('addInterceptor', (method, interceptor) => { +const addInterceptor = defineSyncApi(API_ADD_INTERCEPTOR, (method, interceptor) => { if (typeof method === 'string' && isPlainObject(interceptor)) { mergeInterceptorHook(scopedInterceptors[method] || (scopedInterceptors[method] = {}), interceptor); } @@ -514,7 +531,7 @@ const addInterceptor = defineSyncApi('addInterceptor', (method, interceptor) => mergeInterceptorHook(globalInterceptors, method); } }, AddInterceptorProtocol); -const removeInterceptor = defineSyncApi('removeInterceptor', (method, interceptor) => { +const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interceptor) => { if (typeof method === 'string') { if (isPlainObject(interceptor)) { removeInterceptorHook(scopedInterceptors[method], interceptor); diff --git a/packages/uni-mp-toutiao/dist/uni.api.esm.js b/packages/uni-mp-toutiao/dist/uni.api.esm.js index e0aedf590..7e7185df2 100644 --- a/packages/uni-mp-toutiao/dist/uni.api.esm.js +++ b/packages/uni-mp-toutiao/dist/uni.api.esm.js @@ -254,6 +254,15 @@ const API_TYPE_TASK = 1; const API_TYPE_SYNC = 2; const API_TYPE_ASYNC = 3; function formatApiArgs(args, options) { + const params = args[0]; + if (!options || + (!isPlainObject(options.formatArgs) && isPlainObject(params))) { + return args; + } + const formatArgs = options.formatArgs; + Object.keys(formatArgs).forEach((name) => { + formatArgs[name](args[0][name], params); + }); return args; } function wrapperOnApi(name, fn) { @@ -268,7 +277,12 @@ function wrapperSyncApi(fn) { function wrapperAsyncApi(name, fn, options) { return (args) => { const callbackId = createAsyncApiCallback(name, args, options); - const res = fn.apply(null, [args, callbackId]); + const res = fn.apply(null, [ + args, + (res) => { + invokeCallback(callbackId, res); + }, + ]); if (res) { invokeCallback(callbackId, res); } @@ -282,7 +296,7 @@ function wrapperApi(fn, name, protocol, options) { return errMsg; } } - return fn.apply(null, formatApiArgs(args)); + return fn.apply(null, formatApiArgs(args, options)); }; } function defineSyncApi(name, fn, protocol, options) { @@ -291,13 +305,13 @@ function defineSyncApi(name, fn, protocol, options) { function defineApi(type, name, fn, protocol, options) { switch (type) { case API_TYPE_ON: - return wrapperApi(wrapperOnApi(name, fn), name, protocol); + return wrapperApi(wrapperOnApi(name, fn), name, protocol, options); case API_TYPE_TASK: - return wrapperApi(wrapperTaskApi(name, fn), name, protocol); + return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options); case API_TYPE_SYNC: - return wrapperApi(wrapperSyncApi(fn), name, protocol); + return wrapperApi(wrapperSyncApi(fn), name, protocol, options); case API_TYPE_ASYNC: - return wrapperApi(wrapperAsyncApi(name, fn, options), name, protocol); + return wrapperApi(wrapperAsyncApi(name, fn, options), name, protocol, options); } } @@ -305,6 +319,7 @@ function getBaseSystemInfo() { return tt.getSystemInfoSync() } +const API_UPX2PX = 'upx2px'; const Upx2pxProtocol = [ { name: 'upx', @@ -324,7 +339,7 @@ function checkDeviceWidth() { deviceDPR = pixelRatio; isIOS = platform === 'ios'; } -const upx2px = defineSyncApi('upx2px', (number, newDeviceWidth) => { +const upx2px = defineSyncApi(API_UPX2PX, (number, newDeviceWidth) => { if (deviceWidth === 0) { checkDeviceWidth(); } @@ -452,6 +467,8 @@ function invokeApi(method, api, options, ...params) { return api(options, ...params); } +const API_ADD_INTERCEPTOR = 'addInterceptor'; +const API_REMOVE_INTERCEPTOR = 'removeInterceptor'; const AddInterceptorProtocol = [ { name: 'method', @@ -506,7 +523,7 @@ function removeHook(hooks, hook) { hooks.splice(index, 1); } } -const addInterceptor = defineSyncApi('addInterceptor', (method, interceptor) => { +const addInterceptor = defineSyncApi(API_ADD_INTERCEPTOR, (method, interceptor) => { if (typeof method === 'string' && isPlainObject(interceptor)) { mergeInterceptorHook(scopedInterceptors[method] || (scopedInterceptors[method] = {}), interceptor); } @@ -514,7 +531,7 @@ const addInterceptor = defineSyncApi('addInterceptor', (method, interceptor) => mergeInterceptorHook(globalInterceptors, method); } }, AddInterceptorProtocol); -const removeInterceptor = defineSyncApi('removeInterceptor', (method, interceptor) => { +const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interceptor) => { if (typeof method === 'string') { if (isPlainObject(interceptor)) { removeInterceptorHook(scopedInterceptors[method], interceptor); diff --git a/packages/uni-mp-weixin/dist/uni.api.esm.js b/packages/uni-mp-weixin/dist/uni.api.esm.js index c83959e42..2b678a47b 100644 --- a/packages/uni-mp-weixin/dist/uni.api.esm.js +++ b/packages/uni-mp-weixin/dist/uni.api.esm.js @@ -254,6 +254,15 @@ const API_TYPE_TASK = 1; const API_TYPE_SYNC = 2; const API_TYPE_ASYNC = 3; function formatApiArgs(args, options) { + const params = args[0]; + if (!options || + (!isPlainObject(options.formatArgs) && isPlainObject(params))) { + return args; + } + const formatArgs = options.formatArgs; + Object.keys(formatArgs).forEach((name) => { + formatArgs[name](args[0][name], params); + }); return args; } function wrapperOnApi(name, fn) { @@ -268,7 +277,12 @@ function wrapperSyncApi(fn) { function wrapperAsyncApi(name, fn, options) { return (args) => { const callbackId = createAsyncApiCallback(name, args, options); - const res = fn.apply(null, [args, callbackId]); + const res = fn.apply(null, [ + args, + (res) => { + invokeCallback(callbackId, res); + }, + ]); if (res) { invokeCallback(callbackId, res); } @@ -282,7 +296,7 @@ function wrapperApi(fn, name, protocol, options) { return errMsg; } } - return fn.apply(null, formatApiArgs(args)); + return fn.apply(null, formatApiArgs(args, options)); }; } function defineSyncApi(name, fn, protocol, options) { @@ -291,13 +305,13 @@ function defineSyncApi(name, fn, protocol, options) { function defineApi(type, name, fn, protocol, options) { switch (type) { case API_TYPE_ON: - return wrapperApi(wrapperOnApi(name, fn), name, protocol); + return wrapperApi(wrapperOnApi(name, fn), name, protocol, options); case API_TYPE_TASK: - return wrapperApi(wrapperTaskApi(name, fn), name, protocol); + return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options); case API_TYPE_SYNC: - return wrapperApi(wrapperSyncApi(fn), name, protocol); + return wrapperApi(wrapperSyncApi(fn), name, protocol, options); case API_TYPE_ASYNC: - return wrapperApi(wrapperAsyncApi(name, fn, options), name, protocol); + return wrapperApi(wrapperAsyncApi(name, fn, options), name, protocol, options); } } @@ -305,6 +319,7 @@ function getBaseSystemInfo() { return wx.getSystemInfoSync() } +const API_UPX2PX = 'upx2px'; const Upx2pxProtocol = [ { name: 'upx', @@ -324,7 +339,7 @@ function checkDeviceWidth() { deviceDPR = pixelRatio; isIOS = platform === 'ios'; } -const upx2px = defineSyncApi('upx2px', (number, newDeviceWidth) => { +const upx2px = defineSyncApi(API_UPX2PX, (number, newDeviceWidth) => { if (deviceWidth === 0) { checkDeviceWidth(); } @@ -452,6 +467,8 @@ function invokeApi(method, api, options, ...params) { return api(options, ...params); } +const API_ADD_INTERCEPTOR = 'addInterceptor'; +const API_REMOVE_INTERCEPTOR = 'removeInterceptor'; const AddInterceptorProtocol = [ { name: 'method', @@ -506,7 +523,7 @@ function removeHook(hooks, hook) { hooks.splice(index, 1); } } -const addInterceptor = defineSyncApi('addInterceptor', (method, interceptor) => { +const addInterceptor = defineSyncApi(API_ADD_INTERCEPTOR, (method, interceptor) => { if (typeof method === 'string' && isPlainObject(interceptor)) { mergeInterceptorHook(scopedInterceptors[method] || (scopedInterceptors[method] = {}), interceptor); } @@ -514,7 +531,7 @@ const addInterceptor = defineSyncApi('addInterceptor', (method, interceptor) => mergeInterceptorHook(globalInterceptors, method); } }, AddInterceptorProtocol); -const removeInterceptor = defineSyncApi('removeInterceptor', (method, interceptor) => { +const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interceptor) => { if (typeof method === 'string') { if (isPlainObject(interceptor)) { removeInterceptorHook(scopedInterceptors[method], interceptor); diff --git a/packages/uni-quickapp-webview/dist/uni.api.esm.js b/packages/uni-quickapp-webview/dist/uni.api.esm.js index 4d2deebc0..546a31a48 100644 --- a/packages/uni-quickapp-webview/dist/uni.api.esm.js +++ b/packages/uni-quickapp-webview/dist/uni.api.esm.js @@ -254,6 +254,15 @@ const API_TYPE_TASK = 1; const API_TYPE_SYNC = 2; const API_TYPE_ASYNC = 3; function formatApiArgs(args, options) { + const params = args[0]; + if (!options || + (!isPlainObject(options.formatArgs) && isPlainObject(params))) { + return args; + } + const formatArgs = options.formatArgs; + Object.keys(formatArgs).forEach((name) => { + formatArgs[name](args[0][name], params); + }); return args; } function wrapperOnApi(name, fn) { @@ -268,7 +277,12 @@ function wrapperSyncApi(fn) { function wrapperAsyncApi(name, fn, options) { return (args) => { const callbackId = createAsyncApiCallback(name, args, options); - const res = fn.apply(null, [args, callbackId]); + const res = fn.apply(null, [ + args, + (res) => { + invokeCallback(callbackId, res); + }, + ]); if (res) { invokeCallback(callbackId, res); } @@ -282,7 +296,7 @@ function wrapperApi(fn, name, protocol, options) { return errMsg; } } - return fn.apply(null, formatApiArgs(args)); + return fn.apply(null, formatApiArgs(args, options)); }; } function defineSyncApi(name, fn, protocol, options) { @@ -291,13 +305,13 @@ function defineSyncApi(name, fn, protocol, options) { function defineApi(type, name, fn, protocol, options) { switch (type) { case API_TYPE_ON: - return wrapperApi(wrapperOnApi(name, fn), name, protocol); + return wrapperApi(wrapperOnApi(name, fn), name, protocol, options); case API_TYPE_TASK: - return wrapperApi(wrapperTaskApi(name, fn), name, protocol); + return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options); case API_TYPE_SYNC: - return wrapperApi(wrapperSyncApi(fn), name, protocol); + return wrapperApi(wrapperSyncApi(fn), name, protocol, options); case API_TYPE_ASYNC: - return wrapperApi(wrapperAsyncApi(name, fn, options), name, protocol); + return wrapperApi(wrapperAsyncApi(name, fn, options), name, protocol, options); } } @@ -305,6 +319,7 @@ function getBaseSystemInfo() { return qa.getSystemInfoSync() } +const API_UPX2PX = 'upx2px'; const Upx2pxProtocol = [ { name: 'upx', @@ -324,7 +339,7 @@ function checkDeviceWidth() { deviceDPR = pixelRatio; isIOS = platform === 'ios'; } -const upx2px = defineSyncApi('upx2px', (number, newDeviceWidth) => { +const upx2px = defineSyncApi(API_UPX2PX, (number, newDeviceWidth) => { if (deviceWidth === 0) { checkDeviceWidth(); } @@ -452,6 +467,8 @@ function invokeApi(method, api, options, ...params) { return api(options, ...params); } +const API_ADD_INTERCEPTOR = 'addInterceptor'; +const API_REMOVE_INTERCEPTOR = 'removeInterceptor'; const AddInterceptorProtocol = [ { name: 'method', @@ -506,7 +523,7 @@ function removeHook(hooks, hook) { hooks.splice(index, 1); } } -const addInterceptor = defineSyncApi('addInterceptor', (method, interceptor) => { +const addInterceptor = defineSyncApi(API_ADD_INTERCEPTOR, (method, interceptor) => { if (typeof method === 'string' && isPlainObject(interceptor)) { mergeInterceptorHook(scopedInterceptors[method] || (scopedInterceptors[method] = {}), interceptor); } @@ -514,7 +531,7 @@ const addInterceptor = defineSyncApi('addInterceptor', (method, interceptor) => mergeInterceptorHook(globalInterceptors, method); } }, AddInterceptorProtocol); -const removeInterceptor = defineSyncApi('removeInterceptor', (method, interceptor) => { +const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interceptor) => { if (typeof method === 'string') { if (isPlainObject(interceptor)) { removeInterceptorHook(scopedInterceptors[method], interceptor); -- GitLab