// // ICeCoffEEWebKit.m // ICeCoffEE APE // // Created by Nicholas Riley on Sun Jan 19 2003. // Copyright (c) 2003 Nicholas Riley. All rights reserved. // #import "ICeCoffEEWebKit.h" #import "ICeCoffEEWebPolicyDelegate.h" #import "ICeCoffEEParser.h" #import "ICeCoffEETrigger.h" #import #import // XXX WebCoreFrameBridge is going away // (see ) // WebCoreBridge, from WebCoreBridge.h (Safari 2) // Web(Core)FrameBridge, from WebCoreFrameBridge.h (Safari 3) @interface WebCoreBridge : NSObject // XXX move to DOM-based accessors - (DOMRange *)convertNSRangeToDOMRange:(NSRange)range; - (NSString *)stringForRange:(DOMRange *)range; @end // XXX WebHTMLView is going away @interface WebHTMLView : NSObject - (NSRect)selectionRect; - (DOMRange *)_documentRange; - (WebView *)_webView; - (WebCoreBridge *)_bridge; // WebFrameBridge in Safari 3 (see above) @end @implementation ICeCoffEEWebKit - (NSMenu *)menuForEvent:(NSEvent *)e; { NSMenu *myMenu = [super menuForEvent: e]; return ICCF_MenuForEvent(self, myMenu, e); } static NSEvent *downEvent = nil; static id /* (WebPolicyDelegate) */ policyDelegate; static id /* DOMRange */ selectedRange; - (void)mouseDown:(NSEvent *)e; { [downEvent release]; downEvent = nil; if (ICCF_enabled && ICCF_prefs.commandClickEnabled && ICCF_EventIsCommandMouseDown(e)) { if ([self respondsToSelector: @selector(_webView)]) { WebView *webView = [(WebHTMLView *)self _webView]; // save selection: it may be deselected on super mouseDown selectedRange = [[webView selectedDOMRange] retain]; // stop any URL launching from happening if ([webView isEditable]) { policyDelegate = [[webView policyDelegate] retain]; [webView setPolicyDelegate: [ICeCoffEEWebPolicyDelegate sharedDelegate]]; } downEvent = [e retain]; } } [super mouseDown: e]; } - (void)mouseUp:(NSEvent *)e; { [super mouseUp: e]; if (downEvent == nil) return; WebView *webView = [(WebHTMLView *)self _webView]; BOOL isEditable = [webView isEditable]; if (isEditable) { [webView setPolicyDelegate: policyDelegate]; [policyDelegate release]; policyDelegate = nil; } NSPoint downPt = [downEvent locationInWindow]; NSPoint upPt = [e locationInWindow]; if (abs(downPt.x - upPt.x) > kICHysteresisPixels && abs(downPt.y - upPt.y) > kICHysteresisPixels) return; @try { if (!isEditable) [webView setEditable: YES]; NSPoint viewClickPt = [webView convertPoint: downPt fromView: nil]; NSDictionary *elementDict = [webView elementAtPoint: viewClickPt]; NSLog(@"elementDict: %@", elementDict); NSAssert([elementDict count] != 0, ICCF_LocalizedString(@"Sorry, ICeCoffEE was unable to find anything to select")); WebCoreBridge *bridge = [(WebHTMLView *)self _bridge]; id link = [elementDict objectForKey: @"WebElementLinkURL"]; NSString *url = [link isKindOfClass: [NSURL class]] ? [link absoluteString] : nil; ICCF_StartIC(); id /* DOMRange */ domRange = nil; if (url != nil) { ICLog(@"got a link"); if (!isEditable) { ICCF_StopIC(); return; } // XXX handle existing selection domRange = [webView selectedDOMRange]; [domRange selectNode: [elementDict objectForKey:@"WebElementDOMNode"]]; [webView setSelectedDOMRange: domRange affinity: NSSelectionAffinityDownstream]; } else { // may have become deselected in mouseDown [webView setSelectedDOMRange: selectedRange affinity: NSSelectionAffinityDownstream]; // XXX at some point, characterIndexForPoint: wasn't implemented, so this will fail NSRange range = [ICeCoffEETrigger rangeForEvent: downEvent onTarget: (NSView *)self]; // XXX limit to a reasonable size // NSRange fetchRange = [bridge convertDOMRangeToNSRange: [(WebHTMLView *)self _documentRange]]; NSString *s = [bridge stringForRange: [(WebHTMLView *)self _documentRange]]; if (range.length == 0) { range.length = 1; range = ICCF_URLEnclosingRange(s, range); domRange = [bridge convertNSRangeToDOMRange: range]; [webView setSelectedDOMRange: domRange affinity: NSSelectionAffinityDownstream]; } else { domRange = [bridge convertNSRangeToDOMRange: range]; } url = [s substringWithRange: range]; } if (ICCF_LaunchURL(url, ICCF_KeyboardAction(downEvent)) && ICCF_prefs.textBlinkEnabled && domRange != nil) { NSRect selectionRect = [(WebHTMLView *)self selectionRect]; for (int i = 0 ; i < ICCF_prefs.textBlinkCount ; i++) { [webView setSelectedDOMRange: nil affinity: NSSelectionAffinityDownstream]; [self setNeedsDisplayInRect: selectionRect]; [self display]; usleep(kICBlinkDelayUsecs); [webView setSelectedDOMRange: domRange affinity: NSSelectionAffinityDownstream]; [self setNeedsDisplayInRect: selectionRect]; [self display]; usleep(kICBlinkDelayUsecs); } } } @catch (NSException *e) { ICCF_HandleException(e, downEvent); } @finally { [selectedRange release]; selectedRange = nil; [downEvent release]; downEvent = nil; if (!isEditable) [webView setEditable: NO]; } ICCF_StopIC(); } @end