Bug 199793 - WKWebView PDF viewer doesn't respect selection and callout preferences
Summary: WKWebView PDF viewer doesn't respect selection and callout preferences
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: PDF (show other bugs)
Version: Other
Hardware: All iOS 12
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2019-07-15 01:17 PDT by Josip
Modified: 2019-07-15 16:15 PDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Josip 2019-07-15 01:17:12 PDT
I am trying to disable Copy callout on `WKWebView` for all document types.

Try 1 (JavaScript):
WebKit built in PDF viewer doesn't respect selection and callout preferences set on `WKWebView`.

Executing this JS `document.documentElement.style.webkitUserSelect='none';` in web view that contains PDF doesn't do anything it seems. This works well for any other document type as far as I can tell.

Try 2 (responder chain)

Subclassing `WKWebView` and overriding `canPerformAction` doesn't help either. It seems that this is being called for some actions but not Copy. My guess is that some object deeper in hierarchy (maybe `PDFHostViewController`?) overrides this method and allows Copy action.

All I can think of is to play with private view hierarchies and swizzle this method to hook in behaviour that I need. Are there any other workarounds?

Since PDF preview is transparent for `WKWebView` users I feel both of these approaches should work out of the box?


I am seeing the same behaviour on macOS and iOS.
Comment 1 Josip 2019-07-15 03:47:51 PDT
I disassembled `PDFHostViewController` and it seems that assumption was correct:

```
/* @class PDFHostViewController */
-(bool)canPerformAction:(void *)arg2 withSender:(void *)arg3 {
    rax = (@selector(selectAll:) == arg2 ? 0x1 : 0x0) | (@selector(copy:) == arg2 ? 0x1 : 0x0);
    return rax;
}
```

`PDFHostViewController` explicitly enables selectAll and copy actions.
Comment 2 Josip 2019-07-15 03:51:07 PDT
I am not familiar with specifics of WebKit view hierarchy. Would it be possible to override this method in some of WebKit views and forward to superclass somehow?
Comment 3 Josip 2019-07-15 08:55:10 PDT
For reference:

I managed to workaround this by:

```
if let cls = NSClassFromString("PDFHostViewController") {
  let selector1 = #selector(canPerformAction(_:withSender:))
  let selector2 = #selector(canPerformAction2(_:withSender:))
  if let original = class_getInstanceMethod(cls, selector1),
    let replacement = class_getInstanceMethod(MyObject.self, selector2) {
    let replacemementImp = revert ? original : replacement
    let imp = method_getImplementation(replacemementImp)
    method_setImplementation(original, imp)
  }
}
```
Comment 4 Radar WebKit Bug Importer 2019-07-15 16:15:57 PDT
<rdar://problem/53127343>