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
+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.
//------------------------------------------------------------------------------------------
// 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))
{
}
//------------------------------------------------------------------------------------------
// 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))
{
}
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;
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;
//------------------------------------------------------------------------------------------
// 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)
{
}
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));
//------------------------------------------------------------------------------------------
// 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();
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()));
}
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
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();
DOM::Selection m_selectionToDelete;
bool m_hasSelectionToDelete;
+ bool m_smartDelete;
};
//------------------------------------------------------------------------------------------
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();
private:
DOM::DocumentFragmentImpl *m_fragment;
bool m_selectReplacement;
+ bool m_smartReplace;
};
//------------------------------------------------------------------------------------------
- (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;
- (DOMRange *)dragCaretDOMRange;
- (DOMRange *)editableDOMRangeForPoint:(NSPoint)point;
-- (void)deleteSelection;
+- (void)deleteSelectionWithSmartDelete:(BOOL)smartDelete;
- (void)deleteKeyPressed;
- (void)applyStyle:(DOMCSSStyleDeclaration *)style;
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
return position.isNull() ? nil : [DOMRange _rangeWithImpl:Selection(position).toRange().handle()];
}
-- (void)deleteSelection
+- (void)deleteSelectionWithSmartDelete:(BOOL)smartDelete
{
if (!_part || !_part->xmlDocImpl())
return;
if (!selection.isRange())
return;
- DeleteSelectionCommand cmd(_part->xmlDocImpl());
+ DeleteSelectionCommand cmd(_part->xmlDocImpl(), smartDelete);
cmd.apply();
}
+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.
{
DOMDocumentFragment *fragment = [self _documentFragmentWithArchive:archive];
if (fragment) {
- [[self _bridge] replaceSelectionWithFragment:fragment selectReplacement:selectReplacement];
+ [[self _bridge] replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace: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.
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]];
}
}
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)
- (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
- (NSArray *)pasteboardTypesForSelection
{
- if ([[self _bridge] selectionGranularity] == WebSelectByWord) {
+ if ([self _canSmartCopyOrDelete]) {
NSMutableArray *types = [[[[self class] _selectionPasteboardTypes] mutableCopy] autorelease];
[types addObject:WebSmartPastePboardType];
return types;
[s release];
}
- if ([types containsObject:WebSmartPastePboardType] && [[self _bridge] selectionGranularity] == WebSelectByWord) {
+ if ([self _canSmartCopyOrDelete] && [types containsObject:WebSmartPastePboardType]) {
[pasteboard setData:nil forType:WebSmartPastePboardType];
}
}
} 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;
}
[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]) {
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
- (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]];
}
}
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];
}
}
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];
break;
}
}
- [self _deleteRange:range preflight:YES killRing:killRing prepend:prepend];
+ [self _deleteRange:range preflight:YES killRing:killRing prepend:prepend smartDeleteOK:smartDeleteOK];
return YES;
}
{
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];
}
}
}
if ([self _shouldReplaceSelectionWithText:newWord givenAction:WebViewInsertActionPasted]) {
- [bridge replaceSelectionWithText:newWord selectReplacement:YES];
+ [bridge replaceSelectionWithText:newWord selectReplacement:YES smartReplace:NO];
}
}
} @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];
}
}
[bridge setSelectedDOMRange:r affinity:NSSelectionAffinityUpstream];
if ([self _shouldReplaceSelectionWithText:transposed givenAction:WebViewInsertActionTyped]) {
- [bridge replaceSelectionWithText:transposed selectReplacement:NO];
+ [bridge replaceSelectionWithText:transposed selectReplacement:NO smartReplace:NO];
}
}
return _private->dragSourceActionMask;
}
+- (BOOL)_canSmartCopyOrDelete
+{
+ return [[self _webView] smartInsertDeleteEnabled] && [[self _bridge] selectionGranularity] == WebSelectByWord;
+}
+
@end
@implementation WebHTMLView (WebNSTextInputSupport)
text = string;
}
- [bridge replaceSelectionWithText:text selectReplacement:YES];
+ [bridge replaceSelectionWithText:text selectReplacement:YES smartReplace:NO];
[bridge setMarkedTextDOMRange:[self _selectedRange]];
[self _selectRangeInMarkedText:newSelRange];
[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;
}
// 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
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 {
- (void)_selectionChanged;
- (void)_updateFontPanel;
- (unsigned int)_delegateDragSourceActionMask;
+- (BOOL)_canSmartCopyOrDelete;
@end
#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>
- (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)];
- (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
- (void)deleteSelection
{
- [[self _bridgeForCurrentSelection] deleteSelection];
+ WebBridge *bridge = [self _bridgeForCurrentSelection];
+ [bridge deleteSelectionWithSmartDelete:[(WebHTMLView *)[[[bridge webFrame] frameView] documentView] _canSmartCopyOrDelete]];
}
- (void)applyStyle:(DOMCSSStyleDeclaration *)style