Changeset 443

Show
Ignore:
Timestamp:
03/ 6/08 11:37:50 AM (9 months ago)
Author:
nicholas
Message:

Drop Safari 2 support; add selectionless WebKit? launching

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ICeCoffEE/ICeCoffEE/APEMain.m

    r441 r443  
    160160    } 
    161161 
    162     ICCF_PatchMethod("WebHTMLView", "ICeCoffEEWebKit", "ICeCoffEEWebKitSuper", "mouseUp:") && 
     162    objc_getClass("WebCoreFrameBridge") != NULL /* require Safari 3 */ && 
     163        ICCF_PatchMethod("WebHTMLView", "ICeCoffEEWebKit", "ICeCoffEEWebKitSuper", "mouseUp:") && 
    163164        ICCF_PatchMethod("WebHTMLView", "ICeCoffEEWebKit", "ICeCoffEEWebKitSuper", "mouseDown:") && 
    164165        ICCF_PatchMethod("WebHTMLView", "ICeCoffEEWebKit", "ICeCoffEEWebKitSuper", "menuForEvent:"); 
    165         ICapeprintf("ICeCoffEE APE: loaded in WebHTMLView for WebKit/Safari\n"); 
     166        ICapeprintf("ICeCoffEE APE: loaded in WebHTMLView for WebKit/Safari 3\n"); 
    166167     
    167168    if (shouldLoadInNSTextView) { 
  • trunk/ICeCoffEE/ICeCoffEE/ICeCoffEEWebKit.m

    r436 r443  
    88 
    99#import "ICeCoffEEWebKit.h" 
     10#import "ICeCoffEEWebPolicyDelegate.h" 
     11#import "ICeCoffEEParser.h" 
     12#import "ICeCoffEETrigger.h" 
     13#import <WebKit/WebKit.h> 
    1014#import <unistd.h> 
    1115 
     16// XXX WebCoreFrameBridge is going away 
     17// (see <http://trac.webkit.org/projects/webkit/changeset/30712>) 
    1218// WebCoreBridge, from WebCoreBridge.h (Safari 2) 
    1319// Web(Core)FrameBridge, from WebCoreFrameBridge.h (Safari 3) 
    1420@interface WebCoreBridge : NSObject 
    1521 
    16 // can only use setMarkedText:selectedRange: if WebHTMLView is editable 
    17 // or, should we move to DOM-based accessors, i.e. "setMarkDOMRange"? 
    18 - (void)selectNSRange:(NSRange)range; 
     22// XXX move to DOM-based accessors 
     23- (DOMRange *)convertNSRangeToDOMRange:(NSRange)range; 
     24- (NSString *)stringForRange:(DOMRange *)range; 
    1925 
    2026@end 
    2127 
    22 // from WebKit, private -- XXX maybe I'm better off going back the other way, relying on public methods in the bridge? 
     28// XXX WebHTMLView is going away 
    2329@interface WebHTMLView : NSObject 
    2430 
    25 - (NSString *)selectedString; 
    2631- (NSRect)selectionRect; 
    27 - (NSRect)_selectionRect; // Safari 2, supported in Safari 3 only for use with Mail 
    28 - (NSRange)selectedRange; // XXX same as selectedNSRange in WebCoreFrameBridge.h? 
    29 - (void)deselectAll; 
     32- (DOMRange *)_documentRange; 
    3033 
    31 - (WebCoreBridge *)_bridge; /* WebFrameBridge in Safari 3 (see above) */ 
    32  
    33 - (NSDictionary *)elementAtPoint:(NSPoint)point; 
     34- (WebView *)_webView; 
     35- (WebCoreBridge *)_bridge; // WebFrameBridge in Safari 3 (see above) 
    3436 
    3537@end 
     
    4446 
    4547static NSEvent *downEvent = nil; 
    46 static NSString *selectedString = nil
    47 static NSRange selectedRange; 
     48static id /* (WebPolicyDelegate) */ policyDelegate
     49static id /* DOMRange */ selectedRange; 
    4850 
    4951- (void)mouseDown:(NSEvent *)e; 
     
    5153    [downEvent release]; downEvent = nil; 
    5254    if (ICCF_enabled && ICCF_prefs.commandClickEnabled && ICCF_EventIsCommandMouseDown(e)) { 
    53         if ([self respondsToSelector: @selector(selectedRange)]) { 
     55        if ([self respondsToSelector: @selector(_webView)]) { 
     56            WebView *webView = [(WebHTMLView *)self _webView]; 
     57             
    5458            // save selection: it may be deselected on super mouseDown 
    55             selectedRange = [(WebHTMLView *)self selectedRange]; 
     59            selectedRange = [[webView selectedDOMRange] retain]; 
     60             
     61            // stop any URL launching from happening 
     62            if ([webView isEditable]) { 
     63                policyDelegate = [[webView policyDelegate] retain]; 
     64                [webView setPolicyDelegate: [ICeCoffEEWebPolicyDelegate sharedDelegate]]; 
     65            } 
     66             
     67            downEvent = [e retain]; 
    5668        } 
    57         [selectedString release]; selectedString = nil; 
    58         selectedString = [[(WebHTMLView *)self selectedString] retain]; 
    59         downEvent = [e retain]; 
    6069    } 
    6170    [super mouseDown: e]; 
     
    6574{ 
    6675    [super mouseUp: e]; 
    67     if (downEvent != nil) { 
    68         NSPoint downPt = [downEvent locationInWindow]; 
    69         NSPoint upPt = [e locationInWindow]; 
    70         if (abs(downPt.x - upPt.x) > kICHysteresisPixels && abs(downPt.y - upPt.y) > kICHysteresisPixels) 
    71             return; 
    7276 
    73         @try { 
    74             NSPoint viewClickPt = [self convertPoint: downPt fromView: nil]; 
    75             NSDictionary *elementDict = [(WebHTMLView *)self elementAtPoint: viewClickPt]; 
    76             WebCoreBridge *bridge = [(WebHTMLView *)self _bridge]; 
    77             ICLog(@"elementDict: %@", elementDict); 
    78             NSAssert([elementDict count] != 0, @"Internal error: Got empty element dictionary from WebHTMLView"); 
    79             if ([elementDict objectForKey: @"WebElementLinkURL"] != nil) { 
    80                 ICLog(@"got a link"); 
    81                 return; // don't activate on links 
    82             } 
    83             if (selectedString == nil || [selectedString length] == 0) { 
    84                 ICLog(@"no selected string"); 
     77    if (downEvent == nil) 
     78        return; 
     79     
     80    WebView *webView = [(WebHTMLView *)self _webView]; 
     81    BOOL isEditable = [webView isEditable]; 
     82 
     83    if (isEditable) { 
     84        [webView setPolicyDelegate: policyDelegate]; 
     85        [policyDelegate release]; policyDelegate = nil; 
     86    } 
     87 
     88    NSPoint downPt = [downEvent locationInWindow]; 
     89    NSPoint upPt = [e locationInWindow]; 
     90    if (abs(downPt.x - upPt.x) > kICHysteresisPixels && abs(downPt.y - upPt.y) > kICHysteresisPixels) 
     91        return; 
     92 
     93    @try { 
     94        if (!isEditable) 
     95            [webView setEditable: YES]; 
     96 
     97        NSPoint viewClickPt = [webView convertPoint: downPt fromView: nil]; 
     98        NSDictionary *elementDict = [webView elementAtPoint: viewClickPt]; 
     99        NSLog(@"elementDict: %@", elementDict); 
     100        NSAssert([elementDict count] != 0, ICCF_LocalizedString(@"Sorry, ICeCoffEE was unable to find anything to select")); 
     101 
     102        WebCoreBridge *bridge = [(WebHTMLView *)self _bridge]; 
     103 
     104        id link = [elementDict objectForKey: @"WebElementLinkURL"]; 
     105        NSString *url = [link isKindOfClass: [NSURL class]] ? [link absoluteString] : nil; 
     106 
     107        ICCF_StartIC(); 
     108         
     109        id /* DOMRange */ domRange = nil; 
     110         
     111        if (url != nil) { 
     112            ICLog(@"got a link"); 
     113            if (!isEditable) { 
     114                ICCF_StopIC(); 
    85115                return; 
    86116            } 
    87             ICCF_StartIC(); 
    88             BOOL canSetSelection = [bridge respondsToSelector: @selector(selectNSRange:)]; 
    89             if (canSetSelection) { 
    90                 // may have become deselected in mouseDown 
    91                 [bridge selectNSRange: selectedRange]; 
     117            // XXX handle existing selection 
     118            domRange = [webView selectedDOMRange]; 
     119            [domRange selectNode: [elementDict objectForKey:@"WebElementDOMNode"]]; 
     120            [webView setSelectedDOMRange: domRange affinity: NSSelectionAffinityDownstream]; 
     121        } else { 
     122            // may have become deselected in mouseDown 
     123            [webView setSelectedDOMRange: selectedRange affinity: NSSelectionAffinityDownstream]; 
     124             
     125            // XXX at some point, characterIndexForPoint: wasn't implemented, so this will fail 
     126            NSRange range = [ICeCoffEETrigger rangeForEvent: downEvent onTarget: (NSView<NSTextInput> *)self]; 
     127 
     128            // XXX limit to a reasonable size 
     129            // NSRange fetchRange = [bridge convertDOMRangeToNSRange: [(WebHTMLView *)self _documentRange]]; 
     130            NSString *s = [bridge stringForRange: [(WebHTMLView *)self _documentRange]]; 
     131         
     132            if (range.length == 0) { 
     133                range.length = 1; 
     134                range = ICCF_URLEnclosingRange(s, range); 
     135                domRange = [bridge convertNSRangeToDOMRange: range]; 
     136                [webView setSelectedDOMRange: domRange affinity: NSSelectionAffinityDownstream]; 
     137            } else { 
     138                domRange = [bridge convertNSRangeToDOMRange: range]; 
    92139            } 
    93             if (ICCF_LaunchURL(selectedString, ICCF_KeyboardAction(downEvent)) && ICCF_prefs.textBlinkEnabled && canSetSelection) { 
    94                 int i; 
    95                 NSRect selectionRect; 
    96                 if ([self respondsToSelector: @selector(selectionRect)]) 
    97                     selectionRect = [(WebHTMLView *)self selectionRect]; 
    98                 else 
    99                     selectionRect = [(WebHTMLView *)self _selectionRect]; 
    100                 ICLog(@"selectedRange %@ selectionRect %@ textBlinkCount %d", NSStringFromRange(selectedRange), NSStringFromRect(selectionRect), ICCF_prefs.textBlinkCount); 
    101                 for (i = 0 ; i < ICCF_prefs.textBlinkCount ; i++) { 
    102                     [(WebHTMLView *)self deselectAll]; 
    103                     [self setNeedsDisplayInRect: selectionRect]; 
    104                     [self display]; 
    105                     usleep(kICBlinkDelayUsecs); 
    106                     [bridge selectNSRange: selectedRange]; 
    107                     [self setNeedsDisplayInRect: selectionRect]; 
    108                     [self display]; 
    109                     usleep(kICBlinkDelayUsecs); 
    110                 } 
     140             
     141            url = [s substringWithRange: range]; 
     142        }        
     143         
     144        if (ICCF_LaunchURL(url, ICCF_KeyboardAction(downEvent)) && ICCF_prefs.textBlinkEnabled && domRange != nil) { 
     145            NSRect selectionRect = [(WebHTMLView *)self selectionRect]; 
     146            for (int i = 0 ; i < ICCF_prefs.textBlinkCount ; i++) { 
     147                [webView setSelectedDOMRange: nil affinity: NSSelectionAffinityDownstream]; 
     148                [self setNeedsDisplayInRect: selectionRect]; 
     149                [self display]; 
     150                usleep(kICBlinkDelayUsecs); 
     151                [webView setSelectedDOMRange: domRange affinity: NSSelectionAffinityDownstream]; 
     152                [self setNeedsDisplayInRect: selectionRect]; 
     153                [self display]; 
     154                usleep(kICBlinkDelayUsecs); 
    111155            } 
    112         } @catch (NSException *e) { 
    113             ICCF_HandleException(e, downEvent); 
    114         } @finally { 
    115             [downEvent release]; downEvent = nil; 
    116156        } 
     157    } @catch (NSException *e) { 
     158        ICCF_HandleException(e, downEvent); 
     159    } @finally { 
     160        [selectedRange release]; selectedRange = nil; 
     161        [downEvent release]; downEvent = nil; 
     162        if (!isEditable) 
     163            [webView setEditable: NO]; 
     164    } 
    117165 
    118         ICCF_StopIC(); 
    119     }         
     166    ICCF_StopIC(); 
    120167} 
    121168