1

Due to file-writing security issues we have tried to switch our app from using ms-appx-web: to using ms-appdata:. But it immediately fails because we rely on window.external.notify() which works fine with ms-appx-web: but seems to behave as a no-op with ms-appdata:. As a test we loaded the following html into a WebView object:

<html>
<head>
    <script>
        function demofunc( str ) {
            document.getElementById("demo").innerHTML += str;
            window.external.notify( str );
        }
    </script>
</head>
<body onLoad="demofunc('demofunc()');">
    demo &lt;body&gt;
    <div id="demo"></div>
</body>
</html>

which produces this result as it should:

demo <body> 
demofunc()

BUT, does NOT produce a popup message of any kind. Why? Clearly the demofunc() method is being called to add the second line of output in the demo div, but window.external.notify() is not producing a popup message. Are there special rules regarding notify() along with ms-appdata:?

Update - the question Can't run javascript alerts in universal app's webview at payment gateway is similar and works for ms-appx-web: but not for ms-appdata:. That question catches ScriptNotify() which then uses Windows.UI.Popups.MessageDialog to popup a dialog. With ms-appx-web: the ScriptNotify() is called but with ms-appdata: the ScriptNotify() is not called. That is our problem, there is no popup occurring.

Community
  • 1
  • 1
  • Maybe this will help? https://social.msdn.microsoft.com/Forums/en-US/bdde7d0f-b1dd-4708-95a9-afe1a50dbb75/script-notify-for-msappdata?forum=w81prevwCsharp – NewToJS Apr 18 '17 at 18:21
  • Possible duplicate of [Can't run javascript alerts in universal app's webview at payment gateway](http://stackoverflow.com/questions/31804380/cant-run-javascript-alerts-in-universal-apps-webview-at-payment-gateway) – AVK Apr 18 '17 at 18:46
  • Thank you for the link, it is very interesting. It seems to address catching the notify() event and running another method, which is indeed quite useful. But we also really need to popup a dialog message for the user. The missing popup dialog is actually the most important reason for this post. – user3334340 Apr 18 '17 at 18:46
  • Possible duplicate of [How to receive scriptNotify from html in appdata on UWP c#](http://stackoverflow.com/questions/39041215/how-to-receive-scriptnotify-from-html-in-appdata-on-uwp-c-sharp) – Jay Zuo Apr 20 '17 at 12:34

1 Answers1

2

But it immediately fails because we rely on window.external.notify() which works fine with ms-appx-web: but seems to behave as a no-op with ms-appdata:.

For your scenario please use the scheme ms-local-stream:///, rather than ms-appdata:///. And I have tested ms-local-stream:/// scheme, it is working pretty well.

To use the NavigateToLocalStreamUri method, you must pass in an IUriToStreamResolver implementation that translates a URI pattern into a content stream. Please reference the following code.

StreamUriWinRTResolver

public sealed class StreamUriWinRTResolver : IUriToStreamResolver
    {
        /// <summary>
        /// The entry point for resolving a Uri to a stream.
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        public IAsyncOperation<IInputStream> UriToStreamAsync(Uri uri)
        {
            if (uri == null)
            {
                throw new Exception();
            }
            string path = uri.AbsolutePath;
            // Because of the signature of this method, it can't use await, so we
            // call into a separate helper method that can use the C# await pattern.
            return getContent(path).AsAsyncOperation();
        }

        /// <summary>
        /// Helper that maps the path to package content and resolves the Uri
        /// Uses the C# await pattern to coordinate async operations
        /// </summary>
        private async Task<IInputStream> getContent(string path)
        {
            // We use a package folder as the source, but the same principle should apply
            // when supplying content from other locations
            try
            {
                Uri localUri = new Uri("ms-appdata:///local" + path);
                StorageFile f = await StorageFile.GetFileFromApplicationUriAsync(localUri);
                IRandomAccessStream stream = await f.OpenAsync(FileAccessMode.Read);
                return stream.GetInputStreamAt(0);
            }
            catch (Exception) { throw new Exception("Invalid path"); }
        }
    }

MainPage

public MainPage()
 {
     this.InitializeComponent();
     MyWebView.ScriptNotify += MyWebView_ScriptNotify;
     Uri url = MyWebView.BuildLocalStreamUri("MyTag", "/Test/HomePage.html");
     StreamUriWinRTResolver myResolver = new StreamUriWinRTResolver();
     MyWebView.NavigateToLocalStreamUri(url, myResolver);
 }

I have uploaded the code sample to github. Please check.

Jay Zuo
  • 15,653
  • 2
  • 25
  • 49
Nico Zhu
  • 32,367
  • 2
  • 15
  • 36
  • Thank you, this does indeed solve the problem of the popup dialog not showing. Apparently UWP does not allow Javascript to initiate a popup using ms-appdata but does allow it using ms-local-stream. – user3334340 Apr 19 '17 at 18:25