source: trunk/ICeCoffEE/ICeCoffEE/ICeCoffEEWebKit.m @ 449

Last change on this file since 449 was 449, checked in by Nicholas Riley, 12 years ago

Remove Safari 2 mentions.

File size: 6.3 KB
Line 
1//
2//  ICeCoffEEWebKit.m
3//  ICeCoffEE APE
4//
5//  Created by Nicholas Riley on Sun Jan 19 2003.
6//  Copyright (c) 2003 Nicholas Riley. All rights reserved.
7//
8
9#import "ICeCoffEEWebKit.h"
10#import "ICeCoffEEWebPolicyDelegate.h"
11#import "ICeCoffEEParser.h"
12#import "ICeCoffEETrigger.h"
13#import <WebKit/WebKit.h>
14#import <unistd.h>
15
16// XXX WebCoreFrameBridge is going away
17// (see <http://trac.webkit.org/projects/webkit/wiki/Maintenance%20and%20architecture%20list>)
18@interface WebCoreFrameBridge : NSObject
19
20// XXX move to DOM-based accessors
21- (DOMRange *)convertNSRangeToDOMRange:(NSRange)range;
22- (NSString *)stringForRange:(DOMRange *)range;
23
24@end
25
26// XXX WebHTMLView is going away
27@interface WebHTMLView : NSObject
28
29- (NSRect)selectionRect;
30- (DOMRange *)_documentRange;
31
32- (WebView *)_webView;
33- (WebCoreFrameBridge *)_bridge;
34
35@end
36
37// from WebViewPrivate.h (will become public, part of WebViewEditing)
38@interface WebView (webViewGrammarChecking)
39- (BOOL)isGrammarCheckingEnabled;
40- (void)setGrammarCheckingEnabled:(BOOL)flag;
41@end
42
43@implementation ICeCoffEEWebKit
44
45- (NSMenu *)menuForEvent:(NSEvent *)e;
46{
47    NSMenu *myMenu = [super menuForEvent: e];
48    return ICCF_MenuForEvent(self, myMenu, e);
49}
50
51static NSEvent *downEvent = nil;
52static id /* (WebPolicyDelegate) */ policyDelegate;
53static id /* DOMRange */ selectedRange;
54
55- (void)mouseDown:(NSEvent *)e;
56{
57    [downEvent release]; downEvent = nil;
58    if (ICCF_enabled && ICCF_prefs.commandClickEnabled && ICCF_EventIsCommandMouseDown(e)) {
59        if ([self respondsToSelector: @selector(_webView)]) {
60            WebView *webView = [(WebHTMLView *)self _webView];
61           
62            // save selection: it may be deselected on super mouseDown
63            selectedRange = [[webView selectedDOMRange] retain];
64           
65            // stop any URL launching from happening
66            if ([webView isEditable]) {
67                policyDelegate = [[webView policyDelegate] retain];
68                [webView setPolicyDelegate: [ICeCoffEEWebPolicyDelegate sharedDelegate]];
69            }
70           
71            downEvent = [e retain];
72        }
73    }
74    [super mouseDown: e];
75}
76
77- (void)mouseUp:(NSEvent *)e;
78{
79    [super mouseUp: e];
80
81    if (downEvent == nil)
82        return;
83   
84    WebView *webView = [(WebHTMLView *)self _webView];
85    BOOL isEditable = [webView isEditable];
86    BOOL isContinuousSpellCheckingEnabled = NO, isGrammarCheckingEnabled = NO;
87
88    if (isEditable) {
89        [webView setPolicyDelegate: policyDelegate];
90        [policyDelegate release]; policyDelegate = nil;
91    }
92
93    NSPoint downPt = [downEvent locationInWindow];
94    NSPoint upPt = [e locationInWindow];
95    if (abs(downPt.x - upPt.x) > kICHysteresisPixels && abs(downPt.y - upPt.y) > kICHysteresisPixels)
96        return;
97
98    @try {
99        if (!isEditable) {
100            [webView setEditable: YES];
101       
102            // don't want spelling/grammar marks to persist when view is made uneditable again
103            if ([webView respondsToSelector: @selector(isContinuousSpellCheckingEnabled)] &&
104                (isContinuousSpellCheckingEnabled = [webView isContinuousSpellCheckingEnabled])) {
105                if ([webView respondsToSelector: @selector(setContinuousSpellCheckingEnabled:)])
106                    [webView setContinuousSpellCheckingEnabled: NO];
107                else
108                    isContinuousSpellCheckingEnabled = NO; // don't restore
109            }
110
111            if ([webView respondsToSelector: @selector(isGrammarCheckingEnabled)] &&
112                (isGrammarCheckingEnabled = [webView isGrammarCheckingEnabled])) {
113                if ([webView respondsToSelector: @selector(setGrammarCheckingEnabled:)])
114                    [webView setGrammarCheckingEnabled: NO];
115                else
116                    isGrammarCheckingEnabled = NO; // don't restore
117            }
118        }
119
120        NSPoint viewClickPt = [webView convertPoint: downPt fromView: nil];
121        NSDictionary *elementDict = [webView elementAtPoint: viewClickPt];
122        NSLog(@"elementDict: %@", elementDict);
123        NSAssert([elementDict count] != 0, ICCF_LocalizedString(@"Sorry, ICeCoffEE was unable to find anything to select"));
124       
125        WebCoreFrameBridge *bridge = [(WebHTMLView *)self _bridge];
126
127        id link = [elementDict objectForKey: @"WebElementLinkURL"];
128        NSString *url = [link isKindOfClass: [NSURL class]] ? [link absoluteString] : nil;
129
130        ICCF_StartIC();
131       
132        id /* DOMRange */ domRange = nil;
133       
134        if (url != nil) {
135            ICLog(@"got a link");
136            if (!isEditable) {
137                ICCF_StopIC();
138                return;
139            }
140            // XXX handle existing selection
141            domRange = [webView selectedDOMRange];
142            [domRange selectNode: [elementDict objectForKey:@"WebElementDOMNode"]];
143            [webView setSelectedDOMRange: domRange affinity: NSSelectionAffinityDownstream];
144        } else {
145            // may have become deselected in mouseDown
146            [webView setSelectedDOMRange: selectedRange affinity: NSSelectionAffinityDownstream];
147           
148            NSRange range = [ICeCoffEETrigger rangeForEvent: downEvent onTarget: (NSView<NSTextInput> *)self];
149           
150            NSAssert(range.location != NSNotFound, ICCF_LocalizedString(@"Sorry, ICeCoffEE was unable to find anything to select"));
151
152            // XXX limit to a reasonable size
153            // NSRange fetchRange = [bridge convertDOMRangeToNSRange: [(WebHTMLView *)self _documentRange]];
154            NSString *s = [bridge stringForRange: [(WebHTMLView *)self _documentRange]];
155       
156            if (range.length == 0) {
157                range.length = 1;
158                range = ICCF_URLEnclosingRange(s, range);
159                domRange = [bridge convertNSRangeToDOMRange: range];
160                [webView setSelectedDOMRange: domRange affinity: NSSelectionAffinityDownstream];
161            } else {
162                domRange = [bridge convertNSRangeToDOMRange: range];
163            }
164           
165            url = [s substringWithRange: range];
166        }       
167       
168        if (ICCF_LaunchURL(url, ICCF_KeyboardAction(downEvent)) && ICCF_prefs.textBlinkEnabled && domRange != nil) {
169            NSRect selectionRect = [(WebHTMLView *)self selectionRect];
170            for (int i = 0 ; i < ICCF_prefs.textBlinkCount ; i++) {
171                [webView setSelectedDOMRange: nil affinity: NSSelectionAffinityDownstream];
172                [self setNeedsDisplayInRect: selectionRect];
173                [self display];
174                usleep(kICBlinkDelayUsecs);
175                [webView setSelectedDOMRange: domRange affinity: NSSelectionAffinityDownstream];
176                [self setNeedsDisplayInRect: selectionRect];
177                [self display];
178                usleep(kICBlinkDelayUsecs);
179            }
180        }
181    } @catch (NSException *e) {
182        ICCF_HandleException(e, downEvent);
183    } @finally {
184        [selectedRange release]; selectedRange = nil;
185        [downEvent release]; downEvent = nil;
186        if (!isEditable) {
187            [webView setEditable: NO];
188            if (isContinuousSpellCheckingEnabled)
189                [webView setContinuousSpellCheckingEnabled: YES];
190            if (isGrammarCheckingEnabled)
191                [webView setGrammarCheckingEnabled: YES];
192        }
193    }
194
195    ICCF_StopIC();
196}
197
198@end
Note: See TracBrowser for help on using the repository browser.