按宿主能力声明启用原生能力
HostBridge 契约沉淀 method 与 capability 白名单 H5 解析 hostCapabilities 并按能力调用原生桥 发布分享弹窗仅在声明 share.open 时显示系统分享 补充能力声明测试和宿主壳文档
This commit is contained in:
@@ -2,12 +2,14 @@ import type {
|
||||
FileExportTextPayload,
|
||||
FileExportTextResult,
|
||||
HapticsImpactPayload,
|
||||
HostBridgeCapability,
|
||||
HostBridgeMethod,
|
||||
HostBridgeRuntimeResult,
|
||||
OpenExternalUrlPayload,
|
||||
ShareOpenPayload,
|
||||
} from '../../../packages/shared/src/contracts/hostBridge';
|
||||
import {
|
||||
isHostBridgeCapability,
|
||||
normalizeHostBridgeExternalUrl,
|
||||
} from '../../../packages/shared/src/contracts/hostBridge';
|
||||
import type {
|
||||
@@ -34,6 +36,7 @@ export type HostRuntimeSnapshot = {
|
||||
hostShell: string | null;
|
||||
hostPlatform: string | null;
|
||||
hostVersion: string | null;
|
||||
hostCapabilities: HostBridgeCapability[];
|
||||
miniProgramEnv: string | null;
|
||||
};
|
||||
|
||||
@@ -103,6 +106,17 @@ async function requestNativeHostBoolean(
|
||||
}
|
||||
}
|
||||
|
||||
function runtimeHasNativeCapability(
|
||||
capability: HostBridgeCapability,
|
||||
context: HostRuntimeContext = {},
|
||||
) {
|
||||
const runtime = getHostRuntime(context);
|
||||
return (
|
||||
runtime.kind === 'native_app' &&
|
||||
runtime.hostCapabilities.includes(capability)
|
||||
);
|
||||
}
|
||||
|
||||
function resolveLocation(context: HostRuntimeContext) {
|
||||
return (
|
||||
context.location ?? (typeof window !== 'undefined' ? window.location : null)
|
||||
@@ -157,6 +171,10 @@ export function resolveHostRuntime(
|
||||
const hostShell = params.get('hostShell');
|
||||
const hostPlatform = params.get('hostPlatform');
|
||||
const hostVersion = params.get('hostVersion');
|
||||
const hostCapabilities = (params.get('hostCapabilities') ?? '')
|
||||
.split(',')
|
||||
.map((capability) => capability.trim())
|
||||
.filter(isHostBridgeCapability);
|
||||
const miniProgramEnv = params.get('miniProgramEnv');
|
||||
const navigatorLike = resolveNavigator(context);
|
||||
const wxBridge = resolveWxBridge(context);
|
||||
@@ -176,6 +194,7 @@ export function resolveHostRuntime(
|
||||
hostShell,
|
||||
hostPlatform,
|
||||
hostVersion,
|
||||
hostCapabilities,
|
||||
miniProgramEnv,
|
||||
};
|
||||
}
|
||||
@@ -193,6 +212,7 @@ export function resolveHostRuntime(
|
||||
hostShell,
|
||||
hostPlatform,
|
||||
hostVersion,
|
||||
hostCapabilities,
|
||||
miniProgramEnv,
|
||||
};
|
||||
}
|
||||
@@ -204,6 +224,7 @@ export function resolveHostRuntime(
|
||||
hostShell,
|
||||
hostPlatform,
|
||||
hostVersion,
|
||||
hostCapabilities,
|
||||
miniProgramEnv,
|
||||
};
|
||||
}
|
||||
@@ -222,6 +243,13 @@ export function isNativeAppRuntime(context: HostRuntimeContext = {}) {
|
||||
return resolveHostRuntime(context).kind === 'native_app';
|
||||
}
|
||||
|
||||
export function canUseNativeHostCapability(
|
||||
capability: HostBridgeCapability,
|
||||
context: HostRuntimeContext = {},
|
||||
) {
|
||||
return runtimeHasNativeCapability(capability, context);
|
||||
}
|
||||
|
||||
export function loadWechatMiniProgramBridge(
|
||||
errorMessage = '请在微信小程序内完成操作',
|
||||
) {
|
||||
@@ -303,6 +331,9 @@ export async function navigateHostNativePage(
|
||||
) {
|
||||
const runtime = getHostRuntime();
|
||||
if (runtime.kind === 'native_app') {
|
||||
if (!runtime.hostCapabilities.includes('navigation.openNativePage')) {
|
||||
return false;
|
||||
}
|
||||
const result = await requestNativeHostBoolean(
|
||||
'navigation.openNativePage',
|
||||
{ url },
|
||||
@@ -325,6 +356,9 @@ export async function navigateHostNativePage(
|
||||
|
||||
export async function requestHostLogin() {
|
||||
if (getHostRuntime().kind === 'native_app') {
|
||||
if (!canUseNativeHostCapability('auth.requestLogin')) {
|
||||
return false;
|
||||
}
|
||||
return await requestNativeHostBoolean('auth.requestLogin');
|
||||
}
|
||||
|
||||
@@ -343,6 +377,9 @@ export async function requestHostPayment({
|
||||
}: HostPaymentRequest) {
|
||||
const runtime = getHostRuntime();
|
||||
if (runtime.kind === 'native_app') {
|
||||
if (!runtime.hostCapabilities.includes('payment.request')) {
|
||||
return false;
|
||||
}
|
||||
return await requestNativeHostBoolean('payment.request', {
|
||||
payload,
|
||||
orderId,
|
||||
@@ -452,6 +489,9 @@ export async function openWechatMiniProgramShareGridPage(
|
||||
|
||||
export function setHostShareTarget(message: unknown) {
|
||||
if (getHostRuntime().kind === 'native_app') {
|
||||
if (!canUseNativeHostCapability('share.setTarget')) {
|
||||
return false;
|
||||
}
|
||||
void requestNativeAppHostBridge('share.setTarget', {
|
||||
target: message,
|
||||
}).catch(() => {
|
||||
@@ -475,7 +515,7 @@ export function setHostShareTarget(message: unknown) {
|
||||
}
|
||||
|
||||
export async function openHostShare(params: HostShareOpenRequest) {
|
||||
if (getHostRuntime().kind !== 'native_app') {
|
||||
if (!canUseNativeHostCapability('share.open')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -487,7 +527,7 @@ export async function openHostShare(params: HostShareOpenRequest) {
|
||||
}
|
||||
|
||||
export async function openHostExternalUrl({ url }: HostExternalUrlRequest) {
|
||||
if (getHostRuntime().kind !== 'native_app') {
|
||||
if (!canUseNativeHostCapability('app.openExternalUrl')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -510,7 +550,7 @@ export function postWechatMiniProgramMessage(message: unknown) {
|
||||
}
|
||||
|
||||
export async function getNativeAppHostRuntime() {
|
||||
if (getHostRuntime().kind !== 'native_app') {
|
||||
if (!canUseNativeHostCapability('host.getRuntime')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -522,7 +562,7 @@ export async function getNativeAppHostRuntime() {
|
||||
export async function writeHostClipboardText({
|
||||
text,
|
||||
}: HostClipboardWriteTextRequest) {
|
||||
if (getHostRuntime().kind !== 'native_app') {
|
||||
if (!canUseNativeHostCapability('clipboard.writeText')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -536,7 +576,7 @@ export async function writeHostClipboardText({
|
||||
export async function exportHostTextFile(
|
||||
params: HostFileExportTextRequest,
|
||||
) {
|
||||
if (getHostRuntime().kind !== 'native_app') {
|
||||
if (!canUseNativeHostCapability('file.exportText')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -557,7 +597,7 @@ export async function exportHostTextFile(
|
||||
export async function requestHostHapticsImpact(
|
||||
params: HostHapticsImpactRequest = {},
|
||||
) {
|
||||
if (getHostRuntime().kind !== 'native_app') {
|
||||
if (!canUseNativeHostCapability('haptics.impact')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -570,7 +610,7 @@ export async function requestHostHapticsImpact(
|
||||
|
||||
export async function setHostAppTitle({ title }: HostAppTitleRequest) {
|
||||
const normalizedTitle = title.trim();
|
||||
if (!normalizedTitle || getHostRuntime().kind !== 'native_app') {
|
||||
if (!normalizedTitle || !canUseNativeHostCapability('app.setTitle')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user