Index: trunk/ICeCoffEE/ICeCoffEE/ICeCoffEEWebKit.m
===================================================================
--- trunk/ICeCoffEE/ICeCoffEE/ICeCoffEEWebKit.m	(revision 106)
+++ trunk/ICeCoffEE/ICeCoffEE/ICeCoffEEWebKit.m	(revision 167)
@@ -11,14 +11,12 @@
 
 // from WebCoreBridge.h
-@interface WebCoreBridge
+@interface WebCoreBridge : NSObject
 
 - (NSDictionary *)elementAtPoint:(NSPoint)point;
-
-- (void)setSelectionFrom:(id /* WebDOMNode */)start startOffset:(int)startOffset to:(id /* WebDOMNode */)end endOffset:(int) endOffset;
+- (NSString *)selectedString;
 - (void)deselectAll;
 
-- (void)forceLayout;
-
-- (NSString *)selectedString;
+// only in Safari 1.0-1.2
+- (void)setSelectionFrom:(id /* WebDOMNode */)start startOffset:(int)startOffset to:(id /* WebDOMNode */)end endOffset:(int) endOffset;
 
 - (id /* WebDOMNode */)selectionStart;
@@ -27,11 +25,19 @@
 - (int)selectionEndOffset;
 
+// only in Safari 1.1-1.2
+- (NSRect)selectionRect;
+
+// only in Safari 1.3
+- (void)selectNSRange:(NSRange)range;
+
 @end
 
-// from WebKit, not yet public
-@interface WebHTMLView
+// from WebKit, private
+@interface WebHTMLView : NSObject
 
 - (WebCoreBridge *)_bridge;
-- (NSDictionary *)_elementAtPoint:(NSPoint)point;
+
+// only in Safari 1.3
+- (NSRange)selectedRange;
 
 @end
@@ -46,4 +52,6 @@
 
 static NSEvent *downEvent = nil;
+
+// used in Safari < 1.3 because there's no sane way to set the selection
 typedef struct {
     int startOffset;
@@ -52,5 +60,4 @@
     id toNode;
 } ICCF_WebCoreSelection;
-static NSString *selectedString = nil; // XXX remove when we can do this properly
 
 static ICCF_WebCoreSelection selection = {nil, nil, 0, 0};
@@ -61,8 +68,6 @@
     ioSel->startOffset = [bridge selectionStartOffset];
     ioSel->endOffset = [bridge selectionEndOffset];
-    if (ioSel->startOffset != 0 && ioSel->endOffset != 0) {
-        ioSel->fromNode = [[bridge selectionStart] retain];
-        ioSel->toNode = [[bridge selectionEnd] retain];
-    }
+    ioSel->fromNode = [[bridge selectionStart] retain];
+    ioSel->toNode = [[bridge selectionEnd] retain];
 }
 
@@ -75,19 +80,26 @@
                    endOffset: inSel->endOffset];
 }
+// end Safari < 1.3 section
+
+static NSString *selectedString = nil;
+static NSRange selectedRange;
 
 - (void)mouseDown:(NSEvent *)e;
 {
+	[downEvent release]; downEvent = nil;
     // don't want command-option-click, command-shift-click, etc. to trigger
     if (ICCF_enabled && ICCF_prefs.commandClickEnabled && ICCF_EventIsCommandMouseDown(e)) {
-        // save selection: it will be deselected on super mouseDown
         WebCoreBridge *bridge = [(WebHTMLView *)self _bridge];
-        ICCF_GetWebCoreBridgeSelection(bridge, &selection);
-        ICLog(@"selection start %d@%@ end %d@%@ string %@", [bridge selectionStartOffset], [bridge selectionStart], [bridge selectionEndOffset], [bridge selectionEnd], [bridge selectedString]);
-        // XXX hack until we have something better
-        [selectedString release]; selectedString = nil;
-        selectedString = [[bridge selectedString] retain];
-        downEvent = e;
-    } else {
-        downEvent = nil;
+		if ([self respondsToSelector: @selector(selectedRange)]) {
+			// Safari 1.3 save selection: it may be deselected on super mouseDown
+			selectedRange = [(WebHTMLView *)self selectedRange];
+		} else if ([bridge respondsToSelector: @selector(selectionStartOffset)]) {
+			// Safari < 1.3 save selection: it will be deselected on super mouseDown
+			ICCF_GetWebCoreBridgeSelection(bridge, &selection);
+			ICLog(@"selection start %d@%@ end %d@%@ string %@", [bridge selectionStartOffset], [bridge selectionStart], [bridge selectionEndOffset], [bridge selectionEnd], [bridge selectedString]);
+		}
+		[selectedString release]; selectedString = nil;
+		selectedString = [[bridge selectedString] retain];
+        downEvent = [e retain];
     }
     [super mouseDown: e];
@@ -100,5 +112,5 @@
         NSPoint downPt = [downEvent locationInWindow];
         NSPoint upPt = [e locationInWindow];
-        downEvent = nil;
+		[downEvent release]; downEvent = nil;
         if (abs(downPt.x - upPt.x) > kICHysteresisPixels && abs(downPt.y - upPt.y) > kICHysteresisPixels)
             return;
@@ -107,27 +119,54 @@
             WebCoreBridge *bridge = [(WebHTMLView *)self _bridge];
             NSPoint viewClickPt = [self convertPoint: downPt fromView: nil];
-            NSDictionary *elementDict = [(WebHTMLView *)self _elementAtPoint: viewClickPt];
+            NSDictionary *elementDict = [bridge elementAtPoint: viewClickPt];
             ICLog(@"elementDict: %@", elementDict);
-            NSAssert([elementDict count] != 0, @"ShouldnÕt get empty element dictionary"); // XXX clarify
+            NSAssert([elementDict count] != 0, @"Internal error: Got empty element dictionary from WebHTMLView");
             if ([elementDict objectForKey: @"WebElementLinkURL"] != nil) {
                 ICLog(@"got a link");
                 NS_VOIDRETURN; // donÕt activate on links
             }
-            if (selectedString == nil || [selectedString length] == 0)
-                NS_VOIDRETURN;
-            // XXX works, but doesn't update
-            ICCF_StartIC();
-            ICCF_LaunchURL(selectedString, ICCF_KeyboardAction());
-            // breaks in Safari v62 and before
-            ICCF_SetWebCoreBridgeSelection(bridge, &selection);
-            if (ICCF_prefs.textBlinkEnabled) {
-                int i;
-                for (i = 0 ; i < ICCF_prefs.textBlinkCount ; i++) {
-                    [bridge deselectAll];
-                    usleep(kICBlinkDelayUsecs);
-                    ICCF_SetWebCoreBridgeSelection(bridge, &selection);
-                    usleep(kICBlinkDelayUsecs);
-                }
-            }
+			if (selectedString == nil || [selectedString length] == 0) {
+				ICLog(@"no selected string");
+				NS_VOIDRETURN;
+			}
+			ICCF_StartIC();
+			// ICCF_LaunchURL(selectedString, ICCF_KeyboardAction());
+			if (ICCF_prefs.textBlinkEnabled &&
+				[bridge respondsToSelector: @selector(selectNSRange:)]) {
+				// blink text in Safari 1.3
+				[bridge selectNSRange: selectedRange];
+				int i;
+				NSRect selectionRect = [bridge selectionRect];
+				ICLog(@"selectedRange %@ selectionRect %@ textBlinkCount %d", NSStringFromRange(selectedRange), NSStringFromRect(selectionRect), ICCF_prefs.textBlinkCount);
+				for (i = 0 ; i < ICCF_prefs.textBlinkCount ; i++) {
+					[bridge deselectAll];
+					[self setNeedsDisplayInRect: selectionRect];
+					[self display];
+					usleep(kICBlinkDelayUsecs);
+					[bridge selectNSRange: selectedRange];
+					[self setNeedsDisplayInRect: selectionRect];
+					[self display];
+					usleep(kICBlinkDelayUsecs);
+				}
+			} else {
+				// select text in Safari 1.0-1.2
+				ICCF_SetWebCoreBridgeSelection(bridge, &selection);
+				if (ICCF_prefs.textBlinkEnabled &&
+					[bridge respondsToSelector: @selector(selectionRect)]) {
+					// blink text in Safari 1.1/1.2
+					int i;
+					NSRect selectionRect = [bridge selectionRect];
+					for (i = 0 ; i < ICCF_prefs.textBlinkCount ; i++) {
+						[bridge deselectAll];
+						[self setNeedsDisplayInRect: selectionRect];
+						[self display];
+						usleep(kICBlinkDelayUsecs);
+						ICCF_SetWebCoreBridgeSelection(bridge, &selection);
+						[self setNeedsDisplayInRect: selectionRect];
+						[self display];
+						usleep(kICBlinkDelayUsecs);
+					}
+				}
+			}
         NS_HANDLER
             ICCF_HandleException(localException);
@@ -135,19 +174,6 @@
 
         ICCF_StopIC();
-        // XXX need to release fromNode, toNode
-
-        // [bridge forceLayout];
-        // ICLog(@"force start %d end %d string %@", [bridge selectionStartOffset], [bridge selectionEndOffset], [bridge selectedString]);
-
-        // check selected string, first
-        // fabricate triple-click, examine selected string
-
-        // setSelectionFrom:startOffset:to:endOffset:
-
-        // ICCF_LaunchURLFromTextView(self);
     }        
 }
 
-
-
 @end
