Open external H5 links in system browser

This commit is contained in:
Developer
2026-06-11 22:49:33 +07:00
parent 804b83af66
commit 25dc98f199

View File

@@ -475,6 +475,8 @@ class _H5ShellPageState extends State<H5ShellPage> with WidgetsBindingObserver {
_hideShellCover(generation);
} else if (decoded is Map && decoded['type'] == 'keyboard-bridge-ready') {
unawaited(_syncKeyboardState());
} else if (decoded is Map && decoded['type'] == 'openExternalUrl') {
unawaited(_openExternalUrl(decoded['url']?.toString()));
}
} catch (_) {
if (message.message == 'first-screen-ready') {
@@ -512,6 +514,8 @@ class _H5ShellPageState extends State<H5ShellPage> with WidgetsBindingObserver {
unawaited(openAppSettings());
case 'keyboard-bridge-ready':
unawaited(_syncKeyboardState());
case 'openExternalUrl':
unawaited(_openExternalUrl(decoded['url']?.toString()));
}
} catch (_) {
// Ignore malformed shell messages from web content.
@@ -939,18 +943,52 @@ class _H5ShellPageState extends State<H5ShellPage> with WidgetsBindingObserver {
return NavigationDecision.prevent;
}
const webSchemes = {'http', 'https', 'about', 'data'};
if (webSchemes.contains(uri.scheme)) {
const inWebViewSchemes = {'about', 'data'};
if (inWebViewSchemes.contains(uri.scheme) || _isCurrentH5Origin(uri)) {
return NavigationDecision.navigate;
}
if (uri.scheme == 'http' || uri.scheme == 'https') {
await _openExternalUri(uri);
return NavigationDecision.prevent;
}
await _openExternalUri(uri);
return NavigationDecision.prevent;
}
bool _isCurrentH5Origin(Uri uri) {
final currentUri = Uri.tryParse(_currentSlot.line.url);
if (currentUri == null) {
return false;
}
return uri.scheme == currentUri.scheme &&
uri.host == currentUri.host &&
uri.port == currentUri.port;
}
Future<void> _openExternalUrl(String? rawUrl) async {
final url = rawUrl?.trim();
if (url == null || url.isEmpty) {
return;
}
final uri = Uri.tryParse(url);
if (uri == null || !uri.hasScheme) {
return;
}
await _openExternalUri(uri);
}
Future<void> _openExternalUri(Uri uri) async {
try {
await launchUrl(uri, mode: LaunchMode.externalApplication);
} catch (_) {
// Ignore unsupported custom schemes so the WebView does not navigate to
// an error page.
}
return NavigationDecision.prevent;
}
Future<void> _handleBackNavigation() async {