Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Cut, Copy & Paste operations for WKWebView

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:

  • substitute my own responder in place of WKWebView or
  • customize its responses to 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:

  1. to provide persistence
  2. to provide clipboard integration
  3. to provide printing

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:

  1. mark my NSViewController subclass as accepting first responder and override validateMenyItem: there — my implementation was never called
  2. subclass WKWebView and override validateMenuItem: — my implementation was never called
  3. subclass NSWindowController and override validateMenuItem: — my implementation was never called

Now, 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.

like image 610
M. Anthony Aiello Avatar asked Mar 31 '15 19:03

M. Anthony Aiello


2 Answers

... 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.

like image 121
Kappe Avatar answered Nov 18 '22 00:11

Kappe


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.

like image 1
Ming-Yee Iu Avatar answered Nov 17 '22 22:11

Ming-Yee Iu