WebCore:
authorcblu <cblu@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Sep 2004 01:30:34 +0000 (01:30 +0000)
committercblu <cblu@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Sep 2004 01:30:34 +0000 (01:30 +0000)
Fixed:
<rdar://problem/3735071> REGRESSION (Mail): WebCore Editing must do smart paste
<rdar://problem/3799163> REGRESSION (Mail): Deleting a word doesn't delete whitespace

        Reviewed by darin.

        * khtml/editing/htmlediting.cpp:
        (khtml::DeleteSelectionCommand::DeleteSelectionCommand): take smartDelete parameter
        (khtml::ReplaceSelectionCommand::ReplaceSelectionCommand): take smartReplace parameter
        * khtml/editing/htmlediting.h:
        * khtml/editing/htmlediting_impl.cpp:
        (khtml::DeleteSelectionCommandImpl::DeleteSelectionCommandImpl): take smartDelete parameter
        (khtml::DeleteSelectionCommandImpl::doApply): delete whitespace before and after selection if necessary
        (khtml::ReplaceSelectionCommandImpl::ReplaceSelectionCommandImpl): take smartReplace parameter
        (khtml::ReplaceSelectionCommandImpl::doApply): add whitespace before and after the replacement if necessary
        * khtml/editing/htmlediting_impl.h:
        * kwq/WebCoreBridge.h:
        * kwq/WebCoreBridge.mm:
        (-[WebCoreBridge replaceSelectionWithFragment:selectReplacement:smartReplace:]): take smartReplace parameter
        (-[WebCoreBridge replaceSelectionWithNode:selectReplacement:smartReplace:]): ditto
        (-[WebCoreBridge replaceSelectionWithMarkupString:baseURLString:selectReplacement:smartReplace:]): ditto
        (-[WebCoreBridge replaceSelectionWithText:selectReplacement:smartReplace:]): ditto
        (-[WebCoreBridge deleteSelectionWithSmartDelete:]): take smartDelete parameter

WebKit:

Fixed:
<rdar://problem/3735071> REGRESSION (Mail): WebCore Editing must do smart paste
<rdar://problem/3799163> REGRESSION (Mail): Deleting a word doesn't delete whitespace

        Reviewed by darin.

        * WebView.subproj/WebDataSource.m:
        (-[WebDataSource _replaceSelectionWithArchive:selectReplacement:]): pass NO for smartReplace
        * WebView.subproj/WebHTMLView.m:
        (-[WebHTMLView _pasteWithPasteboard:allowPlainText:]): pass parameter for smartReplace using _canSmartReplaceWithPasteboard
        (-[WebHTMLView _changeSpellingFromMenu:]): pass NO for smartReplace
        (-[WebHTMLView pasteboardTypesForSelection]): include WebSmartPastePboardType when _canSmartCopyOrDelete return YES
        (-[WebHTMLView writeSelectionWithPasteboardTypes:toPasteboard:]): ditto
        (-[WebHTMLView concludeDragForDraggingInfo:actionMask:]): pass parameter for smartReplace using _canSmartReplaceWithPasteboard
        (-[WebHTMLView delete:]): call _deleteSelection
        (-[WebHTMLView cut:]): don't call delegate twice, call _deleteRange to delete
        (-[WebHTMLView pasteAsPlainText:]): pass parameter for smartReplace using _canSmartReplaceWithPasteboard
        (-[WebHTMLView _changeWordCaseWithSelector:]): pass NO for smartReplace
        (-[WebHTMLView deleteBackward:]): call _deleteSelection when there is a selected range
        (-[WebHTMLView _changeSpellingToWord:]): pass NO for smartReplace
        (-[WebHTMLView deleteToMark:]): pass NO for smartDeleteOK
        (-[WebHTMLView transpose:]): pass NO for smartReplace
        (-[WebHTMLView _shouldDeleteRange:]): moved
        (-[WebHTMLView _deleteRange:preflight:killRing:prepend:smartDeleteOK:]): moved, handle smartDelete
        (-[WebHTMLView _deleteWithDirection:granularity:killRing:]): moved
        (-[WebHTMLView _deleteSelection]): new
(-[WebHTMLView _canSmartReplaceWithPasteboard]): new
(-[WebHTMLView _canSmartCopyOrDelete]): new
        (-[WebHTMLView setMarkedText:selectedRange:]): pass NO for smartReplace
        (-[WebHTMLView _discardMarkedText]): call _deleteSelection
        (-[WebTextCompleteController _insertMatch:]): pass NO for smartReplace
        (-[WebTextCompleteController endRevertingChange:moveLeft:]): pass NO for smartReplace
        * WebView.subproj/WebHTMLViewInternal.h:
        * WebView.subproj/WebView.m:
        (-[WebView _commonInitializationWithFrameName:groupName:]): set smartInsertDeleteEnabled to YES
        (-[WebView replaceSelectionWithNode:]): pass NO for smartReplace
        (-[WebView replaceSelectionWithText:]): pass NO for smartReplace
        (-[WebView replaceSelectionWithMarkupString:]): pass NO for smartReplace
        (-[WebView deleteSelection]): call _deleteSelection on WebHTMLView

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

12 files changed:
WebCore/ChangeLog-2005-08-23
WebCore/khtml/editing/htmlediting.cpp
WebCore/khtml/editing/htmlediting.h
WebCore/khtml/editing/htmlediting_impl.cpp
WebCore/khtml/editing/htmlediting_impl.h
WebCore/kwq/WebCoreBridge.h
WebCore/kwq/WebCoreBridge.mm
WebKit/ChangeLog
WebKit/WebView.subproj/WebDataSource.m
WebKit/WebView.subproj/WebHTMLView.m
WebKit/WebView.subproj/WebHTMLViewInternal.h
WebKit/WebView.subproj/WebView.m

index ba3a4d5f36d1cf4cc9aff7e54a57419a6a9eaebc..0eda85b4aed03b4653a342252430598e69e2004e 100644 (file)
@@ -1,3 +1,29 @@
+2004-09-21  Chris Blumenberg  <cblu@apple.com>
+
+       Fixed:
+       <rdar://problem/3735071> REGRESSION (Mail): WebCore Editing must do smart paste
+       <rdar://problem/3799163> REGRESSION (Mail): Deleting a word doesn't delete whitespace
+
+        Reviewed by darin.
+
+        * khtml/editing/htmlediting.cpp:
+        (khtml::DeleteSelectionCommand::DeleteSelectionCommand): take smartDelete parameter
+        (khtml::ReplaceSelectionCommand::ReplaceSelectionCommand): take smartReplace parameter
+        * khtml/editing/htmlediting.h:
+        * khtml/editing/htmlediting_impl.cpp:
+        (khtml::DeleteSelectionCommandImpl::DeleteSelectionCommandImpl): take smartDelete parameter
+        (khtml::DeleteSelectionCommandImpl::doApply): delete whitespace before and after selection if necessary
+        (khtml::ReplaceSelectionCommandImpl::ReplaceSelectionCommandImpl): take smartReplace parameter
+        (khtml::ReplaceSelectionCommandImpl::doApply): add whitespace before and after the replacement if necessary
+        * khtml/editing/htmlediting_impl.h:
+        * kwq/WebCoreBridge.h:
+        * kwq/WebCoreBridge.mm:
+        (-[WebCoreBridge replaceSelectionWithFragment:selectReplacement:smartReplace:]): take smartReplace parameter
+        (-[WebCoreBridge replaceSelectionWithNode:selectReplacement:smartReplace:]): ditto
+        (-[WebCoreBridge replaceSelectionWithMarkupString:baseURLString:selectReplacement:smartReplace:]): ditto
+        (-[WebCoreBridge replaceSelectionWithText:selectReplacement:smartReplace:]): ditto
+        (-[WebCoreBridge deleteSelectionWithSmartDelete:]): take smartDelete parameter
+
 2004-09-21  Richard Williamson   <rjw@apple.com>
 
        More dashboard region work.
index 0870349d62410883bfa1c6f415634f861ec113a9..f578af6555e60ea44cfbea4d16c1cf2df81f4d88 100644 (file)
@@ -245,13 +245,13 @@ CSSStyleDeclarationImpl *ApplyStyleCommand::style() const
 //------------------------------------------------------------------------------------------
 // DeleteSelectionCommand
 
-DeleteSelectionCommand::DeleteSelectionCommand(DocumentImpl *document)
-    : CompositeEditCommand(new DeleteSelectionCommandImpl(document))
+DeleteSelectionCommand::DeleteSelectionCommand(DocumentImpl *document, bool smartDelete)
+    : CompositeEditCommand(new DeleteSelectionCommandImpl(document, smartDelete))
 {
 }
 
-DeleteSelectionCommand::DeleteSelectionCommand(DocumentImpl *document, const Selection &selection)
-    : CompositeEditCommand(new DeleteSelectionCommandImpl(document, selection))
+DeleteSelectionCommand::DeleteSelectionCommand(DocumentImpl *document, const Selection &selection, bool smartDelete)
+    : CompositeEditCommand(new DeleteSelectionCommandImpl(document, selection, smartDelete))
 {
 }
 
@@ -419,8 +419,8 @@ TextImpl *JoinTextNodesCommand::secondNode() const
 //------------------------------------------------------------------------------------------
 // ReplaceSelectionCommand
 
-ReplaceSelectionCommand::ReplaceSelectionCommand(DocumentImpl *document, DOM::DocumentFragmentImpl *fragment, bool selectReplacement) 
-    : CompositeEditCommand(new ReplaceSelectionCommandImpl(document, fragment, selectReplacement))
+ReplaceSelectionCommand::ReplaceSelectionCommand(DocumentImpl *document, DOM::DocumentFragmentImpl *fragment, bool selectReplacement, bool smartReplace
+    : CompositeEditCommand(new ReplaceSelectionCommandImpl(document, fragment, selectReplacement, smartReplace))
 {
 }
 
index f7ab11837a1ab904cd28ece39b6bb412568377cb..abf74a5741f2b49cddc90a0af1412a232cf5430f 100644 (file)
@@ -157,8 +157,8 @@ private:
 class DeleteSelectionCommand : public CompositeEditCommand
 {
 public:
-    DeleteSelectionCommand(DOM::DocumentImpl *document);
-    DeleteSelectionCommand(DOM::DocumentImpl *document, const DOM::Selection &selection);
+    DeleteSelectionCommand(DOM::DocumentImpl *document, bool smartDelete=false);
+    DeleteSelectionCommand(DOM::DocumentImpl *document, const DOM::Selection &selection, bool smartDelete=false);
 
 private:
     DeleteSelectionCommandImpl *impl() const;
@@ -261,7 +261,7 @@ private:
 class ReplaceSelectionCommand : public CompositeEditCommand
 {
 public:
-    ReplaceSelectionCommand(DOM::DocumentImpl *document, DOM::DocumentFragmentImpl *fragment, bool selectReplacement=true);
+    ReplaceSelectionCommand(DOM::DocumentImpl *document, DOM::DocumentFragmentImpl *fragment, bool selectReplacement=true, bool smartReplace=false);
 
 private:
     ReplaceSelectionCommandImpl *impl() const;
index e4e87c4ef0007359e68a3cad4526dfde981a68bd..6941d57fa67cc52c992b0cabb7ee0758b9762fd8 100644 (file)
@@ -984,13 +984,13 @@ Position ApplyStyleCommandImpl::positionInsertionPoint(Position pos)
 //------------------------------------------------------------------------------------------
 // DeleteSelectionCommandImpl
 
-DeleteSelectionCommandImpl::DeleteSelectionCommandImpl(DocumentImpl *document)
-    : CompositeEditCommandImpl(document), m_hasSelectionToDelete(false)
+DeleteSelectionCommandImpl::DeleteSelectionCommandImpl(DocumentImpl *document, bool smartDelete)
+    : CompositeEditCommandImpl(document), m_hasSelectionToDelete(false), m_smartDelete(smartDelete)
 {
 }
 
-DeleteSelectionCommandImpl::DeleteSelectionCommandImpl(DocumentImpl *document, const Selection &selection)
-    : CompositeEditCommandImpl(document), m_selectionToDelete(selection), m_hasSelectionToDelete(true)
+DeleteSelectionCommandImpl::DeleteSelectionCommandImpl(DocumentImpl *document, const Selection &selection, bool smartDelete)
+    : CompositeEditCommandImpl(document), m_selectionToDelete(selection), m_hasSelectionToDelete(true), m_smartDelete(smartDelete)
 {
 }
 
@@ -1103,6 +1103,14 @@ void DeleteSelectionCommandImpl::doApply()
     if (!m_selectionToDelete.isRange())
         return;
 
+    if (m_smartDelete) {
+        if (!m_selectionToDelete.start().leadingWhitespacePosition().isNull()) {
+            m_selectionToDelete.modify(DOM::Selection::EXTEND, DOM::Selection::LEFT, DOM::Selection::CHARACTER);
+        } else if (!m_selectionToDelete.end().trailingWhitespacePosition().isNull()) {
+            m_selectionToDelete.modify(DOM::Selection::EXTEND, DOM::Selection::RIGHT, DOM::Selection::CHARACTER);
+        }
+    }
+    
     Position upstreamStart(m_selectionToDelete.start().upstream(StayInBlock));
     Position downstreamStart(m_selectionToDelete.start().downstream(StayInBlock));
     Position upstreamEnd(m_selectionToDelete.end().upstream(StayInBlock));
@@ -1848,8 +1856,8 @@ void JoinTextNodesCommandImpl::doUnapply()
 //------------------------------------------------------------------------------------------
 // ReplaceSelectionCommandImpl
 
-ReplaceSelectionCommandImpl::ReplaceSelectionCommandImpl(DocumentImpl *document, DOM::DocumentFragmentImpl *fragment, bool selectReplacement) 
-    : CompositeEditCommandImpl(document), m_fragment(fragment), m_selectReplacement(selectReplacement)
+ReplaceSelectionCommandImpl::ReplaceSelectionCommandImpl(DocumentImpl *document, DOM::DocumentFragmentImpl *fragment, bool selectReplacement, bool smartReplace
+    : CompositeEditCommandImpl(document), m_fragment(fragment), m_selectReplacement(selectReplacement), m_smartReplace(smartReplace)
 {
     ASSERT(m_fragment);
     m_fragment->ref();
@@ -1880,15 +1888,32 @@ void ReplaceSelectionCommandImpl::doApply()
     setTypingStyle(0);
     
     selection = endingSelection();
-    ASSERT(!selection.isNone());
+    ASSERT(selection.isCaret());
+    
+    bool addLeadingSpace = false;
+    bool addTrailingSpace = false;
+    if (m_smartReplace) {
+        addLeadingSpace = selection.start().leadingWhitespacePosition().isNull();
+        addTrailingSpace = selection.start().trailingWhitespacePosition().isNull();
+    }
     
     if (!firstChild) {
         // Pasting something that didn't parse or was empty.
         ASSERT(!lastChild);
     } else if (firstChild == lastChild && firstChild->isTextNode()) {
+        // FIXME: HTML fragment case needs to be improved to the point
+        // where we can remove this separate case.
+        
         // Simple text paste. Treat as if the text were typed.
         Position upstreamStart(selection.start().upstream(StayInBlock));
-        inputText(static_cast<TextImpl *>(firstChild)->data());
+        DOMString text = static_cast<TextImpl *>(firstChild)->data();
+        if (addLeadingSpace) {
+            text = " " + text;
+        }
+        if (addTrailingSpace) {
+            text += " ";
+        }
+        inputText(text);
         if (m_selectReplacement) {
             // Select what was inserted.
             setEndingSelection(Selection(selection.base(), endingSelection().extent()));
@@ -1900,9 +1925,13 @@ void ReplaceSelectionCommandImpl::doApply()
     } 
     else {
         // HTML fragment paste.
+        
+        // FIXME: Add leading and trailing spaces to the fragment?
+        // Or just insert them as we insert it?
+        
         NodeImpl *beforeNode = firstChild;
         NodeImpl *node = firstChild->nextSibling();
-
+        
         insertNodeAt(firstChild, selection.start().node(), selection.start().offset());
         
         // Insert the nodes from the fragment
index d0c53083f5b91bf34a864c4380153042ac49efc7..1e4766b4bb7a9c44d27c515ce70800ecab7e24bf 100644 (file)
@@ -232,8 +232,8 @@ private:
 class DeleteSelectionCommandImpl : public CompositeEditCommandImpl
 { 
 public:
-    DeleteSelectionCommandImpl(DOM::DocumentImpl *document);
-    DeleteSelectionCommandImpl(DOM::DocumentImpl *document, const DOM::Selection &selection);
+    DeleteSelectionCommandImpl(DOM::DocumentImpl *document, bool smartDelete=false);
+    DeleteSelectionCommandImpl(DOM::DocumentImpl *document, const DOM::Selection &selection, bool smartDelete=false);
        
     virtual void doApply();
     
@@ -247,6 +247,7 @@ private:
 
     DOM::Selection m_selectionToDelete;
     bool m_hasSelectionToDelete;
+    bool m_smartDelete;
 };
 
 //------------------------------------------------------------------------------------------
@@ -380,7 +381,7 @@ private:
 class ReplaceSelectionCommandImpl : public CompositeEditCommandImpl
 {
 public:
-    ReplaceSelectionCommandImpl(DOM::DocumentImpl *document, DOM::DocumentFragmentImpl *fragment, bool selectReplacement=true);
+    ReplaceSelectionCommandImpl(DOM::DocumentImpl *document, DOM::DocumentFragmentImpl *fragment, bool selectReplacement=true, bool smartReplace=false);
     virtual ~ReplaceSelectionCommandImpl();
     
     virtual void doApply();
@@ -388,6 +389,7 @@ public:
 private:
     DOM::DocumentFragmentImpl *m_fragment;
     bool m_selectReplacement;
+    bool m_smartReplace;
 };
 
 //------------------------------------------------------------------------------------------
index 09bb4dc33b0830e8c7128ca1c2dafe965aa3ff1d..43999f83a72ffe282d7cb69035c6275efa02aa63 100644 (file)
@@ -309,10 +309,10 @@ typedef enum {
 - (DOMDocumentFragment *)documentFragmentWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString;
 - (DOMDocumentFragment *)documentFragmentWithText:(NSString *)text;
 
-- (void)replaceSelectionWithFragment:(DOMDocumentFragment *)fragment selectReplacement:(BOOL)selectReplacement;
-- (void)replaceSelectionWithNode:(DOMNode *)node selectReplacement:(BOOL)selectReplacement;
-- (void)replaceSelectionWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString selectReplacement:(BOOL)selectReplacement;
-- (void)replaceSelectionWithText:(NSString *)text selectReplacement:(BOOL)selectReplacement;
+- (void)replaceSelectionWithFragment:(DOMDocumentFragment *)fragment selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace;
+- (void)replaceSelectionWithNode:(DOMNode *)node selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace;
+- (void)replaceSelectionWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace;
+- (void)replaceSelectionWithText:(NSString *)text selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace;
 
 - (void)insertText:(NSString *)text selectInsertedText:(BOOL)selectInsertedText;
 - (void)insertNewline;
@@ -324,7 +324,7 @@ typedef enum {
 - (DOMRange *)dragCaretDOMRange;
 - (DOMRange *)editableDOMRangeForPoint:(NSPoint)point;
 
-- (void)deleteSelection;
+- (void)deleteSelectionWithSmartDelete:(BOOL)smartDelete;
 - (void)deleteKeyPressed;
 
 - (void)applyStyle:(DOMCSSStyleDeclaration *)style;
index 1ce1c5c33152bc13f0e112ef009e87d6254c4789..b17bc45e07fd39dc032e67396f9b2349df213b89 100644 (file)
@@ -1500,32 +1500,32 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
     return [DOMDocumentFragment _documentFragmentWithImpl:_part->documentFragmentWithText(text)];
 }
 
-- (void)replaceSelectionWithFragment:(DOMDocumentFragment *)fragment selectReplacement:(BOOL)selectReplacement
+- (void)replaceSelectionWithFragment:(DOMDocumentFragment *)fragment selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace
 {
     if (!_part || !_part->xmlDocImpl() || !fragment)
         return;
     
-    ReplaceSelectionCommand cmd(_part->xmlDocImpl(), [fragment _fragmentImpl], selectReplacement);
+    ReplaceSelectionCommand cmd(_part->xmlDocImpl(), [fragment _fragmentImpl], selectReplacement, smartReplace);
     cmd.apply();
     [self ensureCaretVisible];
 }
 
-- (void)replaceSelectionWithNode:(DOMNode *)node selectReplacement:(BOOL)selectReplacement
+- (void)replaceSelectionWithNode:(DOMNode *)node selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace
 {
     DOMDocumentFragment *fragment = [[self DOMDocument] createDocumentFragment];
     [fragment appendChild:node];
-    [self replaceSelectionWithFragment:fragment selectReplacement:selectReplacement];
+    [self replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace];
 }
 
-- (void)replaceSelectionWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString selectReplacement:(BOOL)selectReplacement
+- (void)replaceSelectionWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace
 {
     DOMDocumentFragment *fragment = [self documentFragmentWithMarkupString:markupString baseURLString:baseURLString];
-    [self replaceSelectionWithFragment:fragment selectReplacement:selectReplacement];
+    [self replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace];
 }
 
-- (void)replaceSelectionWithText:(NSString *)text selectReplacement:(BOOL)selectReplacement
+- (void)replaceSelectionWithText:(NSString *)text selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace
 {
-    [self replaceSelectionWithFragment:[self documentFragmentWithText:text] selectReplacement:selectReplacement];
+    [self replaceSelectionWithFragment:[self documentFragmentWithText:text] selectReplacement:selectReplacement smartReplace:smartReplace];
 }
 
 - (void)insertNewline
@@ -1593,7 +1593,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
     return position.isNull() ? nil : [DOMRange _rangeWithImpl:Selection(position).toRange().handle()];
 }
 
-- (void)deleteSelection
+- (void)deleteSelectionWithSmartDelete:(BOOL)smartDelete
 {
     if (!_part || !_part->xmlDocImpl())
         return;
@@ -1602,7 +1602,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
     if (!selection.isRange())
         return;
     
-    DeleteSelectionCommand cmd(_part->xmlDocImpl());
+    DeleteSelectionCommand cmd(_part->xmlDocImpl(), smartDelete);
     cmd.apply();
 }
 
index 7ef9c9c9716fb819f8868d6bcba8945e6f57faa6..0767da2977b9e99687fd605db97ffe62e6764dd2 100644 (file)
@@ -1,3 +1,45 @@
+2004-09-21  Chris Blumenberg  <cblu@apple.com
+
+       Fixed:
+       <rdar://problem/3735071> REGRESSION (Mail): WebCore Editing must do smart paste
+       <rdar://problem/3799163> REGRESSION (Mail): Deleting a word doesn't delete whitespace
+
+        Reviewed by darin.
+
+        * WebView.subproj/WebDataSource.m:
+        (-[WebDataSource _replaceSelectionWithArchive:selectReplacement:]): pass NO for smartReplace
+        * WebView.subproj/WebHTMLView.m:
+        (-[WebHTMLView _pasteWithPasteboard:allowPlainText:]): pass parameter for smartReplace using _canSmartReplaceWithPasteboard
+        (-[WebHTMLView _changeSpellingFromMenu:]): pass NO for smartReplace
+        (-[WebHTMLView pasteboardTypesForSelection]): include WebSmartPastePboardType when _canSmartCopyOrDelete return YES
+        (-[WebHTMLView writeSelectionWithPasteboardTypes:toPasteboard:]): ditto
+        (-[WebHTMLView concludeDragForDraggingInfo:actionMask:]): pass parameter for smartReplace using _canSmartReplaceWithPasteboard
+        (-[WebHTMLView delete:]): call _deleteSelection
+        (-[WebHTMLView cut:]): don't call delegate twice, call _deleteRange to delete
+        (-[WebHTMLView pasteAsPlainText:]): pass parameter for smartReplace using _canSmartReplaceWithPasteboard
+        (-[WebHTMLView _changeWordCaseWithSelector:]): pass NO for smartReplace
+        (-[WebHTMLView deleteBackward:]): call _deleteSelection when there is a selected range
+        (-[WebHTMLView _changeSpellingToWord:]): pass NO for smartReplace
+        (-[WebHTMLView deleteToMark:]): pass NO for smartDeleteOK
+        (-[WebHTMLView transpose:]): pass NO for smartReplace
+        (-[WebHTMLView _shouldDeleteRange:]): moved
+        (-[WebHTMLView _deleteRange:preflight:killRing:prepend:smartDeleteOK:]): moved, handle smartDelete
+        (-[WebHTMLView _deleteWithDirection:granularity:killRing:]): moved
+        (-[WebHTMLView _deleteSelection]): new
+       (-[WebHTMLView _canSmartReplaceWithPasteboard]): new
+       (-[WebHTMLView _canSmartCopyOrDelete]): new
+        (-[WebHTMLView setMarkedText:selectedRange:]): pass NO for smartReplace
+        (-[WebHTMLView _discardMarkedText]): call _deleteSelection
+        (-[WebTextCompleteController _insertMatch:]): pass NO for smartReplace
+        (-[WebTextCompleteController endRevertingChange:moveLeft:]): pass NO for smartReplace
+        * WebView.subproj/WebHTMLViewInternal.h:
+        * WebView.subproj/WebView.m:
+        (-[WebView _commonInitializationWithFrameName:groupName:]): set smartInsertDeleteEnabled to YES
+        (-[WebView replaceSelectionWithNode:]): pass NO for smartReplace
+        (-[WebView replaceSelectionWithText:]): pass NO for smartReplace
+        (-[WebView replaceSelectionWithMarkupString:]): pass NO for smartReplace
+        (-[WebView deleteSelection]): call _deleteSelection on WebHTMLView
+
 2004-09-21  John Sullivan  <sullivan@apple.com>
 
         Reviewed by Darin.
index cc0fa08297d139a85bfe67cffb4c1a93cc128a5f..060d0596a9eb709360447e3baa806f252b37764a 100644 (file)
 {
     DOMDocumentFragment *fragment = [self _documentFragmentWithArchive:archive];
     if (fragment) {
-        [[self _bridge] replaceSelectionWithFragment:fragment selectReplacement:selectReplacement];
+        [[self _bridge] replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:NO];
     }
 }
 
index 18d35c8b2eb29b990034989d34268e3043412137..113de220ba96a61986ec26a2de622840fe76a5d8 100644 (file)
@@ -141,6 +141,14 @@ static BOOL forceRealHitTest = NO;
 - (float)_calculatePrintHeight;
 - (void)_updateTextSizeMultiplier;
 - (DOMRange *)_selectedRange;
+- (BOOL)_shouldDeleteRange:(DOMRange *)range;
+- (void)_deleteRange:(DOMRange *)range 
+           preflight:(BOOL)preflight 
+            killRing:(BOOL)killRing 
+             prepend:(BOOL)prepend 
+       smartDeleteOK:(BOOL)smartDeleteOK;
+- (void)_deleteSelection;
+- (BOOL)_canSmartReplaceWithPasteboard:(NSPasteboard *)pasteboard;
 @end
 
 @interface WebHTMLView (WebForwardDeclaration) // FIXME: Put this in a normal category and stop doing the forward declaration trick.
@@ -351,7 +359,7 @@ static BOOL forceRealHitTest = NO;
     DOMDocumentFragment *fragment = [self _documentFragmentFromPasteboard:pasteboard allowPlainText:allowPlainText];
     WebBridge *bridge = [self _bridge];
     if (fragment && [self _shouldInsertFragment:fragment replacingDOMRange:[self _selectedRange] givenAction:WebViewInsertActionPasted]) {
-        [bridge replaceSelectionWithFragment:fragment selectReplacement:NO];
+        [bridge replaceSelectionWithFragment:fragment selectReplacement:NO smartReplace:[self _canSmartReplaceWithPasteboard:pasteboard]];
     }
 }
 
@@ -394,6 +402,54 @@ static BOOL forceRealHitTest = NO;
     return [[self _bridge] selectedDOMRange];
 }
 
+- (BOOL)_shouldDeleteRange:(DOMRange *)range
+{
+    if (range == nil || [range collapsed])
+        return NO;
+    WebView *webView = [self _webView];
+    return [[webView _editingDelegateForwarder] webView:webView shouldDeleteDOMRange:range];
+}
+
+- (void)_deleteRange:(DOMRange *)range 
+           preflight:(BOOL)preflight 
+            killRing:(BOOL)killRing 
+             prepend:(BOOL)prepend 
+       smartDeleteOK:(BOOL)smartDeleteOK 
+{
+    if (![self _shouldDeleteRange:range]) {
+        return;
+    }
+    WebBridge *bridge = [self _bridge];
+    if (killRing && _private->startNewKillRingSequence) {
+        _NSNewKillRingSequence();
+    }
+    [bridge setSelectedDOMRange:range affinity:NSSelectionAffinityUpstream];
+    if (killRing) {
+        if (prepend) {
+            _NSPrependToKillRing([bridge selectedString]);
+        } else {
+            _NSAppendToKillRing([bridge selectedString]);
+        }
+        _private->startNewKillRingSequence = NO;
+    }
+    BOOL smartDelete = smartDeleteOK ? [self _canSmartCopyOrDelete] : NO;
+    [bridge deleteSelectionWithSmartDelete:smartDelete];
+}
+
+- (void)_deleteSelection
+{
+    [self _deleteRange:[self _selectedRange]
+             preflight:YES 
+              killRing:YES 
+               prepend:NO
+         smartDeleteOK:YES];
+}
+
+- (BOOL)_canSmartReplaceWithPasteboard:(NSPasteboard *)pasteboard
+{
+    return [[self _webView] smartInsertDeleteEnabled] && [[pasteboard types] containsObject:WebSmartPastePboardType];
+}
+
 @end
 
 @implementation WebHTMLView (WebPrivate)
@@ -1187,7 +1243,7 @@ static WebHTMLView *lastHitView = nil;
 - (void)_changeSpellingFromMenu:(id)sender
 {
     ASSERT([[self selectedString] length] != 0);
-    [[self _bridge] replaceSelectionWithText:[sender title] selectReplacement:YES];
+    [[self _bridge] replaceSelectionWithText:[sender title] selectReplacement:YES smartReplace:NO];
 }
 
 - (void)_ignoreSpellingFromMenu:(id)sender
@@ -1349,7 +1405,7 @@ static WebHTMLView *lastHitView = nil;
 
 - (NSArray *)pasteboardTypesForSelection
 {
-    if ([[self _bridge] selectionGranularity] == WebSelectByWord) {
+    if ([self _canSmartCopyOrDelete]) {
         NSMutableArray *types = [[[[self class] _selectionPasteboardTypes] mutableCopy] autorelease];
         [types addObject:WebSmartPastePboardType];
         return types;
@@ -1429,7 +1485,7 @@ static WebHTMLView *lastHitView = nil;
         [s release];
     }
     
-    if ([types containsObject:WebSmartPastePboardType] && [[self _bridge] selectionGranularity] == WebSelectByWord) {
+    if ([self _canSmartCopyOrDelete] && [types containsObject:WebSmartPastePboardType]) {
         [pasteboard setData:nil forType:WebSmartPastePboardType];
     }
 }
@@ -2235,14 +2291,15 @@ static WebHTMLView *lastHitView = nil;
     } else if (actionMask & WebDragDestinationActionEdit) {
         BOOL didInsert = NO;
         if ([self _canProcessDragWithDraggingInfo:draggingInfo]) {
-            DOMDocumentFragment *fragment = [self _documentFragmentFromPasteboard:[draggingInfo draggingPasteboard] allowPlainText:YES];
+            NSPasteboard *pasteboard = [draggingInfo draggingPasteboard];
+            DOMDocumentFragment *fragment = [self _documentFragmentFromPasteboard:pasteboard allowPlainText:YES];
             if (fragment && [self _shouldInsertFragment:fragment replacingDOMRange:[bridge dragCaretDOMRange] givenAction:WebViewInsertActionDropped]) {
                 [[webView _UIDelegateForwarder] webView:webView willPerformDragDestinationAction:WebDragDestinationActionEdit forDraggingInfo:draggingInfo];
                 if ([self _isMoveDrag]) {
                     [bridge moveSelectionToDragCaret:fragment];
                 } else {
                     [bridge setSelectionToDragCaret];
-                    [bridge replaceSelectionWithFragment:fragment selectReplacement:YES];
+                    [bridge replaceSelectionWithFragment:fragment selectReplacement:YES smartReplace:[self _canSmartReplaceWithPasteboard:pasteboard]];
                 }
                 didInsert = YES;
             }
@@ -2888,47 +2945,19 @@ static WebHTMLView *lastHitView = nil;
     [self _writeSelectionToPasteboard:[NSPasteboard generalPasteboard]];
 }
 
-- (BOOL)_shouldDeleteRange:(DOMRange *)range
-{
-    if (range == nil || [range collapsed])
-        return NO;
-    WebView *webView = [self _webView];
-    return [[webView _editingDelegateForwarder] webView:webView shouldDeleteDOMRange:range];
-}
-
-- (void)_deleteRange:(DOMRange *)range preflight:(BOOL)preflight killRing:(BOOL)killRing prepend:(BOOL)prepend
-{
-    if (![self _shouldDeleteRange:range]) {
-        return;
-    }
-    WebBridge *bridge = [self _bridge];
-    if (killRing && _private->startNewKillRingSequence) {
-        _NSNewKillRingSequence();
-    }
-    [bridge setSelectedDOMRange:range affinity:NSSelectionAffinityUpstream];
-    if (killRing) {
-        if (prepend) {
-            _NSPrependToKillRing([bridge selectedString]);
-        } else {
-            _NSAppendToKillRing([bridge selectedString]);
-        }
-        _private->startNewKillRingSequence = NO;
-    }
-    [bridge deleteSelection];
-}
-
 - (void)delete:(id)sender
 {
     if (![self _canDelete]) {
         NSBeep();
         return;
     }
-    [self _deleteRange:[self _selectedRange] preflight:YES killRing:YES prepend:NO];
+    [self _deleteSelection];
 }
 
 - (void)cut:(id)sender
 {
-    if ([[self _bridge] tryDHTMLCut]) {
+    WebBridge *bridge = [self _bridge];
+    if ([bridge tryDHTMLCut]) {
         return;     // DHTML did the whole operation
     }
     if (![self _canCut]) {
@@ -2938,8 +2967,8 @@ static WebHTMLView *lastHitView = nil;
     DOMRange *range = [self _selectedRange];
     if ([self _shouldDeleteRange:range]) {
         [self _writeSelectionToPasteboard:[NSPasteboard generalPasteboard]];
-        [self _deleteRange:[self _selectedRange] preflight:NO killRing:YES prepend:NO];
-    }
+        [bridge deleteSelectionWithSmartDelete:[self _canSmartCopyOrDelete]];
+   }
 }
 
 - (void)paste:(id)sender
@@ -3043,10 +3072,11 @@ static WebHTMLView *lastHitView = nil;
 
 - (void)pasteAsPlainText:(id)sender
 {
-    NSString *text = [[NSPasteboard generalPasteboard] stringForType:NSStringPboardType];
+    NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
+    NSString *text = [pasteboard stringForType:NSStringPboardType];
     WebBridge *bridge = [self _bridge];
     if ([self _shouldReplaceSelectionWithText:text givenAction:WebViewInsertActionPasted]) {
-        [bridge replaceSelectionWithText:text selectReplacement:NO];
+        [bridge replaceSelectionWithText:text selectReplacement:NO smartReplace:[self _canSmartReplaceWithPasteboard:pasteboard]];
     }
 }
 
@@ -3386,7 +3416,7 @@ NSStrokeColorAttributeName        /* NSColor, default nil: same as foreground co
     NSString *word = [[bridge selectedString] performSelector:selector];
     // FIXME: Does this need a different action context other than "typed"?
     if ([self _shouldReplaceSelectionWithText:word givenAction:WebViewInsertActionTyped]) {
-        [bridge replaceSelectionWithText:word selectReplacement:NO];
+        [bridge replaceSelectionWithText:word selectReplacement:NO smartReplace:NO];
     }
 }
 
@@ -3413,8 +3443,10 @@ NSStrokeColorAttributeName        /* NSColor, default nil: same as foreground co
         return NO;
     DOMRange *range;
     BOOL prepend = NO;
+    BOOL smartDeleteOK = NO;
     if ([self _hasSelection]) {
         range = [self _selectedRange];
+        smartDeleteOK = YES;
     } else {
         WebBridge *bridge = [self _bridge];
         range = [bridge rangeByAlteringCurrentSelection:WebSelectByExtending direction:direction granularity:granularity];
@@ -3430,7 +3462,7 @@ NSStrokeColorAttributeName        /* NSColor, default nil: same as foreground co
                 break;
         }
     }
-    [self _deleteRange:range preflight:YES killRing:killRing prepend:prepend];
+    [self _deleteRange:range preflight:YES killRing:killRing prepend:prepend smartDeleteOK:smartDeleteOK];
     return YES;
 }
 
@@ -3443,10 +3475,11 @@ NSStrokeColorAttributeName        /* NSColor, default nil: same as foreground co
 {
     if (![self _isEditable])
         return;
-    WebBridge *bridge = [self _bridge];
-    WebView *webView = [self _webView];
-    if ([[webView _editingDelegateForwarder] webView:webView shouldDeleteDOMRange:[self _selectedRange]]) {
-        [bridge deleteKeyPressed];
+    if ([self _hasSelection]) {
+        [self _deleteSelection];
+    } else {
+        // FIXME: We are not calling the delegate here. Why can't we just call _deleteRange here?
+        [[self _bridge] deleteKeyPressed];
     }
 }
 
@@ -3546,7 +3579,7 @@ NSStrokeColorAttributeName        /* NSColor, default nil: same as foreground co
     }
 
     if ([self _shouldReplaceSelectionWithText:newWord givenAction:WebViewInsertActionPasted]) {
-        [bridge replaceSelectionWithText:newWord selectReplacement:YES];
+        [bridge replaceSelectionWithText:newWord selectReplacement:YES smartReplace:NO];
     }
 }
 
@@ -3682,7 +3715,7 @@ static DOMRange *unionDOMRanges(DOMRange *a, DOMRange *b)
         } @catch (NSException *exception) {
             r = selection;
         }
-        [self _deleteRange:r preflight:YES killRing:YES prepend:YES];
+        [self _deleteRange:r preflight:YES killRing:YES prepend:YES smartDeleteOK:NO];
     }
     [self setMark:sender];
 }
@@ -3739,7 +3772,7 @@ static DOMRange *unionDOMRanges(DOMRange *a, DOMRange *b)
     }
     [bridge setSelectedDOMRange:r affinity:NSSelectionAffinityUpstream];
     if ([self _shouldReplaceSelectionWithText:transposed givenAction:WebViewInsertActionTyped]) {
-        [bridge replaceSelectionWithText:transposed selectReplacement:NO];
+        [bridge replaceSelectionWithText:transposed selectReplacement:NO smartReplace:NO];
     }
 }
 
@@ -3924,6 +3957,11 @@ static DOMRange *unionDOMRanges(DOMRange *a, DOMRange *b)
     return _private->dragSourceActionMask;
 }
 
+- (BOOL)_canSmartCopyOrDelete
+{
+    return [[self _webView] smartInsertDeleteEnabled] && [[self _bridge] selectionGranularity] == WebSelectByWord;
+}
+
 @end
 
 @implementation WebHTMLView (WebNSTextInputSupport)
@@ -4036,7 +4074,7 @@ static DOMRange *unionDOMRanges(DOMRange *a, DOMRange *b)
        text = string;
     }
 
-    [bridge replaceSelectionWithText:text selectReplacement:YES];
+    [bridge replaceSelectionWithText:text selectReplacement:YES smartReplace:NO];
     [bridge setMarkedTextDOMRange:[self _selectedRange]];
     [self _selectRangeInMarkedText:newSelRange];
 
@@ -4063,7 +4101,8 @@ static DOMRange *unionDOMRanges(DOMRange *a, DOMRange *b)
     [self _selectMarkedText];
     [[NSInputManager currentInputManager] markedTextAbandoned:self];
     [self unmarkText];
-    [[self _bridge] deleteSelection];
+    // FIXME: Should we be calling the delegate here?
+    [[self _bridge] deleteSelectionWithSmartDelete:NO];
 
     _private->ignoreMarkedTextSelectionChange = NO;
 }
@@ -4186,7 +4225,7 @@ static DOMRange *unionDOMRanges(DOMRange *a, DOMRange *b)
     // able to revert that).  Mimic NSText.
     WebBridge *bridge = [_view _bridge];
     NSString *newText = [match substringFromIndex:prefixLength];
-    [bridge replaceSelectionWithText:newText selectReplacement:YES];
+    [bridge replaceSelectionWithText:newText selectReplacement:YES smartReplace:NO];
 }
 
 // mostly lifted from NSTextView_KeyBinding.m
@@ -4339,7 +4378,7 @@ static DOMRange *unionDOMRanges(DOMRange *a, DOMRange *b)
 
         if (revertChange) {
             WebBridge *bridge = [_view _bridge];
-            [bridge replaceSelectionWithText:_originalString selectReplacement:YES];
+            [bridge replaceSelectionWithText:_originalString selectReplacement:YES smartReplace:NO];
         } else if (goLeft) {
             [_view moveBackward:nil];
         } else {
index 6fca00eb9f13960b550c20c985904d3f135402d6..5c72bc4b40872cdc1287a34a6a6f206be617e738 100644 (file)
@@ -58,4 +58,5 @@
 - (void)_selectionChanged;
 - (void)_updateFontPanel;
 - (unsigned int)_delegateDragSourceActionMask;
+- (BOOL)_canSmartCopyOrDelete;
 @end
index e5648f0b2e03d4424e3ae4b28d8a0e2f3ba12951..d3b2ae78e5b9f58223159581a23f75c131f360c5 100644 (file)
@@ -31,8 +31,7 @@
 #import <WebKit/WebFrameViewInternal.h>
 #import <WebKit/WebHistoryItemPrivate.h>
 #import <WebKit/WebHTMLRepresentation.h>
-#import <WebKit/WebHTMLView.h>
-#import <WebKit/WebHTMLViewPrivate.h>
+#import <WebKit/WebHTMLViewInternal.h>
 #import <WebKit/WebIconDatabase.h>
 #import <WebKit/WebKitErrors.h>
 #import <WebKit/WebKitLogging.h>
@@ -1251,6 +1250,7 @@ NSMutableDictionary *countInvocations;
 - (void)_commonInitializationWithFrameName:(NSString *)frameName groupName:(NSString *)groupName
 {
     _private->drawsBackground = YES;
+    _private->smartInsertDeleteEnabled = YES;
 
     NSRect f = [self frame];
     WebFrameView *wv = [[WebFrameView alloc] initWithFrame: NSMakeRect(0,0,f.size.width,f.size.height)];
@@ -2564,17 +2564,17 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
 
 - (void)replaceSelectionWithNode:(DOMNode *)node
 {
-    [[self _bridgeForCurrentSelection] replaceSelectionWithNode:node selectReplacement:YES];
+    [[self _bridgeForCurrentSelection] replaceSelectionWithNode:node selectReplacement:YES smartReplace:NO];
 }    
 
 - (void)replaceSelectionWithText:(NSString *)text
 {
-    [[self _bridgeForCurrentSelection] replaceSelectionWithText:text selectReplacement:YES];
+    [[self _bridgeForCurrentSelection] replaceSelectionWithText:text selectReplacement:YES smartReplace:NO];
 }
 
 - (void)replaceSelectionWithMarkupString:(NSString *)markupString
 {
-    [[self _bridgeForCurrentSelection] replaceSelectionWithMarkupString:markupString baseURLString:nil selectReplacement:YES];
+    [[self _bridgeForCurrentSelection] replaceSelectionWithMarkupString:markupString baseURLString:nil selectReplacement:YES smartReplace:NO];
 }
 
 - (void)replaceSelectionWithArchive:(WebArchive *)archive
@@ -2584,7 +2584,8 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
 
 - (void)deleteSelection
 {
-    [[self _bridgeForCurrentSelection] deleteSelection];
+    WebBridge *bridge = [self _bridgeForCurrentSelection];
+    [bridge deleteSelectionWithSmartDelete:[(WebHTMLView *)[[[bridge webFrame] frameView] documentView] _canSmartCopyOrDelete]];
 }
     
 - (void)applyStyle:(DOMCSSStyleDeclaration *)style