From c52e3f74424de89258b97dabc15f91f5ce6826b4 Mon Sep 17 00:00:00 2001 From: Niek Deibus Date: Sun, 12 Jan 2025 13:39:22 +0100 Subject: [PATCH 1/3] fix: Adds support for standard protocol activations on wasm --- .../Helpers/ProtocolActivation.wasm.cs | 80 +++++++++++++------ 1 file changed, 55 insertions(+), 25 deletions(-) diff --git a/src/Uno.UWP/Helpers/ProtocolActivation.wasm.cs b/src/Uno.UWP/Helpers/ProtocolActivation.wasm.cs index d761944c8418..cefbb4b78dde 100644 --- a/src/Uno.UWP/Helpers/ProtocolActivation.wasm.cs +++ b/src/Uno.UWP/Helpers/ProtocolActivation.wasm.cs @@ -1,10 +1,14 @@ using System; +using System.Collections; +using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using System.Runtime.InteropServices.JavaScript; +using System.Runtime.Intrinsics.X86; using System.Web; using Uno.Extensions; using Uno.Foundation.Logging; +using static System.Net.WebRequestMethods; namespace Uno.Helpers { @@ -12,6 +16,33 @@ public static partial class ProtocolActivation { internal const string QueryKey = "unoprotocolactivation"; + private static readonly IEnumerable _predefinedPrefixes = [ + "bitcoin", + "ftp", + "ftps", + "geo", + "im", + "irc", + "ircs", + "magnet", + "mailto", + "matrix", + "mms", + "news", + "nntp", + "openpgp4fpr", + "sftp", + "sip", + "sms", + "smsto", + "ssh", + "tel", + "urn", + "webcal", + "wtai", + "xmpp" + ]; + /// /// Registers a custom URI scheme for protocol activation on WASM. /// @@ -21,40 +52,39 @@ public static partial class ProtocolActivation public static void RegisterCustomScheme(string scheme, Uri domain, string prompt) { // rules as per https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler - - // The custom scheme's name begins with web+ - if (!scheme.StartsWith("web+", StringComparison.Ordinal)) + if (!_predefinedPrefixes.Contains(scheme)) { - throw new ArgumentException( - "Scheme must start with 'web+'", - nameof(scheme)); - } - - // The custom scheme's name includes at least 1 letter after the web+ prefix - if (scheme.Length == "web+".Length) - { - throw new ArgumentException( - "Scheme must include at least 1 letter after 'web+' prefix", - nameof(scheme)); - } + // The custom scheme's name begins with web+ + if (!scheme.StartsWith("web+", StringComparison.Ordinal)) + { + throw new ArgumentException( + "Scheme must start with 'web+'", + nameof(scheme)); + } - // The custom scheme has only lowercase ASCII letters in its name. - for (int i = "web+".Length; i < scheme.Length; i++) - { - if (scheme[i] is not (>= 'a' and <= 'z')) + // The custom scheme's name includes at least 1 letter after the web+ prefix + if (scheme.Length == "web+".Length) { throw new ArgumentException( - "Scheme must include only lowercase ASCII letters after " + - "the 'web+' prefix", + "Scheme must include at least 1 letter after 'web+' prefix", nameof(scheme)); } - } - if (domain == null) - { - throw new ArgumentNullException(nameof(domain)); + // The custom scheme has only lowercase ASCII letters in its name. + for (int i = "web+".Length; i < scheme.Length; i++) + { + if (scheme[i] is not (>= 'a' and <= 'z')) + { + throw new ArgumentException( + "Scheme must include only lowercase ASCII letters after " + + "the 'web+' prefix", + nameof(scheme)); + } + } } + ArgumentNullException.ThrowIfNull(domain); + if (!domain.IsAbsoluteUri) { throw new ArgumentException( From b3af291525c256498bf2d8eec0f3e1b09c5de406 Mon Sep 17 00:00:00 2001 From: Niek Deibus Date: Sun, 12 Jan 2025 13:46:13 +0100 Subject: [PATCH 2/3] chore: Removed unused Usings in ProtocolActivation.wasm.cs --- src/Uno.UWP/Helpers/ProtocolActivation.wasm.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Uno.UWP/Helpers/ProtocolActivation.wasm.cs b/src/Uno.UWP/Helpers/ProtocolActivation.wasm.cs index cefbb4b78dde..07f898ff0e7c 100644 --- a/src/Uno.UWP/Helpers/ProtocolActivation.wasm.cs +++ b/src/Uno.UWP/Helpers/ProtocolActivation.wasm.cs @@ -1,14 +1,11 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using System.Runtime.InteropServices.JavaScript; -using System.Runtime.Intrinsics.X86; using System.Web; using Uno.Extensions; using Uno.Foundation.Logging; -using static System.Net.WebRequestMethods; namespace Uno.Helpers { From 665b15bd419ab7c317c88a96bf696e56dd6b893e Mon Sep 17 00:00:00 2001 From: Niek Deibus Date: Wed, 15 Jan 2025 18:31:58 +0100 Subject: [PATCH 3/3] chore: Updated protocol-activation doc to reflect standard-protocols on WASM --- doc/articles/features/protocol-activation.md | 35 ++++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/doc/articles/features/protocol-activation.md b/doc/articles/features/protocol-activation.md index 58d11ba2176a..3688b9d35641 100644 --- a/doc/articles/features/protocol-activation.md +++ b/doc/articles/features/protocol-activation.md @@ -46,24 +46,53 @@ If your target framework is Android 12, you must also add `Exported = true` to t ### WASM -WASM implementation uses the [`Navigator.registerProtocolHandler` API](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler). This has several limitations for the custom scheme: +WASM implementation uses the [`Navigator.registerProtocolHandler` API](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler). + +This has several limitations when using a custom scheme: - The custom scheme's name must begin with `web+` - The custom scheme's name must include at least 1 letter after the `web+` prefix - The custom scheme must have only lowercase ASCII letters in its name. +You can also use one of the following supported schemes instead: + +- `bitcoin` +- `ftp` +- `ftps` +- `geo` +- `im` +- `irc` +- `ircs` +- `magnet` +- `mailto` +- `matrix` +- `mms` +- `news` +- `nntp` +- `openpgp4fpr` +- `sftp` +- `sip` +- `sms` +- `smsto` +- `ssh` +- `tel` +- `urn` +- `webcal` +- `wtai` +- `xmpp` + To register the custom theme, call the WASM-specific `Uno.Helpers.ProtocolActivation` API when appropriate to let the user confirm URI handler association: ```csharp #if __WASM__ Uno.Helpers.ProtocolActivation.RegisterCustomScheme( - "web+myscheme", + "web+myscheme", new System.Uri("http://localhost:55838/"), "Can we handle web+myscheme links?"); #endif ``` -The first argument is the scheme name, the second is the base URL of your application (it must match the current domain to be registered successfully), and the third is a text prompt, which will be displayed to the user to ask for permission. +The first argument is the scheme name, the second is the base URL of your application (it must match the current domain to be registered successfully), and the third is a text prompt, which will be displayed to the user to ask for permission (this does not work on all browsers e.g. edge). When a link with the custom scheme gets executed, the browser will navigate to a your URL with additional `unoprotocolactivation` query string key, which will contain the custom URI. Uno internally recognizes this query string key and executes `OnActivated` appropriately.