[webkit-dev] DOMRange and khtml::Selection direction

Duncan Wilcox duncan at mclink.it
Thu Aug 11 02:04:01 PDT 2005


khtml::Selection can represent both selection range and selection  
direction, through m_start/m_end and m_base/m_extent positions.  
DOMRange instead only represents a range, and not a direction.

This is an issue when during a text selection done with a mouse drag,  
in response to a  
webView:shouldChangeSelectedDOMRange:toDOMRange:affinity:stillSelecting: 
, a delegate programmatically sets a new selection with -[WebView  
setSelectedDOMRange:affinity:].

If the mouse selection is backwards, the selection direction isn't  
preserved in its DOMRange incarnation, and the mouse selection  
basically doesn't work.

This is easy enough to test, with <http://bugzilla.opendarwin.org/ 
attachment.cgi?id=3201> applied (a patch of <http:// 
bugzilla.opendarwin.org/show_bug.cgi?id=4011> to properly call  
delegates before selecting).

Create a cocoa app in xcode, replace main.m with the following code  
and add the WebKit.framework to the project:

----------
#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>

@interface Test : NSObject
@end

@implementation Test
- (BOOL)webView:(WebView *)webView shouldChangeSelectedDOMRange: 
(DOMRange *)currentRange toDOMRange:(DOMRange *)proposedRange  
affinity:(NSSelectionAffinity)selectionAffinity stillSelecting:(BOOL) 
flag
{
     NSLog(@"shouldChangeSelectedDOMRange: %ld-%ld", [proposedRange  
startOffset], [proposedRange endOffset]);
     [webView setSelectedDOMRange:proposedRange  
affinity:selectionAffinity];
     return NO;
}
@end

int main(int argc, char *argv[])
{
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
     Test *t = [[Test alloc] init];
     [NSApplication sharedApplication];
     NSRect contentRect = NSMakeRect(200, 180, 300, 300);
     NSRect wvRect = NSMakeRect(0, 0, 300, 300);
     NSWindow *w = [[NSWindow alloc] initWithContentRect:contentRect
         styleMask:NSMiniaturizableWindowMask | NSClosableWindowMask  
| NSTitledWindowMask
         backing:NSBackingStoreBuffered defer:NO];
     WebView *wv = [[WebView alloc] initWithFrame:wvRect];
     [[w contentView] addSubview:wv];
     [wv setEditable:YES];
     [wv setEditingDelegate:t];
     [[wv mainFrame] loadHTMLString:@"<html><body><p>select me  
backwards! select me backwards! select me backwards!</p></body></ 
html>" baseURL:nil];
     [w makeKeyAndOrderFront:nil];
     [NSApp run];
     return 0;
}
----------

With this app select text backwards and you'll see the selection sort  
of vanishing while you drag.


I don't think I fully understand the concept of selection affinity,  
so I don't know if it might be used for the purpose of also setting  
the selection direction (in -[WebCoreBridge  
setSelectedDOMRange:affinity:closeTyping:]), otherwise the proposal  
would be to add a couple new methods to WebView to access the current  
selection's direction:

typedef enum {
     WebViewSelectionForward,
     WebViewSelectionBackward
} WebViewSelectionDirection;

- (void)setSelectionDirection:(WebViewSelectionDirection)direction;
- (WebViewSelectionDirection)selectionDirection;

These methods would trivially resolve in swapping m_base/m_extent,  
when needed.

Please excuse the poor choice of names, I'll leave that up to the  
Apple API approval process.

Duncan




More information about the webkit-dev mailing list