macOS WKWebView, NSTextFinder, NSTextFinderBarContainer

I'm trying to get a macOS WKWebView to support a standard find bar.


I had hoped that, since NSScrollView supports NSTextFinderBarContainer this might be easy, but it looks like webView.enclosingScrollView returns nil and webView.scrollView doesn't exist on macOS. I suspect it's because WKWebView is using a custom scrolling/caching solution.


However, following the code from WK2WebDocumentController.m I've made some progress. I can now show the find bar, perform a search, see the highlighted regions in the results, and even click the next button to jump to subsequent finds.


But it doesn't auto-scroll to move to the next occurrence if it's offscreen. And if you scroll manually then the highlights aren't getting regenerated so you have ghost "holes" in the results and searching seems broken.


I've tried observing NSViewBoundsDidChangeNotification and NSViewFrameDidChangeNotification for various views and then calling textFinder's setFindIndicatorNeedsUpdate:YES but that doesn't fix the issue. I think the problem is I can't access the WKWebView's scrollview or clipview reference so I can't listen to it.


Does anyone have this working? I feel like I'm so close!


Oh, I'm targetting Mojave and Catalina.


Thanks!

Replies

You aren't going to have much luck interacting with a web view via native methods. You generally have to do all of that via Javascript.


I have a find feature in my webview-based app. It wasn't all that difficult. Just add the seach bar to the toolbar with all of the required delegates and connections. Then the trick is figuring out how search your HTML content. Once you have that, you can scroll the desired HTML element into view and highlight phrases.


I have a mini demo available on my github site: github.com/etresoft/ESHelp


This is a demo for my help system replacement, but it does have a web view with search. The search in this case is designed to act like Apple's help seach. In my main app, I have more of a traditional search, again using webviews, multiple webviews, actually.

I appreciate the prompt response. I'll check out your example.


For the old WebView class there was a SHCWebViewwork project around that used injected JavaScript and hooked into scrollbar events to support NSTextFinder searching. I was hoping for something less drastic and preferably a solution that didn't involve evaluating JavaScript code to perform the searching. And a similar technique won't work now since we don't have access to the scrollview.

A WKWebView is not a real view. It isn't even running in the same process. Anything you want to do with it has to be done via Javascript.

Just found out this a known internal bug which has been recently fixed. We just need it released in a future Safari/framework update.


https://trac.webkit.org/changeset/247490/webkit


Yay!