Ignore:
Timestamp:
03/06/08 11:37:50 (16 years ago)
Author:
Nicholas Riley
Message:

Drop Safari 2 support; add selectionless WebKit launching

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.