Unable to use Clipboard API to write to clipboard in WinUI 3 app with WebView2

Kyle W 1 Reputation point
2022-06-06T01:11:34.667+00:00

Hello,

I am writing a WinUI 3 app with WebView2 in Visual Studio Community 2022 (64-bit) which will load a web page and then the user will click a button on the WinUI 3 window that sends JavaScript to the WebView2 via an "await" with the ExecuteScriptAsync function.

It is my understanding that I must use WinUI 3 with Windows App SDK in order for my final app to be eligible to potentially be published to the Microsoft Store.

The JavaScript is supposed to gather information from the web page and then copy it to the clipboard as an HTML blob using the Clipboard API "clipboard.write()" function, but I currently can't even get it to work with plain text. It gives me a "DOMException: Document is not focused." error from the returned promise from the write() function. I have tried correcting this by putting "MyWebView2.Focus(FocusState.Programmatic);" or "MyWebView2.Focus(FocusState.Pointer);" in the click function of the WinUI 3 button before the JavaScript is called, and then also in the JavaScript I put "window.focus();", but none of it has helped.

It appears that the WebView2 class I am required to use with WinUI 3 is the one located at "Microsoft.UI.Xaml.Controls.WebView2".
It works from that namespace in my app even though the WebView2 Nuget package is not added to the project.
If I add the Nuget package I get an error about CoreWebView2 existing in two namespaces.
I found no way to check the version or update the version for the WebView2 under "Microsoft.UI.Xaml.Controls".
I have updated my Windows App SDK and Visual Studio, but it didn't help.
I searched Google and found nothing helpful.
Hopefully someone can tell me how to fix this.
Otherwise, I suspect it is a bug with the WinUI 3 WebView2 control that will prevent me from writing my app until fixed.
My JavaScript is below.
To see the DOMException error, after I click the button to run the JavaScript, I verify the contents of the clipboard have not changed, and then I right-click the web page in the WebView2 and click Inspect and go to the Console and type MyExportStr to view its value.
The WebView2 is on a TabViewItem on the WinUI 3 window. I don't think that's important, but I could be wrong. The TabViewItem is also selected when this runs.

Thank you in advance,
Kyle Wilbanks

        readonly String JavaScriptHTML =  
            @"  
            try {  
            window.focus();  
            MyExportStr = 'Init';  
            content = 'This is sample text.'  
            blobInput = new Blob([content], {type: 'text/plain'});  
            clipboardItemInput = new ClipboardItem({'text/plain' : blobInput});  
            navigator.clipboard.write([clipboardItemInput]).then(function () {MyExportStr='Success'}, function (errr) {MyExportStr=errr});  
            MyExportStr;  
            } catch(e) {MyExportStr = e};  
            ";  


  
Windows development | Windows App SDK
Microsoft Edge | Microsoft Edge development
{count} votes

1 answer

Sort by: Most helpful
  1. Junjie Zhu - MSFT 21,646 Reputation points
    2022-06-16T08:12:20.22+00:00

    Hello,@Kyle W
    Welcome to Microsoft Q&A!

    We are still trying to solve the problem of clipboard API, we first provide a solution to the current problem.
    Use window.document.execcommand('copy') in javascript.

     private async void myButton_Click(object sender, RoutedEventArgs e)  
            {  
                string text = System.IO.File.ReadAllText(@"C:\**\****\***\Untitled-1.js");  
      
                var res = await webView.ExecuteScriptAsync(text);  
                 
            }  
    

    The javascript related content is below.

    document.featurePolicy.allowedFeatures();  
      
    const span = document.createelement('span')  
    let text = document.body.innertext;  
    span.textcontent = text  
      
    span.style.whiteSpace = 'pre'  
    // Put <span> into the page  
    document.body.appendchild(span)  
    const selection = window.getselection()  
    const range = window.document.createrange()  
    selection.removeallranges()  
    range.selectnode(span)  
    selection.addrange(range)  
      
    // Copy text to clipboard  
    let success = false  
    try {  
        success = window.document.execcommand('copy')  
    } catch (err) {  
        console.log('error', err)  
    }  
    selection.removeallranges()  
    window.document.body.removechild(span)  
    

    211897-untitled-1.txt
    Thank you.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.