fabulous-dev / Fabulous

Declarative UI framework for cross-platform mobile & desktop apps, using MVU and F# functional programming
https://fabulous.dev
Apache License 2.0
1.13k stars 122 forks source link

How to avoid opening browser in webview?(UWP) #893

Closed RickyYCheng closed 2 years ago

RickyYCheng commented 2 years ago

when using WebView fabulous.XF(UWP), if you clicked a URL, the app will open your default browser to show the website. I know that in C# uwp you can get the WebView control and then set the event of it then write codes to show your content in your WebView. The question is that I cannot do that in Fabulous 'cuz it's seemed that I cannot get the instance of WebView when creating it use View.WebView( xxx ), and possibly, it is also not the correct way when using MVU architecture. So what is the correct way to solve this problem? :( Thank you so much to the person who gave the answer. :) have a nice day.

SergejDK commented 2 years ago

Hi @RickyYChan, do you have a minimal reproduction for this which you could share?

Did you follow the documentation? https://fsprojects.github.io/Fabulous/Fabulous.XamarinForms/view-if-p-webview.html

Maybe you coudl use ViewRef e.g.

let webviewRef = ViewRef<WebView>()

let view dispatch model = 
    View.WebView(ref=animatedLabelRef) 
RickyYCheng commented 2 years ago

Hi @RickyYChan, do you have a minimal reproduction for this which you could share?

Did you follow the documentation? https://fsprojects.github.io/Fabulous/Fabulous.XamarinForms/view-if-p-webview.html

Maybe you coudl use ViewRef e.g.

let webviewRef = ViewRef<WebView>()

let view dispatch model = 
    View.WebView(ref=animatedLabelRef) 

The only question is: When you clicking a link inside webview in (Fabulous or) Xamarin.Form UWP, your default browser(MS EDGE) will pop up and open the link. And I have no idea to avoid this case

I've checked the doc before I post this issue.

A few days later, I found the question is that -- it's hard to handle new window requests in xamarin.forms uwp webview.
In typically uwp app, we can just do :

// In pure UWP app(C#)
webviewInstance.NewWindowRequest += (sender, e) => {
    e.Handled = true; // will not pop up my browser
    webviewInstance.Source = new Uri(e.Uri); // will update the source of webview
}

// in webview2 of WPF(C#)
wv.CoreWebView2InitializationCompleted += (sender, e) =>
            {
                wv.CoreWebView2.NewWindowRequested += (sender, e) =>
                {
                    e.Handled = true;
                    wv.Source = new Uri(e.Uri);
//                     _addPage(e.Uri);
                };
            };

and then you can just use your webview to continue or you can do something else such as opening a new webview or something instead of opening the browser. (The same thing can be done in Microsoft.WebView2 in WPF or WinForm)

The repo is easy to be built. I'll descript the user behavior first.

  1. add the webview to the content page and set the source. (Bing: https://www.bing.com)
  2. run the app. (debug X64 or X86)
  3. input "Youtube" and then search in Bing.
  4. click the result item.
  5. the default browser pops up.

image

Click this in webview of Fabulous Xamarin.Forms UWP, your browser will open the link and webview has no changes)

Interestingly, if you do this in XF android, the webview will just navigate to the link. Seems like there's no simple way to handle a new window event of webview in Xamarin.Forms( in webview of pure UWP or webview2 in WPF, WINUI, or WinForm, you can achieve this easily).

I have no idea about how to handle this in both Xamarin.Forms and fabulous.

RickyYCheng commented 2 years ago
type Model = 
        {
            None: unit
        }

    type Msg = 
        | None

    let initModel = { None = () }

    let init () = initModel, Cmd.none

    let update (msg:Msg) (model:Model) = initModel, Cmd.none

    let view (model: Model) dispatch =
        View.ContentPage(                    
            backgroundColor = Color.Transparent,
            title ="WebView",                         
            content = 
                View.WebView
                    (
                        source = UrlWebViewSource.op_Implicit "https://www.bing.com"
                    )
        )
SergejDK commented 2 years ago

Thanks for the input. I will check it these days and will give you a feedback on this.

SergejDK commented 2 years ago

@RickyYChan I played with this a bit and this is neither a bug in fabulous nor xamarin.forms.

If you are using bing there is a switch button which opens a new window in browser. See the picture below:

temp

If you are switching it off it works as expected.

Does this help you?

If this is not something that is working for you it may be more of an ms edge-feature/bug. The standard procedure for edge/bing is to open a link in a new tab. That is the reason why I think the behivour is expected. Anyway the switch in the register made everything run smoothly in the webview context for me.

RickyYCheng commented 2 years ago

@RickyYChan I played with this a bit and this is neither a bug in fabulous nor xamarin.forms.

If you are using bing there is a switch button which opens a new window in browser. See the picture below:

temp

If you are switching it off it works as expected.

Does this help you?

If this is not something that is working for you it may be more of an -feature/bug. The standard procedure for edge/bing is to open a link in a new tab. That is the reason why I think the behivour is expected. Anyway the switch in the register made everything run smoothly in the webview context for me.ms edge

I understand what you mean. If we switch that toggled button, the new link will be shown on the same page instead of a new page in bing. Actually, I've tried a lot of search engines already.

If a hyper link(not your search engine) choose to open a new page, seems that there's no way(or no easy way) in xamarin.forms or fabulous to handle that(such as, open it in a new page IN OUR APP, or just use the current page to show that).

The default behaviour of opening a new page is to OPEN A NEW WINDOW in UWP(Xamarin), but sometimes we need to handle it IN OUR APP, such as filtering the links that are not good for children.

So the problem is not what bing decides to do, but how our app handles that. And in my perspective, after days of searching, it seems that there's no way or easy way to do that(In WPF webview2 or UWP(not xamarin) webview, you can set events to handles it easily)

PS:

The standard procedure for edge/bing is to open a link in a new tab. That is the reason why I think the behivour is expected.

I agree with that too. But I think we should be able to deciding the behaviour, such as

  1. By default. UWP(XAMARIN) will open a new window to show that.
  2. Don't open new window, passing the hyper link of the website to a new webview so i can make my app more like a web browser
  3. I just want to show some thing so i decided to show the link in current webview.

As I've decribed before, in pure wpf or uwp, we just have to set events. But in Fabulous.xf(or xamarin.forms), it seems like it's impossible or very hard.

SergejDK commented 2 years ago

@RickyYChan as far as I tested this it is a problem of Xamarin.forms. We only build Fabulous on top of it an dont change the mechanism of the possible events.

So this is sth. that should be done in XF or MAUI.

RickyYCheng commented 2 years ago

@RickyYChan as far as I tested this it is a problem of Xamarin.forms. We only build Fabulous on top of it an dont change the mechanism of the possible events.

So this is sth. that should be done in XF or MAUI.

I think so. I'll close the issue. Thanks for your help. Have a nice day :) 👍