locked
How I can get selection value with WKWebView before CanPerform calling? RRS feed

  • Question

  • User280874 posted

    My problem is this: Before returning true or false from CanPerform, I need to check some value from js (getSelection), and only after that I can return. This is my code:

    public class CustomWKWebView : WKWebView
        {
            private const string SelectorOne = "One:";
    
            private const string SelectorTwo = "Two:";
    
            public CustomWKWebView(CGRect frame, WKWebViewConfiguration configuration) : base(frame, configuration)
            {
                _menu = UIMenuController.SharedMenuController;
    
                _menu.MenuItems = new[]
                {
                new UIMenuItem("One", new ObjCRuntime.Selector(SelectorOne)),
                new UIMenuItem("Two", new ObjCRuntime.Selector(SelectorTwo))
            }
    
            public override bool CanPerform(ObjCRuntime.Selector action, NSObject withSender)
            {
                /*this is a deadlock*/
                var checkValue = EvaluateJavaScriptAsync($"window.getSelection();").Result;
                if (checkValue)
                    return true;
                return false;
            }
        }
    

    But so solution is wrong. I thank all in advance. And waiting for your proposal.

    Tuesday, July 7, 2020 5:59 AM

All replies

  • User369979 posted

    We can't run an async method in an override method. Try to retrieve the selected text in your One: method. Try to only display the custom menus like:

    public override bool CanPerform(ObjCRuntime.Selector action, NSObject withSender)
    {
        /*this is a deadlock*/
        //var checkValue = await EvaluateJavaScriptAsync($"window.getSelection();");
        //if (checkValue)
        //    return true;
    
        if (action.Name == "One:" || action.Name == "Two:")
        {
            return true;
        }
        return false;
    }
    

    And retrieve the text like:

    [Export("One:")]
    async void OneEvent(NSObject menu)
    {
        var txt = await EvaluateJavaScriptAsync("window.getSelection().toString();");
    }
    
    Tuesday, July 7, 2020 9:14 AM
  • User280874 posted

    @LandLu said: We can't run an async method in an override method. Try to retrieve the selected text in your One: method. Try to only display the custom menus like:

    public override bool CanPerform(ObjCRuntime.Selector action, NSObject withSender)
    {
        /*this is a deadlock*/
        //var checkValue = await EvaluateJavaScriptAsync($"window.getSelection();");
        //if (checkValue)
        //    return true;
    
        if (action.Name == "One:" || action.Name == "Two:")
        {
            return true;
        }
        return false;
    }
    

    And retrieve the text like:

    [Export("One:")]
    async void OneEvent(NSObject menu)
    {
        var txt = await EvaluateJavaScriptAsync("window.getSelection().toString();");
    }
    

    The thing is I need to know selection info to decide what menu items will add to menu. The main task is define menu items based on selection info.

    Wednesday, July 8, 2020 6:19 PM
  • User369979 posted

    We can't retrieve it in the CanPerform event.

    Thursday, July 9, 2020 7:38 AM