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

_______________________________________________
webkit-dev mailing list
[email protected]
http://www.opendarwin.org/mailman/listinfo/webkit-dev

Reply via email to