WebCore:
authorkocienda <kocienda@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 24 Aug 2004 23:23:27 +0000 (23:23 +0000)
committerkocienda <kocienda@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 24 Aug 2004 23:23:27 +0000 (23:23 +0000)
        Reviewed by Hyatt

        Improved the ability of the bridge to report selection state.

        * khtml/editing/htmlediting_impl.cpp:
        (khtml::TypingCommandImpl::doApply): Bail when there is no selection.
        * kwq/WebCoreBridge.h: Added an enum to report selection state. These constants
        mirror those used in DOM::Selection.
        * kwq/WebCoreBridge.mm:
        (-[WebCoreBridge selectionState]): Replacement for haveSelection. Returns a value
        from an enum telling whether the selection is in the None, Caret, or Range state,
        rather than just true/false for the Range state as it did before.

WebKit:

        Reviewed by Hyatt

        Improved the checks used to see if certain operations can be done based
        on the state of the selection and whether the selection is editable. I
        added some helpers and improved some others to assist in making these
        determinations.

        This helps to fix this bug:
        <rdar://problem/3764987> Crash after adding newline to quoted text

        Since some editing methods expect the the selection to be in a certain state
        in order to work, these checks help obviate crashes like 3764987.

        * WebView.subproj/WebHTMLView.m:
        (-[WebHTMLView _writeSelectionToPasteboard:]): _haveSelection name changed to _hasSelection.
        (-[WebHTMLView _canCopy]): Checks to see if state is appropriate to perform this operation.
        (-[WebHTMLView _canCut]): Ditto. Function added.
        (-[WebHTMLView _canDelete]): Ditto. Function refined.
        (-[WebHTMLView _canPaste]): Ditto. Function refined.
        (-[WebHTMLView _canType]): Ditto. Function added.
        (-[WebHTMLView _hasSelection]): Name changed from _haveSelection.
        (-[WebHTMLView _hasSelectionOrInsertionPoint]): Added.
        (-[WebHTMLView _isEditable]): Added.
        (-[WebHTMLView takeFindStringFromSelection:]): _haveSelection name changed to _hasSelection.
        (-[WebHTMLView validateUserInterfaceItem:]): Ditto
        (-[WebHTMLView validRequestorForSendType:returnType:]): Ditto
        (-[WebHTMLView keyDown:]):
        (-[WebHTMLView copy:]): Uses new _canCopy check.
        (-[WebHTMLView cut:]): Uses new _canCut check.
        (-[WebHTMLView delete:]): Now uses _canDelete check.
        (-[WebHTMLView paste:]): Now uses _canPaste check.
        (-[WebHTMLView _updateFontPanel]): _haveSelection name changed to _hasSelection.
        * WebView.subproj/WebHTMLViewPrivate.h:
        * WebView.subproj/WebView.m:
        (-[WebView writeSelectionWithPasteboardTypes:toPasteboard:]): Use selectionState check to
        determine whether or not operation can be done.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@7343 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog-2005-08-23
WebCore/khtml/editing/htmlediting_impl.cpp
WebCore/kwq/WebCoreBridge.h
WebCore/kwq/WebCoreBridge.mm
WebKit/ChangeLog
WebKit/WebView.subproj/WebHTMLView.m
WebKit/WebView.subproj/WebHTMLViewPrivate.h
WebKit/WebView.subproj/WebView.m

index 10545716bd8694841fbde83ad7e55b6155329934..612032d382b5810194fb8cfe07cbfb5052123ce0 100644 (file)
@@ -1,3 +1,18 @@
+2004-08-24  Ken Kocienda  <kocienda@apple.com>
+
+        Reviewed by Hyatt
+
+        Improved the ability of the bridge to report selection state.     
+
+        * khtml/editing/htmlediting_impl.cpp:
+        (khtml::TypingCommandImpl::doApply): Bail when there is no selection.
+        * kwq/WebCoreBridge.h: Added an enum to report selection state. These constants
+        mirror those used in DOM::Selection.
+        * kwq/WebCoreBridge.mm:
+        (-[WebCoreBridge selectionState]): Replacement for haveSelection. Returns a value 
+        from an enum telling whether the selection is in the None, Caret, or Range state, 
+        rather than just true/false for the Range state as it did before.
+
 2004-08-24  David Hyatt  <hyatt@apple.com>
 
        Make sure the ifdef XSLT is present for Panther.
index 64716d36d815bbb4515b92da16fd98674899fcc7..596facdec6ebb4b24d49678251b7e5bed369d1f6 100644 (file)
@@ -2215,6 +2215,9 @@ int TypingCommandImpl::commandID() const
 
 void TypingCommandImpl::doApply()
 {
+    if (endingSelection().state() == Selection::NONE)
+        return;
+
     switch (m_commandType) {
         case TypingCommand::DeleteKey:
             deleteKeyPressed();
index b14e47e1132085b9875aad039e8175a0ac62100b..a839f84cf93c5e25d1831e490694d35e6d404285 100644 (file)
@@ -90,6 +90,12 @@ typedef enum {
     WebCoreDevicePrinter
 } WebCoreDeviceType;
 
+typedef enum {
+    WebSelectionStateNone,
+    WebSelectionStateCaret,
+    WebSelectionStateRange,
+} WebSelectionState;
+
 typedef enum {
     WebSelectByMoving,
     WebSelectByExtending
@@ -234,8 +240,7 @@ typedef enum {
 - (void)setSelectionFrom:(DOMNode *)start startOffset:(int)startOffset to:(DOMNode *)end endOffset:(int) endOffset;
 
 - (BOOL)isSelectionEditable;
-
-- (BOOL)haveSelection;
+- (WebSelectionState)selectionState;
 
 - (NSAttributedString *)selectedAttributedString;
 - (NSString *)selectedString;
index ea583069249365e3fa7cc70ef01cf15ab24dd928..ede632a8043856326748316430b8018e29918b8a 100644 (file)
@@ -450,9 +450,19 @@ static bool initializedKJS = FALSE;
        return startNode ? startNode->isContentEditable() : NO;
 }
 
-- (BOOL)haveSelection
-{
-    return _part->selection().state() == Selection::RANGE;
+- (WebSelectionState)selectionState
+{
+    switch (_part->selection().state()) {
+        case Selection::NONE:
+            return WebSelectionStateNone;
+        case Selection::CARET:
+            return WebSelectionStateCaret;
+        case Selection::RANGE:
+            return WebSelectionStateRange;
+    }
+    
+    ASSERT_NOT_REACHED();
+    return WebSelectionStateNone;
 }
 
 - (NSString *)_documentTypeString
index 565fee3340ab20ed41132e07f904ce89b3df0af3..7728725b827db4bac37f457af0a5f5f3460c3899 100644 (file)
@@ -1,3 +1,42 @@
+2004-08-24  Ken Kocienda  <kocienda@apple.com>
+
+        Reviewed by Hyatt
+
+        Improved the checks used to see if certain operations can be done based
+        on the state of the selection and whether the selection is editable. I
+        added some helpers and improved some others to assist in making these
+        determinations.
+        
+        This helps to fix this bug:
+        <rdar://problem/3764987> Crash after adding newline to quoted text
+        
+        Since some editing methods expect the the selection to be in a certain state 
+        in order to work, these checks help obviate crashes like 3764987.
+
+        * WebView.subproj/WebHTMLView.m:
+        (-[WebHTMLView _writeSelectionToPasteboard:]): _haveSelection name changed to _hasSelection.
+        (-[WebHTMLView _canCopy]): Checks to see if state is appropriate to perform this operation.
+        (-[WebHTMLView _canCut]): Ditto. Function added.
+        (-[WebHTMLView _canDelete]): Ditto. Function refined.
+        (-[WebHTMLView _canPaste]): Ditto. Function refined.
+        (-[WebHTMLView _canType]): Ditto. Function added.
+        (-[WebHTMLView _hasSelection]): Name changed from _haveSelection.
+        (-[WebHTMLView _hasSelectionOrInsertionPoint]): Added.
+        (-[WebHTMLView _isEditable]): Added.
+        (-[WebHTMLView takeFindStringFromSelection:]): _haveSelection name changed to _hasSelection.
+        (-[WebHTMLView validateUserInterfaceItem:]): Ditto
+        (-[WebHTMLView validRequestorForSendType:returnType:]): Ditto
+        (-[WebHTMLView keyDown:]):
+        (-[WebHTMLView copy:]): Uses new _canCopy check.
+        (-[WebHTMLView cut:]): Uses new _canCut check.
+        (-[WebHTMLView delete:]): Now uses _canDelete check.
+        (-[WebHTMLView paste:]): Now uses _canPaste check.
+        (-[WebHTMLView _updateFontPanel]): _haveSelection name changed to _hasSelection.
+        * WebView.subproj/WebHTMLViewPrivate.h:
+        * WebView.subproj/WebView.m:
+        (-[WebView writeSelectionWithPasteboardTypes:toPasteboard:]): Use selectionState check to
+        determine whether or not operation can be done.
+
 2004-08-24  Richard Williamson   <rjw@apple.com>
 
         Fixed <rdar://problem/3770469> Some PDFs open with line of previous page above PDF view
index 0894f420cb50b62955dca1d9ea4746d5ab078cfd..ae4336e8ec60269f62610eb19529e7a0203678e2 100644 (file)
@@ -718,27 +718,12 @@ static WebHTMLView *lastHitView = nil;
 
 - (void)_writeSelectionToPasteboard:(NSPasteboard *)pasteboard
 {
-    ASSERT([self _haveSelection]);
+    ASSERT([self _hasSelection]);
     NSArray *types = [[self class] _selectionPasteboardTypes];
     [pasteboard declareTypes:types owner:nil];
     [self writeSelectionWithPasteboardTypes:types toPasteboard:pasteboard];
 }
 
-- (BOOL)_haveSelection
-{
-    return [[self _bridge] haveSelection];
-}
-
-- (BOOL)_canDelete
-{
-    return [self _haveSelection] && [[self _bridge] isSelectionEditable];
-}
-
-- (BOOL)_canPaste
-{
-    return [[self _bridge] isSelectionEditable];
-}
-
 - (NSImage *)_dragImageForLinkElement:(NSDictionary *)element
 {
     NSURL *linkURL = [element objectForKey: WebElementLinkURLKey];
@@ -1067,6 +1052,47 @@ static WebHTMLView *lastHitView = nil;
     [self mouseDragged:fakeEvent];
 }
 
+- (BOOL)_canCopy
+{
+    // Copying can be done regardless of whether you can edit.
+    return [self _hasSelection];
+}
+
+- (BOOL)_canCut
+{
+    return [self _hasSelection] && [self _isEditable];
+}
+
+- (BOOL)_canDelete
+{
+    return [self _hasSelection] && [self _isEditable];
+}
+
+- (BOOL)_canPaste
+{
+    return [self _hasSelectionOrInsertionPoint] && [self _isEditable];
+}
+
+- (BOOL)_canType
+{
+    return [self _hasSelectionOrInsertionPoint] && [self _isEditable];
+}
+
+- (BOOL)_hasSelection
+{
+    return [[self _bridge] selectionState] == WebSelectionStateRange;
+}
+
+- (BOOL)_hasSelectionOrInsertionPoint
+{
+    return [[self _bridge] selectionState] != WebSelectionStateNone;
+}
+
+- (BOOL)_isEditable
+{
+    return [[self _webView] isEditable] || [[self _bridge] isSelectionEditable];
+}
+
 @end
 
 @implementation NSView (WebHTMLViewPrivate)
@@ -1184,7 +1210,7 @@ static WebHTMLView *lastHitView = nil;
 
 - (IBAction)takeFindStringFromSelection:(id)sender
 {
-    if (![self _haveSelection]) {
+    if (![self _hasSelection]) {
         NSBeep();
         return;
     }
@@ -1255,15 +1281,15 @@ static WebHTMLView *lastHitView = nil;
     if (action == @selector(cut:)) {
         return [bridge mayDHTMLCut] || [self _canDelete];
     } else if (action == @selector(copy:)) {
-        return [bridge mayDHTMLCopy] || [self _haveSelection];
+        return [bridge mayDHTMLCopy] || [self _canCopy];
     } else if (action == @selector(delete:)) {
         return [self _canDelete];
     } else if (action == @selector(paste:)) {
         return [bridge mayDHTMLPaste] || [self _canPaste];
     } else if (action == @selector(takeFindStringFromSelection:)) {
-        return [self _haveSelection];
+        return [self _hasSelection];
     } else if (action == @selector(jumpToSelection:)) {
-        return [self _haveSelection];
+        return [self _hasSelection];
     } else if (action == @selector(checkSpelling:)
                || action == @selector(showGuessPanel:)
                || action == @selector(changeSpelling:)
@@ -1276,7 +1302,7 @@ static WebHTMLView *lastHitView = nil;
 
 - (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType
 {
-    if (sendType && ([[[self class] _selectionPasteboardTypes] containsObject:sendType]) && [self _haveSelection]){
+    if (sendType && ([[[self class] _selectionPasteboardTypes] containsObject:sendType]) && [self _hasSelection]){
         return self;
     }
 
@@ -2362,7 +2388,7 @@ static WebHTMLView *lastHitView = nil;
     // We're going to process a key event, bail on any outstanding complete: UI
     [_private->compController endRevertingChange:YES moveLeft:NO];
     
-    if (([[self _webView] isEditable] || [bridge isSelectionEditable]) && [self _interceptEditingKeyEvent:event]) 
+    if ([self _canType] && [self _interceptEditingKeyEvent:event]) 
         return;
     
     [super keyDown:event];
@@ -2618,7 +2644,7 @@ static WebHTMLView *lastHitView = nil;
         return;     // DHTML did the whole operation
     }
 
-    if (![self _haveSelection]) {
+    if (![self _canCopy]) {
         NSBeep();
         return;
     }
@@ -2631,7 +2657,7 @@ static WebHTMLView *lastHitView = nil;
         return;     // DHTML did the whole operation
     }
 
-    if (![self _haveSelection]) {
+    if (![self _canCut]) {
         NSBeep();
         return;
     }
@@ -2641,7 +2667,7 @@ static WebHTMLView *lastHitView = nil;
 
 - (void)delete:(id)sender
 {
-    if (![self _haveSelection]) {
+    if (![self _canDelete]) {
         NSBeep();
         return;
     }
@@ -2654,6 +2680,11 @@ static WebHTMLView *lastHitView = nil;
         return;     // DHTML did the whole operation
     }
 
+    if (![self _canPaste]) {
+        NSBeep();
+        return;
+    }
+
     [self _pasteWithPasteboard:[NSPasteboard generalPasteboard] allowPlainText:YES];
 }
 
@@ -3313,7 +3344,7 @@ static WebHTMLView *lastHitView = nil;
     BOOL onlyOneFontInSelection = YES;
     NSFont *font = nil;
     
-    if (![bridge haveSelection]) {
+    if (![self _hasSelection]) {
         font = [bridge fontForCurrentPosition];
     } 
     else {
@@ -3349,7 +3380,7 @@ static WebHTMLView *lastHitView = nil;
     // FIXME: for now, return a bogus font that distinguishes the empty selection from the non-empty
     // selection. We should be able to remove this once the rest of this code works properly.
     if (font == nil) {
-        if (![bridge haveSelection]) {
+        if (![self _hasSelection]) {
             font = [NSFont toolTipsFontOfSize:17];
         } else {
             font = [NSFont menuFontOfSize:23];
index 8260297ec2babcc49919b54bd9f905d94a2ccc31..bfedc992b573664b35866f596797a6e9ccda9d8f 100644 (file)
@@ -38,9 +38,6 @@
 - (void)_writeSelectionToPasteboard:(NSPasteboard *)pasteboard;
 - (WebArchive *)_selectedArchive;
 - (NSData *)_selectedRTFData;
-- (BOOL)_canDelete;
-- (BOOL)_canPaste;
-- (BOOL)_haveSelection;
 
 - (void)_frameOrBoundsChanged;
 
 - (void)_startAutoscrollTimer:(NSEvent *)event;
 - (void)_stopAutoscrollTimer;
 
+- (BOOL)_canCopy;
+- (BOOL)_canCut;
+- (BOOL)_canDelete;
+- (BOOL)_canPaste;
+- (BOOL)_canType;
+- (BOOL)_hasSelection;
+- (BOOL)_hasSelectionOrInsertionPoint;
+- (BOOL)_isEditable;
+
 @end
index 77517c24134d2eba642d8f2c6cc8b76fd9ef9be3..48dd1fdfb23f5d102adf0470e40e8e8a7f0b8861 100644 (file)
@@ -1972,7 +1972,7 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
 - (void)writeSelectionWithPasteboardTypes:(NSArray *)types toPasteboard:(NSPasteboard *)pasteboard
 {
     WebBridge *bridge = [self _bridgeForCurrentSelection];
-    if ([bridge haveSelection]) {
+    if ([bridge selectionState] != WebSelectionStateRange) {
         NSView <WebDocumentView> *documentView = [[[bridge webFrame] frameView] documentView];
         if ([documentView conformsToProtocol:@protocol(WebDocumentSelection)]) {
             [(NSView <WebDocumentSelection> *)documentView writeSelectionWithPasteboardTypes:types toPasteboard:pasteboard];