Revision: 29482 http://sourceforge.net/p/bibdesk/svn/29482 Author: hofman Date: 2025-08-27 09:39:29 +0000 (Wed, 27 Aug 2025) Log Message: ----------- Move wkwebview subclass to separate files
Modified Paths: -------------- trunk/bibdesk/BDSKTextImportController.m trunk/bibdesk/Bibdesk.xcodeproj/project.pbxproj Added Paths: ----------- trunk/bibdesk/BDSKWKWebView.h trunk/bibdesk/BDSKWKWebView.m Modified: trunk/bibdesk/BDSKTextImportController.m =================================================================== --- trunk/bibdesk/BDSKTextImportController.m 2025-08-27 09:23:32 UTC (rev 29481) +++ trunk/bibdesk/BDSKTextImportController.m 2025-08-27 09:39:29 UTC (rev 29482) @@ -42,6 +42,7 @@ #import "BDSKTypeManager.h" #import "BDSKTypeSelectHelper.h" #import <WebKit/WebKit.h> +#import "BDSKWKWebView.h" #import "BDSKCiteKeyFormatter.h" #import "BDSKFieldNameFormatter.h" #import "BDSKComplexStringFormatter.h" @@ -101,24 +102,8 @@ #define WKNavigationResponsePolicyDownload 2 #endif -@protocol BDSKUIDelegate <WKUIDelegate> -@optional -- (void)webView:(WKWebView *)webView willOpenMenu:(NSMenu *)menu; -- (void)webView:(WKWebView *)webView mouseDidMoveOverLink:(NSString *)link; -- (void)webView:(WKWebView *)webView didChangeSelection:(NSString *)selectedText; -@end - -@interface BDSKWKWebView : WKWebView -@property (nullable, nonatomic, weak) id<BDSKUIDelegate> UIDelegate; -@end - #pragma mark - -@interface BDSKScriptMessageHandler : NSObject <WKScriptMessageHandler> -@end - -#pragma mark - - @interface BDSKTextImportController () <BDSKCitationFormatterDelegate, BDSKDownloadDelegate, WKNavigationDelegate, BDSKUIDelegate> - (void)handleFlagsChangedNotification:(NSNotification *)notification; @@ -1643,81 +1628,3 @@ } @end - -#pragma mark - - -@implementation BDSKWKWebView - -@dynamic UIDelegate; - -- (void)addScriptObserversIfNeeded { - NSString *jsSource = @"" - "function changeSelection(){ window.webkit.messageHandlers.didChangeSelection.postMessage(document.getSelection().toString()); };\n" - "document.addEventListener('selectionchange', changeSelection);\n" - "function hover(){ window.webkit.messageHandlers.mouseDidMoveOverLink.postMessage(this.href); }\n" - "function unhover(){ window.webkit.messageHandlers.mouseDidMoveOverLink.postMessage(null); }\n" - "var links = document.links;\n" - "for(var i=0; i<links.length; i++){\n" - " links[i].addEventListener('mouseover', hover);\n" - " links[i].addEventListener('mouseout', unhover);\n" - "}"; - WKUserContentController *userController = [[self configuration] userContentController]; - if ([[userController userScripts] count] == 0 || [[[userController userScripts] valueForKey:@"source"] containsObject:jsSource] == NO) { - BDSKScriptMessageHandler *messageHandler = [[BDSKScriptMessageHandler alloc] init]; - [userController addScriptMessageHandler:messageHandler name:@"didChangeSelection"]; - [userController addScriptMessageHandler:messageHandler name:@"mouseDidMoveOverLink"]; - WKUserScript *script = [[WKUserScript alloc] initWithSource:jsSource injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:NO]; - [userController addUserScript:script]; - } -} - -- (id)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration { - self = [super initWithFrame:frame configuration:configuration]; - if (self) { - [self addScriptObserversIfNeeded]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)coder { - self = [super initWithCoder:coder]; - if (self) { - [self addScriptObserversIfNeeded]; - } - return self; -} - -- (void)willOpenMenu:(NSMenu *)menu withEvent:(NSEvent *)event { - [super willOpenMenu:menu withEvent:event]; - - if ([[self UIDelegate] respondsToSelector:@selector(webView:willOpenMenu:)]) - [[self UIDelegate] webView:self willOpenMenu:menu]; -} - -@end - -#pragma mark - - -@implementation BDSKScriptMessageHandler - -- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { - WKWebView *webView = [message webView]; - if ([webView isKindOfClass:[BDSKWKWebView class]] == NO) - return; - id<BDSKUIDelegate> delegate = [(BDSKWKWebView *)webView UIDelegate]; - if (delegate == nil) - return; - NSString *name = [message name]; - NSString *body = [message body]; - if ([body isKindOfClass:[NSString class]] == NO) - body = nil; - if ([name isEqualToString:@"mouseDidMoveOverLink"]) { - if ([delegate respondsToSelector:@selector(webView:mouseDidMoveOverLink:)]) - [delegate webView:webView mouseDidMoveOverLink:body]; - } else if ([name isEqualToString:@"didChangeSelection"]) { - if ([delegate respondsToSelector:@selector(webView:didChangeSelection:)]) - [delegate webView:webView didChangeSelection:body]; - } -} - -@end Added: trunk/bibdesk/BDSKWKWebView.h =================================================================== --- trunk/bibdesk/BDSKWKWebView.h (rev 0) +++ trunk/bibdesk/BDSKWKWebView.h 2025-08-27 09:39:29 UTC (rev 29482) @@ -0,0 +1,55 @@ +// +// BDSKWKWebView.h +// BibDesk +// +// Created by Christiaan Hofman on 27/08/2025. +/* + This software is Copyright (c) 2025 + Christiaan Hofman. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Neither the name of Christiaan Hofman nor the names of any + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import <Cocoa/Cocoa.h> +#import <WebKit/WebKit.h> + +NS_ASSUME_NONNULL_BEGIN + +@protocol BDSKUIDelegate <WKUIDelegate> +@optional +- (void)webView:(WKWebView *)webView willOpenMenu:(NSMenu *)menu; +- (void)webView:(WKWebView *)webView mouseDidMoveOverLink:(nullable NSString *)link; +- (void)webView:(WKWebView *)webView didChangeSelection:(nullable NSString *)selectedText; +@end + +@interface BDSKWKWebView : WKWebView +@property (nullable, nonatomic, weak) id<BDSKUIDelegate> UIDelegate; +@end + +NS_ASSUME_NONNULL_END Added: trunk/bibdesk/BDSKWKWebView.m =================================================================== --- trunk/bibdesk/BDSKWKWebView.m (rev 0) +++ trunk/bibdesk/BDSKWKWebView.m 2025-08-27 09:39:29 UTC (rev 29482) @@ -0,0 +1,116 @@ +// +// BDSKWKWebView.m +// BibDesk +// +// Created by Christiaan Hofman on 27/08/2025. +/* + This software is Copyright (c) 2025 + Christiaan Hofman. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Neither the name of Christiaan Hofman nor the names of any + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "BDSKWKWebView.h" + +@interface BDSKScriptMessageHandler : NSObject <WKScriptMessageHandler> +@end + +@implementation BDSKWKWebView + +@dynamic UIDelegate; + +- (void)addScriptObserversIfNeeded { + NSString *jsSource = @"" + "function changeSelection(){ window.webkit.messageHandlers.didChangeSelection.postMessage(document.getSelection().toString()); };\n" + "document.addEventListener('selectionchange', changeSelection);\n" + "function hover(){ window.webkit.messageHandlers.mouseDidMoveOverLink.postMessage(this.href); }\n" + "function unhover(){ window.webkit.messageHandlers.mouseDidMoveOverLink.postMessage(null); }\n" + "var links = document.links;\n" + "for(var i=0; i<links.length; i++){\n" + " links[i].addEventListener('mouseover', hover);\n" + " links[i].addEventListener('mouseout', unhover);\n" + "}"; + WKUserContentController *userController = [[self configuration] userContentController]; + if ([[userController userScripts] count] == 0 || [[[userController userScripts] valueForKey:@"source"] containsObject:jsSource] == NO) { + BDSKScriptMessageHandler *messageHandler = [[BDSKScriptMessageHandler alloc] init]; + [userController addScriptMessageHandler:messageHandler name:@"didChangeSelection"]; + [userController addScriptMessageHandler:messageHandler name:@"mouseDidMoveOverLink"]; + WKUserScript *script = [[WKUserScript alloc] initWithSource:jsSource injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:NO]; + [userController addUserScript:script]; + } +} + +- (id)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration { + self = [super initWithFrame:frame configuration:configuration]; + [self addScriptObserversIfNeeded]; + return self; +} + +- (id)initWithCoder:(NSCoder *)coder { + self = [super initWithCoder:coder]; + [self addScriptObserversIfNeeded]; + return self; +} + +- (void)willOpenMenu:(NSMenu *)menu withEvent:(NSEvent *)event { + [super willOpenMenu:menu withEvent:event]; + + if ([[self UIDelegate] respondsToSelector:@selector(webView:willOpenMenu:)]) + [[self UIDelegate] webView:self willOpenMenu:menu]; +} + +@end + +#pragma mark - + +@implementation BDSKScriptMessageHandler + +- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { + WKWebView *webView = [message webView]; + if ([webView isKindOfClass:[BDSKWKWebView class]] == NO) + return; + id<BDSKUIDelegate> delegate = [(BDSKWKWebView *)webView UIDelegate]; + if (delegate == nil) + return; + + NSString *name = [message name]; + NSString *body = [message body]; + if ([body isKindOfClass:[NSString class]] == NO) + body = nil; + + if ([name isEqualToString:@"mouseDidMoveOverLink"]) { + if ([delegate respondsToSelector:@selector(webView:mouseDidMoveOverLink:)]) + [delegate webView:webView mouseDidMoveOverLink:body]; + } else if ([name isEqualToString:@"didChangeSelection"]) { + if ([delegate respondsToSelector:@selector(webView:didChangeSelection:)]) + [delegate webView:webView didChangeSelection:body]; + } +} + +@end Modified: trunk/bibdesk/Bibdesk.xcodeproj/project.pbxproj =================================================================== --- trunk/bibdesk/Bibdesk.xcodeproj/project.pbxproj 2025-08-27 09:23:32 UTC (rev 29481) +++ trunk/bibdesk/Bibdesk.xcodeproj/project.pbxproj 2025-08-27 09:39:29 UTC (rev 29482) @@ -456,6 +456,8 @@ CE3448020A11302F0026A92A /* BDSKPreviewItem.m in Sources */ = {isa = PBXBuildFile; fileRef = CE3448000A11302F0026A92A /* BDSKPreviewItem.m */; }; CE34A5740B249E0B00755730 /* BDSKMARCParser.m in Sources */ = {isa = PBXBuildFile; fileRef = CE34A5720B249E0B00755730 /* BDSKMARCParser.m */; }; CE35DCEA0A99B1A700029B66 /* BDSKErrorEditor.m in Sources */ = {isa = PBXBuildFile; fileRef = CE35DCE80A99B1A700029B66 /* BDSKErrorEditor.m */; }; + CE375CAF2E5F081200A91CD6 /* BDSKWKWebView.h in Headers */ = {isa = PBXBuildFile; fileRef = CE375CAD2E5F081200A91CD6 /* BDSKWKWebView.h */; }; + CE375CB02E5F081200A91CD6 /* BDSKWKWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = CE375CAE2E5F081200A91CD6 /* BDSKWKWebView.m */; }; CE38FB87091D946A00BCB69D /* BDSKCondition.m in Sources */ = {isa = PBXBuildFile; fileRef = CE38FB83091D946900BCB69D /* BDSKCondition.m */; }; CE38FB89091D946A00BCB69D /* BDSKConditionController.m in Sources */ = {isa = PBXBuildFile; fileRef = CE38FB85091D946A00BCB69D /* BDSKConditionController.m */; }; CE38FB8F091D94A100BCB69D /* BDSKFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = CE38FB8B091D94A100BCB69D /* BDSKFilter.m */; }; @@ -1525,6 +1527,8 @@ CE34A5720B249E0B00755730 /* BDSKMARCParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BDSKMARCParser.m; sourceTree = "<group>"; }; CE35DCE70A99B1A700029B66 /* BDSKErrorEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BDSKErrorEditor.h; sourceTree = "<group>"; }; CE35DCE80A99B1A700029B66 /* BDSKErrorEditor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BDSKErrorEditor.m; sourceTree = "<group>"; }; + CE375CAD2E5F081200A91CD6 /* BDSKWKWebView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BDSKWKWebView.h; sourceTree = "<group>"; }; + CE375CAE2E5F081200A91CD6 /* BDSKWKWebView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BDSKWKWebView.m; sourceTree = "<group>"; }; CE38FB82091D946900BCB69D /* BDSKCondition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BDSKCondition.h; sourceTree = "<group>"; }; CE38FB83091D946900BCB69D /* BDSKCondition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BDSKCondition.m; sourceTree = "<group>"; }; CE38FB84091D946A00BCB69D /* BDSKConditionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BDSKConditionController.h; sourceTree = "<group>"; }; @@ -2729,6 +2733,7 @@ F9DCEA4E094B7D1100AEE662 /* BDSKTextWithIconCell.m */, CE6DACC30A503ECF00123185 /* BDSKToolbarItem.m */, CEF7F42512743BCC00B20881 /* BDSKWebView.m */, + CE375CAE2E5F081200A91CD6 /* BDSKWKWebView.m */, CEA99967264EC52900AB2050 /* BDSKWrappingView.m */, F98F33C90892D4B700C1427D /* BDSKZoomablePDFView.m */, CE27D95A0AF92BFD00419879 /* BDSKZoomableTextView.m */, @@ -3528,6 +3533,7 @@ CE3A254D0B75FF09006B64D3 /* BDSKWebParser.h */, CEF7F42412743BCC00B20881 /* BDSKWebView.h */, CE03C0C8127D751D00F62F51 /* BDSKWebViewModalDialogController.h */, + CE375CAD2E5F081200A91CD6 /* BDSKWKWebView.h */, CEA99966264EC52900AB2050 /* BDSKWrappingView.h */, 6C567DB70F8189F500DE285D /* BDSKZentralblattParser.h */, F98F33C80892D4B700C1427D /* BDSKZoomablePDFView.h */, @@ -3727,6 +3733,7 @@ CE963637283D292F00D8A983 /* BDSKTextUndoManager.h in Headers */, CE2A09D8224599B300A8F31C /* BDSKCondition+Scripting.h in Headers */, CE2A0A1D224599EF00A8F31C /* BDSKISIGroupServer.h in Headers */, + CE375CAF2E5F081200A91CD6 /* BDSKWKWebView.h in Headers */, CE5417CA22D4DA7700867189 /* BDSKAuthenticationHandler.h in Headers */, CE2A0AE822459A5100A8F31C /* NSWindowController_BDSKExtensions.h in Headers */, CE60FF8E26CFE56F0077AF87 /* BDSKColorCell.h in Headers */, @@ -4862,6 +4869,7 @@ CE4476DC2128907100DF38E1 /* DOMNode_BDSKExtensions.m in Sources */, F92EF32309E6242200A244D0 /* BDSKSharedGroup.m in Sources */, F946DCE909FDC4B600D471DF /* BDSKAsyncObject.m in Sources */, + CE375CB02E5F081200A91CD6 /* BDSKWKWebView.m in Sources */, CEFB269027E0E262002E50D5 /* BDSKLineTextField.m in Sources */, F9A411FC0A0B2066008493C0 /* BDSKPreferenceController.m in Sources */, CE3448020A11302F0026A92A /* BDSKPreviewItem.m in Sources */, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. _______________________________________________ Bibdesk-commit mailing list Bibdesk-commit@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bibdesk-commit