Skip to content

Commit

Permalink
feat(wasm): Added javascript helpers for Wasm, to allow interop with …
Browse files Browse the repository at this point in the history
…javascript after the new packaging system.
  • Loading branch information
carldebilly committed Jul 23, 2020
1 parent 3442621 commit b1d11d0
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 61 deletions.
3 changes: 2 additions & 1 deletion src/AddIns/Uno.UI.Lottie/Uno.UI.Lottie.Wasm.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
<Import Project="..\..\Uno.CrossTargetting.props" />

<ItemGroup>
<ProjectReference Include="..\..\Uno.UI\Uno.UI.Wasm.csproj" />
<ProjectReference Include="..\..\Uno.UI.Runtime.Wasm\Uno.UI.Runtime.Wasm.csproj" />
<ProjectReference Include="..\..\Uno.UI.Wasm\Uno.UI.Wasm.csproj" />
</ItemGroup>

<PropertyGroup>
Expand Down
184 changes: 184 additions & 0 deletions src/Uno.UI.Runtime.WebAssembly/Xaml/UIElementWasmExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
using System;
using Windows.UI.Xaml;
using Uno.UI.Xaml;
using System.Threading.Tasks;
using Uno.Extensions;
using Uno.Foundation;

namespace Windows.UI.Xaml
{
public static class UIElementWasmExtensions
{
/// <summary>
/// Get the Id of the corresponding element in the HTML DOM
/// </summary>
public static string GetHtmlId(this UIElement element)
{
return element.HtmlId.ToString();
}

/// <summary>
/// Set one or many CSS styles on a HTML element.
/// </summary>
/// <remarks>
/// The style is using the CSS syntax format, not the DOM syntax.
/// Ex: for font size, use "font-size", not "fontSize".
/// </remarks>
public static void SetCssStyle(this UIElement element, params (string name, string value)[] styles)
{
WindowManagerInterop.SetStyles(element.HtmlId, styles);
}

/// <summary>
/// Clear one or may CSS styles from a HTML element.
/// </summary>
public static void ResetCssStyle(this UIElement element, params string[] names)
{
WindowManagerInterop.ResetStyle(element.HtmlId, names);
}

/// <summary>
/// Set one of the predefined class
/// </summary>
/// <remarks>
/// Useful to switch a control from different modes when each mode is bound
/// to a specific class.
/// </remarks>
public static void SetCssClass(this UIElement element, string[] classes, int index)
{
WindowManagerInterop.SetClasses(element.HtmlId, classes, index);
}

/// <summary>
/// Add one or many CSS classes to a HTML element, if not present.
/// </summary>
public static void SetCssClasses(this UIElement element, params string[] classesToSet)
{
WindowManagerInterop.SetUnsetCssClasses(element.HtmlId, classesToSet, null);
}

/// <summary>
/// Remove one or many CSS classes from a HTML element, if defined.
/// </summary>
public static void UnsetCssClasses(this UIElement element, params string[] classesToUnset)
{
WindowManagerInterop.SetUnsetCssClasses(element.HtmlId, null, classesToUnset);
}

/// <summary>
/// Set a HTML attribute to an element.
/// </summary>
public static void SetHtmlAttribute(this UIElement element, string name, string value)
{
WindowManagerInterop.SetAttribute(element.HtmlId, name, value);
}

/// <summary>
/// Set multiple HTML attributes to an element at the same time.
/// </summary>
public static void SetHtmlAttributes(this UIElement element, params (string name, string value)[] attributes)
{
WindowManagerInterop.SetAttributes(element.HtmlId, attributes);
}

/// <summary>
/// Clear/remove a HTML attribute from an element.
/// </summary>
public static void RemoteHtmlAttribute(this UIElement element, string name)
{
WindowManagerInterop.RemoveAttribute(element.HtmlId, name);
}

/// <summary>
/// Run javascript in the context of a DOM element.
/// This one is available in the scope as "element".
/// </summary>
/// <remarks>
/// Will work even if the element is not yet loaded into the DOM.
/// </remarks>
public static string ExecuteJavascript(this UIElement element, string jsCode)
{
var js = @$"
(function(element) {{
{jsCode}
}})(Uno.UI.WindowManager.current.getView({element.HtmlId}));
";
return WebAssemblyRuntime.InvokeJS(js);
}

/// <summary>
/// Asynchronously run javascript on a DOM element.
/// This one is available in the scope as "element".
/// The called code is expected to return something awaitable (a Promise).
/// </summary>
/// <remarks>
/// Will work even if the element is not yet loaded into the DOM.
/// </remarks>
public static Task<string> ExecuteJavascriptAsync(this UIElement element, string asyncJsCode)
{
var js = @$"
(function(element) {{
const __f = () => {asyncJsCode};
return __f(element);
}})(Uno.UI.WindowManager.current.getView({element.HtmlId}));
";
return WebAssemblyRuntime.InvokeAsync(js);
}

/// <summary>
/// Set raw HTML Content for this element.
/// Don't use this when there's child elements managed by Uno or you'll
/// get expected results.
/// </summary>
public static void SetHtmlContent(this UIElement element, string html)
{
WindowManagerInterop.SetContentHtml(element.HtmlId, html);
}

/// <summary>
/// Will invoke `addEventListener(<paramref name="eventName"/>)` on the corresponding HTML element.
/// </summary>
public static void RegisterHtmlEventHandler(this UIElement element, string eventName, EventHandler handler)
{
element.RegisterEventHandler(eventName, handler);
}

/// <summary>
/// Unregister previously registered event with RegisterHtmlEventHandler.
/// </summary>
public static void UnregisterHtmlEventHandler(this UIElement element, string eventName, EventHandler handler)
{
element.UnregisterEventHandler(eventName, handler);
}

/// <summary>
/// Will invoke `addEventListener(<paramref name="eventName"/>)` on the corresponding HTML element.
/// </summary>
/// <remarks>
/// For use with CustomEvent("name", {detail:{detail here}}).
/// </remarks>
/// <param name="isDetailJson">
/// True will JSON.stringify the content. False will treat the content as a string.
/// </param>
public static void RegisterHtmlCustomEventHandler(this UIElement element, string eventName, EventHandler<HtmlCustomEventArgs> handler, bool isDetailJson = false)
{
var extractor = isDetailJson
? UIElement.HtmlEventExtractor.CustomEventDetailJsonExtractor
: UIElement.HtmlEventExtractor.CustomEventDetailStringExtractor;

element.RegisterEventHandler(
eventName,
handler,
eventExtractor: extractor,
payloadConverter: (_, s) => new HtmlCustomEventArgs(s));
}

/// <summary>
/// Unregister previously registered event with RegisterHtmlCustomEventHandler.
/// </summary>
public static void UnregisterHtmlCustomEventHandler(this UIElement element, string eventName, EventHandler<HtmlCustomEventArgs> handler)
{
element.UnregisterEventHandler(eventName, handler);
}
}
}
1 change: 1 addition & 0 deletions src/Uno.UI/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
[assembly: InternalsVisibleTo("Uno.UI.Tests.Performance")]
[assembly: InternalsVisibleTo("Uno.UI.Toolkit")]
[assembly: InternalsVisibleTo("Uno.UI.RemoteControl")]
[assembly: InternalsVisibleTo("Uno.UI.Runtime.Wasm")]
[assembly: InternalsVisibleTo("Uno.UI.RuntimeTests")]
[assembly: InternalsVisibleTo("Uno.UI.RuntimeTests.Wasm")]
[assembly: InternalsVisibleTo("Uno.UI.RuntimeTests.Skia")]
Expand Down
7 changes: 1 addition & 6 deletions src/Uno.UI/UI/Xaml/UIElement.wasm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public UIElement(string htmlTag, bool isSvg)
private static Dictionary<Type, string> _htmlTagCache = new Dictionary<Type, string>(FastTypeComparer.Default);
private static Type _htmlElementAttribute;
private static PropertyInfo _htmlTagAttributeTagGetter;
private static Assembly _unoUIAssembly = typeof(UIElement).Assembly;
private static readonly Assembly _unoUIAssembly = typeof(UIElement).Assembly;

private string GetHtmlTag(string htmlTag)
{
Expand Down Expand Up @@ -278,11 +278,6 @@ protected internal void SetNativeTransform(Matrix3x2 matrix)

protected internal void ResetStyle(params string[] names)
{
if (names == null || names.Length == 0)
{
// nothing to do
}

Uno.UI.Xaml.WindowManagerInterop.ResetStyle(HtmlId, names);

}
Expand Down
54 changes: 0 additions & 54 deletions src/Uno.UI/UI/Xaml/UIElementExtensions.wasm.cs

This file was deleted.

5 changes: 5 additions & 0 deletions src/Uno.UI/UI/Xaml/WindowManagerInterop.wasm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,11 @@ private struct WindowManagerDestroyViewParams
#region ResetStyle
internal static void ResetStyle(IntPtr htmlId, string[] names)
{
if (names == null || names.Length == 0)
{
// nothing to do
}

if (UseJavascriptEval)
{
if (names.Length == 1)
Expand Down

0 comments on commit b1d11d0

Please sign in to comment.