void InsertTextCommand::input(const DOMString &text, bool selectInsertedText)
{
+ assert(text.find('\n') == -1);
+
Selection selection = endingSelection();
bool adjustDownstream = isFirstVisiblePositionOnLine(VisiblePosition(selection.start().downstream(StayInBlock), DOWNSTREAM));
}
void TypingCommand::insertText(const DOMString &text, bool selectInsertedText)
+{
+ // FIXME: Need to implement selectInsertedText for cases where more than one insert is involved.
+ // This requires support from insertTextRunWithoutNewlines and insertParagraphSeparator for extending
+ // an existing selection; at the moment they can either put the caret after what's inserted or
+ // select what's inserted, but there's no way to "extend selection" to include both an old selection
+ // that ends just before where we want to insert text and the newly inserted text.
+ int offset = 0;
+ int newline;
+ while ((newline = text.find('\n', offset)) != -1) {
+ if (newline != offset) {
+ insertTextRunWithoutNewlines(text.substring(offset, newline - offset), false);
+ }
+ insertParagraphSeparator();
+ offset = newline + 1;
+ }
+ if (offset == 0) {
+ insertTextRunWithoutNewlines(text, selectInsertedText);
+ } else {
+ int length = text.length();
+ if (length != offset) {
+ insertTextRunWithoutNewlines(text.substring(offset, length - offset), selectInsertedText);
+ }
+ }
+}
+
+void TypingCommand::insertTextRunWithoutNewlines(const DOMString &text, bool selectInsertedText)
{
// FIXME: Improve typing style.
// See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
+2005-03-04 Darin Adler <darin@apple.com>
+
+ Reviewed by John.
+
+ - fixed <rdar://problem/4036817> REGRESSION: ctrl-y broken when a line + carriage return cut
+
+ * WebView.subproj/WebHTMLView.m:
+ (-[WebHTMLView _deleteRange:killRing:prepend:smartDeleteOK:deletionAction:]): Merged _handleKillRing behavior
+ into this function, since there's now a more-complicated way the startNewKillRingSequence boolean needs to
+ be handled. Set the startNewKillRingSequence boolean after the entire process so changing the selection before
+ and during the editing dosn't clear it. Also change "isTypingAction" parameter to "deletionAction" so we can
+ handle forward delete with this method.
+ (-[WebHTMLView _deleteSelection]): Pass deleteSelectionAction for action rather than NO for isTypingAction,
+ which is the way to say the same thing using the new parameter.
+ (-[WebHTMLView _deleteWithDirection:granularity:killRing:isTypingAction:]): Refactor to use the _deleteRange
+ method above. Also calls _shouldDeleteRange: for the pre-existing selection case; not doing that before was
+ a bug.
+ (-[WebHTMLView deleteToMark:]): Pass deleteSelectionAction for action rather than NO for isTypingAction,
+ which is the way to say the same thing using the new parameter.
+
2005-03-04 Darin Adler <darin@apple.com>
Reviewed by John.
// FIXME: This constant is copied from AppKit's _NXSmartPaste constant.
#define WebSmartPastePboardType @"NeXT smart paste pasteboard type"
+typedef enum {
+ deleteSelectionAction,
+ deleteKeyAction,
+ forwardDeleteKeyAction
+} WebDeletionAction;
+
static BOOL forceRealHitTest = NO;
// Used to avoid linking with ApplicationServices framework for _DCMDictionaryServiceWindowShow
- (void)_updateTextSizeMultiplier;
- (DOMRange *)_selectedRange;
- (BOOL)_shouldDeleteRange:(DOMRange *)range;
-- (void)_handleKillRing:(BOOL)hasKillRing prepend:(BOOL)prepend;
- (void)_deleteRange:(DOMRange *)range
killRing:(BOOL)killRing
prepend:(BOOL)prepend
smartDeleteOK:(BOOL)smartDeleteOK
- isTypingAction:(BOOL)isTypingAction;
+ deletionAction:(WebDeletionAction)deletionAction;
- (void)_deleteSelection;
- (BOOL)_canSmartReplaceWithPasteboard:(NSPasteboard *)pasteboard;
- (NSView *)_hitViewForEvent:(NSEvent *)event;
return [[webView _editingDelegateForwarder] webView:webView shouldDeleteDOMRange:range];
}
-- (void)_handleKillRing:(BOOL)hasKillRing prepend:(BOOL)prepend
-{
- if (!hasKillRing)
- return;
-
- WebBridge *bridge = [self _bridge];
- if (_private->startNewKillRingSequence) {
- _NSNewKillRingSequence();
- }
- if (prepend) {
- _NSPrependToKillRing([bridge selectedString]);
- } else {
- _NSAppendToKillRing([bridge selectedString]);
- }
- _private->startNewKillRingSequence = NO;
-}
-
- (void)_deleteRange:(DOMRange *)range
killRing:(BOOL)killRing
prepend:(BOOL)prepend
smartDeleteOK:(BOOL)smartDeleteOK
- isTypingAction:(BOOL)isTypingAction
+ deletionAction:(WebDeletionAction)deletionAction
{
if (![self _shouldDeleteRange:range]) {
return;
}
+
WebBridge *bridge = [self _bridge];
- [bridge setSelectedDOMRange:range affinity:NSSelectionAffinityDownstream];
- [self _handleKillRing:killRing prepend:prepend];
BOOL smartDelete = smartDeleteOK ? [self _canSmartCopyOrDelete] : NO;
- if (isTypingAction) {
- [bridge deleteKeyPressedWithSmartDelete:smartDelete];
+
+ BOOL startNewKillRingSequence = _private->startNewKillRingSequence;
+
+ if (killRing) {
+ if (startNewKillRingSequence) {
+ _NSNewKillRingSequence();
+ }
+ NSString *string = [bridge stringForRange:range];
+ if (prepend) {
+ _NSPrependToKillRing(string);
+ } else {
+ _NSAppendToKillRing(string);
+ }
+ startNewKillRingSequence = NO;
}
- else {
- [bridge deleteSelectionWithSmartDelete:smartDelete];
+
+ [bridge setSelectedDOMRange:range affinity:NSSelectionAffinityDownstream];
+ switch (deletionAction) {
+ case deleteSelectionAction:
+ [bridge deleteSelectionWithSmartDelete:smartDelete];
+ break;
+ case deleteKeyAction:
+ [bridge deleteKeyPressedWithSmartDelete:smartDelete];
+ break;
+ case forwardDeleteKeyAction:
+ [bridge forwardDeleteKeyPressedWithSmartDelete:smartDelete];
+ break;
}
+
+ _private->startNewKillRingSequence = startNewKillRingSequence;
}
- (void)_deleteSelection
killRing:YES
prepend:NO
smartDeleteOK:YES
- isTypingAction:NO];
+ deletionAction:deleteSelectionAction];
}
- (BOOL)_canSmartReplaceWithPasteboard:(NSPasteboard *)pasteboard
{
// Delete the selection, if there is one.
// If not, make a selection using the passed-in direction and granularity.
+
if (![self _canEdit])
return NO;
-
+
DOMRange *range;
+ WebDeletionAction deletionAction = deleteSelectionAction;
+
if ([self _hasSelection]) {
range = [self _selectedRange];
- [self _deleteRange:range killRing:killRing prepend:NO smartDeleteOK:YES isTypingAction:isTypingAction];
+ deletionAction = isTypingAction ? deleteSelectionAction : deleteKeyAction;
} else {
- WebBridge *bridge = [self _bridge];
- range = [bridge rangeByAlteringCurrentSelection:WebSelectByExtending direction:direction granularity:granularity];
- if (range == nil || [range collapsed] || ![self _shouldDeleteRange:range])
- return NO;
+ range = [[self _bridge] rangeByAlteringCurrentSelection:WebSelectByExtending direction:direction granularity:granularity];
switch (direction) {
case WebSelectForward:
case WebSelectRight:
- [bridge setSelectedDOMRange:range affinity:NSSelectionAffinityDownstream];
- [self _handleKillRing:killRing prepend:NO];
- [bridge forwardDeleteKeyPressedWithSmartDelete:NO];
+ deletionAction = forwardDeleteKeyAction;
break;
case WebSelectBackward:
case WebSelectLeft:
- [bridge setSelectedDOMRange:range affinity:NSSelectionAffinityDownstream];
- [self _handleKillRing:killRing prepend:YES];
- [bridge deleteKeyPressedWithSmartDelete:NO];
+ deletionAction = deleteKeyAction;
break;
}
}
+
+ if (range == nil || [range collapsed] || ![self _shouldDeleteRange:range])
+ return NO;
+ [self _deleteRange:range killRing:killRing prepend:NO smartDeleteOK:YES deletionAction:deletionAction];
return YES;
}
} @catch (NSException *exception) {
r = selection;
}
- [self _deleteRange:r killRing:YES prepend:YES smartDeleteOK:NO isTypingAction:NO];
+ [self _deleteRange:r killRing:YES prepend:YES smartDeleteOK:NO deletionAction:deleteSelectionAction];
}
[self setMark:sender];
}