/// Mall pages stay in the resident WebView unless H5 explicitly requests an /// external handoff or the URI is handled by the operating system. bool shouldOpenWebUrlExternally(String rawUrl) { final uri = Uri.tryParse(rawUrl); if (uri == null) return false; return const {'tel', 'mailto', 'sms'}.contains(uri.scheme.toLowerCase()) || uri.queryParameters.containsKey('out'); } Uri sanitizeSystemCommunicationUri(Uri uri) { if (uri.scheme.toLowerCase() != 'tel') return uri; final parameterMarker = uri.path.indexOf('&'); final phone = parameterMarker < 0 ? uri.path : uri.path.substring(0, parameterMarker); return Uri(scheme: uri.scheme, path: phone); } bool isTrustedQiyuUrl(String rawUrl) { final uri = Uri.tryParse(rawUrl); if (uri == null || (uri.scheme != 'http' && uri.scheme != 'https') || uri.host.isEmpty) { return false; } final host = uri.host.toLowerCase(); return host == 'qiyukf.com' || host.endsWith('.qiyukf.com') || host == 'qiyukf.cn' || host.endsWith('.qiyukf.cn'); } bool shouldApplyQiyuSafeArea(String rawUrl) => isTrustedQiyuUrl(rawUrl); bool isQiyuClientEntryUrl(String rawUrl) { final path = Uri.tryParse(rawUrl)?.path; return path == '/client' || (path?.startsWith('/client/') ?? false); }