5

Currently, I am working on a UNO platform application which should display dynamically created HTML code in a WebView. This is working fine on UWP and Android, but not in the compiled WebAssembly. Is there some kind of workaround I could use here? I thought about a simple IFRAME, but obviously there is no possibility to include HTML in the XAML file. Or am I wrong?

To be more specific: The WebView's NavigateToString("<html><head></head><body>BLAH!</body><html>") method leads to the desired results in UWP and Android (iOS not tested).

EdChum
  • 376,765
  • 198
  • 813
  • 562
Syntaxrabbit
  • 126
  • 8

2 Answers2

5

A full featured webview can't be done easily: it's related to xss protections in browsers.

Another reason is simply features priorization. Wasm is still a new target for nventive (the cie behind Uno Platform) and some features still missing to reach parity with iOS and Android. About this, please open an issue on github and explain what is missing for you.

But you can still do something. You can create a custom control in your application like that:

  [ContentProperty(nameof(HtmlContent))]
  public class WasmHtmlContentControl : Control
  {
    public WasmHtmlContentControl()
     : base(htmlTag: "div") // the root HTML tag of your content
    {
    }

    private string _html;

    public string HtmlContent
    {
      get => _html;
      set
      {
        base.SetHtmlContent(html); // this is a protected method on Wasm target
        _html = value;
      }
    }
  }

And the XAML:

  <ctl:WasmHtmlContentControl>
    <!-- xml encoded html -->
    &lt;h1&gt;It works!&lt;/h1&gt;
  </ctl:WasmHtmlContentControl>

Maybe a <![CDATA[ ... ]]> could work... never tried.

Carl de Billy
  • 941
  • 6
  • 13
  • Thank you very much, this sounds like a really usable solution. Is it possible to change the content with a binding, too? (As soon as I can try to implement your solution, I will mark your answer. Maybe, I will add a new question later about accessing local JavaScript files...) – Syntaxrabbit Apr 17 '19 at 11:56
  • 2
    Yes you can set the content using a DependencyProperty... That should be easy to do. The `base.SetHtmlContent()` will replace the whole content of the node. If you want to update just a part of it, you'll need to inject javascript. – Carl de Billy Apr 17 '19 at 13:19
2

Your code sample almost worked. With small adjustments, this is a working solution:

using System;
using System.Collections.Generic;
using System.Text;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Markup;

namespace MyProjectNamespace
{
    [ContentProperty(Name = nameof(HtmlContent))]
    public class WebAssemblyHtmlControl : Control
    {
        public WebAssemblyHtmlControl()
         : base(htmlTag: "div") // the root HTML tag of your content
        {
        }

        private string _html;

        public string HtmlContent
        {
            get => _html;
            set
            {
                base.SetHtmlContent(value); // this is a protected method on Wasm target   
                _html = value;
            }
        }
    }
}

And in XAML:

<WebAssemblyHtmlControl HtmlContent="{Binding HtmlString}" />
Syntaxrabbit
  • 126
  • 8
  • 1
    Additional hint: I succesfully implemented a dynamic "WebView" with the suggested DependencyProperty solution by @carl-de-billy. In addition, I also was able to inject external libraries (ThreeJS in my case) with the already existing RequireJS modular loader, even dynamically at a later point in time. This can be done by creating for example an element with something like [this](https://stackoverflow.com/a/22534608/11367271) in the "onload" attribute's content. – Syntaxrabbit Apr 23 '19 at 00:19
  • Probably there is no need to invoke the base ctor. By default it will become a
    .
    – Tommy May 15 '21 at 19:16