I am developing a Cocoa application to wrap a JavaScript web application I have developed that provides editing of SVG graphics. I have the following question, which is motivated by a desire to customize the Cut, Copy and Paste operations and their associated menu items.
How can I either:
validateMenuItem:
and the cut:
, copy:
and paste:
selectors? I am particularly interested in solutions that retain the useful WKWebView functionality of providing Cut, Copy and Paste for text fields.
Any help would be much appreciated. Detail follows.
The purpose of my Cocoa wrapper is threefold:
I've achieved 1, but am blocked on 2 and 3; this question is about 2.
Specifically, I cannot get the framework to call any implementation of validateMenuItem:
that I provide — as a result, I have no control over when the Cut, Copy or Paste menu items are available for the user to select.
I have tried the following:
validateMenyItem:
there — my implementation was never calledvalidateMenuItem:
— my implementation was never calledvalidateMenuItem:
— my implementation was never calledNow, my wrapped web app has some text fields. When I give one of those focus and when it is appropriate (text is on the clipboard; I highlight some text), the Cut, Copy and Paste options in my Edit menu automagically activate. They even work. (I like this functionality, and would like to retain it.) I therefore suspect that what is happening is that the WKWebView, as my current first responder, is intercepting any call to validateMenuItem:
along the responder chain. But I also need to be able to activate menu items according to other states in my wrapped web app — for example, when the user selects an SVG graphic.
Update
I have done additional digging, in trying to figure out a solution to my problem. In my WKWebView subclass, I added a custom @IBAction
. I created a menu item for it on my story board and wired the menu item to FirstResponder, choosing my new action.
And my validateMenuItem:
on my WKWebView subclass was called. But only for that new selector, not for the copy:
selector associated with the @IBAction
that I had previously added to my WKWebView subclass.
Now, my copy:
method, marked with @IBAction and having the method signature for things that Interface Builder (or whatever it's called these days) is able to use, is not marked override
. When I tried to mark it override
, I got an error. Apparently, WKWebView does not provide a copy:id
method — even though it provides Copy functionality and handles the menu item correctly, when text in a text field is selected.
So it appears that, somehow, WKWebView automatically (and always) handles validation for certain selectors typically bound to menus — specifically, cut:
, copy:
and paste:
. Moreover, subclassing WKWebView and overriding validateMenuItem:
is insufficient to interrupt/take control over this default behavior. Which seems odd.
But from reading other posts on WKWebView on StackOverflow, I am aware that WKWebView is actually quite a complex piece of functionality. Of particular interest/concern to me is that WKWebView actually runs the web content in a separate process. I therefore wonder if something related to that separate process is responsible for menu validation and handling cut:
, copy:
and paste:
— something internal to the framework and to which I don't have access.
I'm still hoping for a solution. Hopefully the above update will prove useful.
... 5 years later....
Please have a look at my own answer to another problem: Manipulate paste content in WKWebView this solution involves method Swizzling and probably can easily solve your problem too.
Oddly enough, I was also looking at porting over a vector design tool to the Mac via WKWebView and encountered the same problem. It looks like you can actually control the cut/copy/paste menu items from inside JavaScript. If you add beforecopy
and beforecut
event handlers and preventDefault()
them, then the cut and copy menu items will be enabled. I can't seem to enable the paste menu item though. I think that may be due to a long-running bug in WebKit. You can still ⌘-V on the keyboard, and the paste will still happen because in that case, WebKit will skip calling beforepaste
and just trigger the paste
event directly. I just can't figure out enabling the paste menu item. As a workaround, I've created a "fake" Paste menu option that doesn't go to the normal paste:
selector but to my own selector that the WKWebView won't intercept.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With