@livx.cc/appwrap 0.47.1 → 0.47.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livx.cc/appwrap",
3
- "version": "0.47.1",
3
+ "version": "0.47.3",
4
4
  "description": "Wrap any PWA into a native app with native capabilities (appwrap runtime + @livx.cc/native-kit).",
5
5
  "license": "MIT",
6
6
  "author": "Elya Livshitz",
@@ -335,6 +335,41 @@ function createAssetServingClient(): android.webkit.WebViewClient {
335
335
  );
336
336
  },
337
337
 
338
+ // External URL schemes (mailto:/tel:/sms:/geo:/intent:/webcal:/market:/…) can't be rendered by the
339
+ // WebView — without this override it tries to LOAD them and dumps a full-page net::ERR_UNKNOWN_URL_SCHEME
340
+ // over the app. Hand every non-WebView scheme to the OS via ACTION_VIEW (intent: via parseUri) and
341
+ // return true so the WebView never navigates. http/https/file/about/blob/data/javascript stay in-WebView.
342
+ shouldOverrideUrlLoading(
343
+ view: android.webkit.WebView,
344
+ request: android.webkit.WebResourceRequest | string
345
+ ): boolean {
346
+ const url: string = typeof request !== 'string' ? String(request.getUrl().toString()) : request;
347
+ const scheme = (url.split(':')[0] || '').toLowerCase();
348
+ if (['http', 'https', 'file', 'about', 'blob', 'data', 'javascript'].includes(scheme)) return false;
349
+ try {
350
+ const intent = scheme === 'intent'
351
+ ? android.content.Intent.parseUri(url, android.content.Intent.URI_INTENT_SCHEME)
352
+ : new android.content.Intent(android.content.Intent.ACTION_VIEW, android.net.Uri.parse(url));
353
+ intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
354
+ try {
355
+ view.getContext().startActivity(intent);
356
+ } catch (notInstalled) {
357
+ // Target app missing. intent: URLs carry `browser_fallback_url` for exactly this (Chrome
358
+ // semantics — e.g. "add to Google Calendar" falls back to the web calendar). Honor it via the
359
+ // OS browser rather than silently dropping the action.
360
+ const fallback = scheme === 'intent' && intent.getStringExtra('browser_fallback_url');
361
+ if (!fallback) throw notInstalled;
362
+ const fb = new android.content.Intent(android.content.Intent.ACTION_VIEW, android.net.Uri.parse(String(fallback)));
363
+ fb.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
364
+ view.getContext().startActivity(fb);
365
+ }
366
+ } catch (e) {
367
+ // No installed app handles the scheme / no fallback — swallow (better a no-op than an error page).
368
+ console.warn('[appwrap] no OS handler for external URL: ' + url + ' (' + e + ')');
369
+ }
370
+ return true;
371
+ },
372
+
338
373
  onPageStarted(view: android.webkit.WebView, _url: string, _favicon: android.graphics.Bitmap): void {
339
374
  // Fallback injection — no-op when the document-start scripts already ran
340
375
  view.evaluateJavascript(buildBootstrapJs(), null as unknown as android.webkit.ValueCallback<string>);