summaryrefslogtreecommitdiffstats
path: root/Source/WebKit/mac/WebView/WebHTMLView.mm
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit/mac/WebView/WebHTMLView.mm')
-rw-r--r--Source/WebKit/mac/WebView/WebHTMLView.mm325
1 files changed, 195 insertions, 130 deletions
diff --git a/Source/WebKit/mac/WebView/WebHTMLView.mm b/Source/WebKit/mac/WebView/WebHTMLView.mm
index 00f65bd..e611e2b 100644
--- a/Source/WebKit/mac/WebView/WebHTMLView.mm
+++ b/Source/WebKit/mac/WebView/WebHTMLView.mm
@@ -383,6 +383,7 @@ static CachedResourceClient* promisedDataClient()
- (DOMDocumentFragment *)_documentFragmentFromPasteboard:(NSPasteboard *)pasteboard inContext:(DOMRange *)context allowPlainText:(BOOL)allowPlainText;
- (NSString *)_plainTextFromPasteboard:(NSPasteboard *)pasteboard;
- (void)_pasteWithPasteboard:(NSPasteboard *)pasteboard allowPlainText:(BOOL)allowPlainText;
+- (void)_pasteAsPlainTextWithPasteboard:(NSPasteboard *)pasteboard;
- (void)_removeMouseMovedObserverUnconditionally;
- (void)_removeSuperviewObservers;
- (void)_removeWindowObservers;
@@ -461,11 +462,9 @@ static CachedResourceClient* promisedDataClient()
struct WebHTMLViewInterpretKeyEventsParameters {
KeyboardEvent* event;
- BOOL eventWasHandled;
- BOOL shouldSaveCommand;
- // The Input Method may consume an event and not tell us, in
- // which case we should not bubble the event up the DOM
- BOOL consumedByIM;
+ bool eventInterpretationHadSideEffects;
+ bool shouldSaveCommands;
+ bool consumedByIM;
};
@interface WebHTMLViewPrivate : NSObject {
@@ -522,7 +521,6 @@ struct WebHTMLViewInterpretKeyEventsParameters {
BOOL transparentBackground;
WebHTMLViewInterpretKeyEventsParameters* interpretKeyEventsParameters;
- BOOL receivedNOOP;
WebDataSource *dataSource;
WebCore::CachedImage* promisedDragTIFFDataSource;
@@ -914,6 +912,32 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
[webView release];
}
+- (void)_pasteAsPlainTextWithPasteboard:(NSPasteboard *)pasteboard
+{
+ WebView *webView = [[self _webView] retain];
+ [webView _setInsertionPasteboard:pasteboard];
+
+ NSString *text = [self _plainTextFromPasteboard:pasteboard];
+ if ([self _shouldReplaceSelectionWithText:text givenAction:WebViewInsertActionPasted])
+ [[self _frame] _replaceSelectionWithText:text selectReplacement:NO smartReplace:[self _canSmartReplaceWithPasteboard:pasteboard]];
+
+ [webView _setInsertionPasteboard:nil];
+ [webView release];
+}
+
+// This method is needed to support Mac OS X services.
+- (BOOL)readSelectionFromPasteboard:(NSPasteboard *)pasteboard
+{
+ Frame* coreFrame = core([self _frame]);
+ if (!coreFrame)
+ return NO;
+ if (coreFrame->selection()->isContentRichlyEditable())
+ [self _pasteWithPasteboard:pasteboard allowPlainText:YES];
+ else
+ [self _pasteAsPlainTextWithPasteboard:pasteboard];
+ return YES;
+}
+
- (void)_removeMouseMovedObserverUnconditionally
{
if (!_private || !_private->observingMouseMovedNotifications)
@@ -1169,21 +1193,7 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
+ (NSArray *)unsupportedTextMIMETypes
{
- return [NSArray arrayWithObjects:
- @"text/calendar", // iCal
- @"text/x-calendar",
- @"text/x-vcalendar",
- @"text/vcalendar",
- @"text/vcard", // vCard
- @"text/x-vcard",
- @"text/directory",
- @"text/ldif", // Netscape Address Book
- @"text/qif", // Quicken
- @"text/x-qif",
- @"text/x-csv", // CSV (for Address Book and Microsoft Outlook)
- @"text/x-vcf", // vCard type used in Sun affinity app
- @"text/rtf", // Rich Text Format
- nil];
+ return [WebHTMLRepresentation unsupportedTextMIMETypes];
}
+ (void)_postFlagsChangedEvent:(NSEvent *)flagsChangedEvent
@@ -1985,10 +1995,6 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info)
[self removeAllToolTips];
[_private clear];
-
- Page* page = core([self _webView]);
- if (page)
- page->dragController()->setDraggingImageURL(KURL());
}
- (BOOL)_hasHTMLDocument
@@ -2608,6 +2614,7 @@ WEBCORE_COMMAND(yankAndSelect)
[NSPasteboard _web_setFindPasteboardString:[self selectedString] withOwner:self];
}
+// This method is needed to support Mac OS X services.
- (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pasteboard types:(NSArray *)types
{
[pasteboard declareTypes:types owner:[self _topHTMLView]];
@@ -3036,7 +3043,12 @@ WEBCORE_COMMAND(yankAndSelect)
// We may have created the layer hosting view while outside the window. Update the scale factor
// now that we have a window to get it from.
if (_private->layerHostingView) {
- CGFloat scaleFactor = [[self window] userSpaceScaleFactor];
+ CGFloat scaleFactor;
+#if !defined(BUILDING_ON_SNOW_LEOPARD)
+ scaleFactor = [[self window] backingScaleFactor];
+#else
+ scaleFactor = [[self window] userSpaceScaleFactor];
+#endif
[[_private->layerHostingView layer] setTransform:CATransform3DMakeScale(scaleFactor, scaleFactor, 1)];
}
#endif
@@ -5416,59 +5428,96 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point)
[self _updateMouseoverWithFakeEvent];
}
-- (BOOL)_interceptEditingKeyEvent:(KeyboardEvent*)event shouldSaveCommand:(BOOL)shouldSave
+- (void)_executeSavedEditingCommands
+{
+ WebHTMLViewInterpretKeyEventsParameters* parameters = _private->interpretKeyEventsParameters;
+ if (!parameters || parameters->event->keypressCommands().isEmpty())
+ return;
+
+ // Avoid an infinite loop that would occur if executing a command appended it to event->keypressCommands() again.
+ bool wasSavingCommands = parameters->shouldSaveCommands;
+ parameters->shouldSaveCommands = false;
+
+ const Vector<KeypressCommand>& commands = parameters->event->keypressCommands();
+
+ for (size_t i = 0; i < commands.size(); ++i) {
+ if (commands[i].commandName == "insertText:")
+ [self insertText:commands[i].text];
+ else
+ [self doCommandBySelector:NSSelectorFromString(commands[i].commandName)];
+ }
+ parameters->event->keypressCommands().clear();
+ parameters->shouldSaveCommands = wasSavingCommands;
+}
+
+- (BOOL)_interpretKeyEvent:(KeyboardEvent*)event savingCommands:(BOOL)savingCommands
{
- // Ask AppKit to process the key event -- it will call back with either insertText or doCommandBySelector.
+ ASSERT(core([self _frame]) == event->target()->toNode()->document()->frame());
+ ASSERT(!savingCommands || event->keypressCommands().isEmpty()); // Save commands once for each event.
+
WebHTMLViewInterpretKeyEventsParameters parameters;
- parameters.eventWasHandled = false;
- parameters.shouldSaveCommand = shouldSave;
+ parameters.eventInterpretationHadSideEffects = false;
+ parameters.shouldSaveCommands = savingCommands;
// If we're intercepting the initial IM call we assume that the IM has consumed the event,
// and only change this assumption if one of the NSTextInput/Responder callbacks is used.
// We assume the IM will *not* consume hotkey sequences
- parameters.consumedByIM = !event->metaKey() && shouldSave;
+ parameters.consumedByIM = savingCommands && !event->metaKey();
- if (const PlatformKeyboardEvent* platformEvent = event->keyEvent()) {
- NSEvent *macEvent = platformEvent->macEvent();
- if ([macEvent type] == NSKeyDown && [_private->completionController filterKeyDown:macEvent])
- return true;
-
- if ([macEvent type] == NSFlagsChanged)
- return false;
-
- parameters.event = event;
- _private->interpretKeyEventsParameters = &parameters;
- _private->receivedNOOP = NO;
- const Vector<KeypressCommand>& commands = event->keypressCommands();
- bool hasKeypressCommand = !commands.isEmpty();
-
- // FIXME: interpretKeyEvents doesn't match application key equivalents (such as Cmd+A),
- // and sends noop: for those. As a result, we don't handle those from within WebCore,
- // but send a full sequence of DOM events, including an unneeded keypress.
- if (parameters.shouldSaveCommand || !hasKeypressCommand)
- [self interpretKeyEvents:[NSArray arrayWithObject:macEvent]];
- else {
- size_t size = commands.size();
- // Are there commands that would just cause text insertion if executed via Editor?
- // WebKit doesn't have enough information about mode to decide how they should be treated, so we leave it upon WebCore
- // to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
- // (e.g. Tab that inserts a Tab character, or Enter).
- bool haveTextInsertionCommands = false;
- for (size_t i = 0; i < size; ++i) {
- if ([self coreCommandBySelector:NSSelectorFromString(commands[i].commandName)].isTextInsertion())
- haveTextInsertionCommands = true;
- }
- if (!haveTextInsertionCommands || platformEvent->type() == PlatformKeyboardEvent::Char) {
- for (size_t i = 0; i < size; ++i) {
- if (commands[i].commandName == "insertText:")
- [self insertText:commands[i].text];
- else
- [self doCommandBySelector:NSSelectorFromString(commands[i].commandName)];
- }
- }
+ const PlatformKeyboardEvent* platformEvent = event->keyEvent();
+ if (!platformEvent)
+ return NO;
+
+ NSEvent *macEvent = platformEvent->macEvent();
+ if ([macEvent type] == NSKeyDown && [_private->completionController filterKeyDown:macEvent])
+ return YES;
+
+ if ([macEvent type] == NSFlagsChanged)
+ return NO;
+
+ parameters.event = event;
+ _private->interpretKeyEventsParameters = &parameters;
+ const Vector<KeypressCommand>& commands = event->keypressCommands();
+
+ if (savingCommands) {
+ // AppKit will respond with a series of NSTextInput protocol method calls. There are three groups that we heuristically differentiate:
+ // 1. Key Bindings. Only doCommandBySelector: and insertText: calls will be made, which we save in the event for execution
+ // after DOM dispatch. This is safe, because neither returns a result, so there is no branching on AppKit side.
+ // 2. Plain text input. Here as well, we need to dispatch DOM events prior to inserting text, so we save the insertText: command.
+ // 3. Input method processing. An IM can make any NSTextInput calls, and can base its decisions on results it gets, so we must
+ // execute the calls immediately. DOM events like keydown are tweaked to have keyCode of 229, and canceling them has no effect.
+ // Unfortunately, there is no real difference between plain text input and IM processing - for example, AppKit queries hasMarkedText
+ // when typing with U.S. keyboard, and inserts marked text for dead keys.
+ [self interpretKeyEvents:[NSArray arrayWithObject:macEvent]];
+ } else {
+ // Are there commands that could just cause text insertion if executed via Editor?
+ // WebKit doesn't have enough information about mode to decide how they should be treated, so we leave it upon WebCore
+ // to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
+ // (e.g. Tab that inserts a Tab character, or Enter).
+ bool haveTextInsertionCommands = false;
+ for (size_t i = 0; i < commands.size(); ++i) {
+ if ([self coreCommandBySelector:NSSelectorFromString(commands[i].commandName)].isTextInsertion())
+ haveTextInsertionCommands = true;
}
- _private->interpretKeyEventsParameters = 0;
+ // If there are no text insertion commands, default keydown handler is the right time to execute the commands.
+ // Keypress (Char event) handler is the latest opportunity to execute.
+ if (!haveTextInsertionCommands || platformEvent->type() == PlatformKeyboardEvent::Char)
+ [self _executeSavedEditingCommands];
}
- return (!_private->receivedNOOP && parameters.eventWasHandled) || parameters.consumedByIM;
+ _private->interpretKeyEventsParameters = 0;
+
+ // An input method may make several actions per keypress. For example, pressing Return with Korean IM both confirms it and sends a newline.
+ // IM-like actions are handled immediately (so parameters.eventInterpretationHadSideEffects is true), but there are saved commands that
+ // should be handled like normal text input after DOM event dispatch.
+ if (!event->keypressCommands().isEmpty())
+ return NO;
+
+ // An input method may consume an event and not tell us (e.g. when displaying a candidate window),
+ // in which case we should not bubble the event up the DOM.
+ if (parameters.consumedByIM)
+ return YES;
+
+ // If we have already executed all commands, don't do it again.
+ return parameters.eventInterpretationHadSideEffects;
}
- (WebCore::CachedImage*)promisedDragTIFFDataSource
@@ -5551,7 +5600,20 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point)
#if !defined(BUILDING_ON_LEOPARD)
// If we aren't in the window yet, we'll use the screen's scale factor now, and reset the scale
// via -viewDidMoveToWindow.
- CGFloat scaleFactor = [self window] ? [[self window] userSpaceScaleFactor] : [[NSScreen mainScreen] userSpaceScaleFactor];
+ NSWindow *window = [self window];
+ CGFloat scaleFactor;
+#if !defined(BUILDING_ON_SNOW_LEOPARD)
+ if (window)
+ scaleFactor = [window backingScaleFactor];
+ else
+ scaleFactor = [[NSScreen mainScreen] backingScaleFactor];
+#else
+ if (window)
+ scaleFactor = [window userSpaceScaleFactor];
+ else
+ scaleFactor = [[NSScreen mainScreen] userSpaceScaleFactor];
+#endif
+
[viewLayer setTransform:CATransform3DMakeScale(scaleFactor, scaleFactor, 1)];
#endif
@@ -5684,6 +5746,8 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point)
- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint
{
+ [self _executeSavedEditingCommands];
+
NSWindow *window = [self window];
WebFrame *frame = [self _frame];
@@ -5703,7 +5767,9 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point)
}
- (NSRect)firstRectForCharacterRange:(NSRange)theRange
-{
+{
+ [self _executeSavedEditingCommands];
+
WebFrame *frame = [self _frame];
// Just to match NSTextView's behavior. Regression tests cannot detect this;
@@ -5734,6 +5800,8 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point)
- (NSRange)selectedRange
{
+ [self _executeSavedEditingCommands];
+
if (!isTextInput(core([self _frame]))) {
LOG(TextInput, "selectedRange -> (NSNotFound, 0)");
return NSMakeRange(NSNotFound, 0);
@@ -5746,6 +5814,8 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point)
- (NSRange)markedRange
{
+ [self _executeSavedEditingCommands];
+
WebFrame *webFrame = [self _frame];
Frame* coreFrame = core(webFrame);
if (!coreFrame)
@@ -5758,6 +5828,8 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point)
- (NSAttributedString *)attributedSubstringFromRange:(NSRange)nsRange
{
+ [self _executeSavedEditingCommands];
+
WebFrame *frame = [self _frame];
Frame* coreFrame = core(frame);
if (!isTextInput(coreFrame) || isInPasswordField(coreFrame)) {
@@ -5799,6 +5871,8 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point)
- (BOOL)hasMarkedText
{
+ [self _executeSavedEditingCommands];
+
Frame* coreFrame = core([self _frame]);
BOOL result = coreFrame && coreFrame->editor()->hasComposition();
LOG(TextInput, "hasMarkedText -> %u", result);
@@ -5807,6 +5881,8 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point)
- (void)unmarkText
{
+ [self _executeSavedEditingCommands];
+
LOG(TextInput, "unmarkText");
// Use pointer to get parameters passed to us by the caller of interpretKeyEvents.
@@ -5814,8 +5890,8 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point)
_private->interpretKeyEventsParameters = 0;
if (parameters) {
- parameters->eventWasHandled = YES;
- parameters->consumedByIM = NO;
+ parameters->eventInterpretationHadSideEffects = true;
+ parameters->consumedByIM = false;
}
if (Frame* coreFrame = core([self _frame]))
@@ -5844,6 +5920,8 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
- (void)setMarkedText:(id)string selectedRange:(NSRange)newSelRange
{
+ [self _executeSavedEditingCommands];
+
BOOL isAttributedString = [string isKindOfClass:[NSAttributedString class]]; // Otherwise, NSString
LOG(TextInput, "setMarkedText:\"%@\" selectedRange:(%u, %u)", isAttributedString ? [string string] : string, newSelRange.location, newSelRange.length);
@@ -5853,8 +5931,8 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
_private->interpretKeyEventsParameters = 0;
if (parameters) {
- parameters->eventWasHandled = YES;
- parameters->consumedByIM = NO;
+ parameters->eventInterpretationHadSideEffects = true;
+ parameters->consumedByIM = false;
}
Frame* coreFrame = core([self _frame]);
@@ -5869,7 +5947,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
if (isAttributedString) {
unsigned markedTextLength = [(NSString *)string length];
- NSString *rangeString = [string attribute:NSTextInputReplacementRangeAttributeName atIndex:0 longestEffectiveRange:NULL inRange:NSMakeRange(0, markedTextLength)];
+ NSString *rangeString = [string attribute:NSTextInputReplacementRangeAttributeName atIndex:0 longestEffectiveRange:0 inRange:NSMakeRange(0, markedTextLength)];
LOG(TextInput, " ReplacementRange: %@", rangeString);
// The AppKit adds a 'secret' property to the string that contains the replacement range.
// The replacement range is the range of the the text that should be replaced with the new string.
@@ -5891,17 +5969,16 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
// The same call to interpretKeyEvents can do more than one command.
WebHTMLViewInterpretKeyEventsParameters* parameters = _private->interpretKeyEventsParameters;
if (parameters)
- parameters->consumedByIM = NO;
-
- if (selector == @selector(noop:)) {
- _private->receivedNOOP = YES;
- return;
- }
+ parameters->consumedByIM = false;
KeyboardEvent* event = parameters ? parameters->event : 0;
- bool shouldSaveCommand = parameters && parameters->shouldSaveCommand;
+ bool shouldSaveCommand = parameters && parameters->shouldSaveCommands;
+
+ // As in insertText:, we assume that the call comes from an input method if there is marked text.
+ RefPtr<Frame> coreFrame = core([self _frame]);
+ bool isFromInputMethod = coreFrame && coreFrame->editor()->hasComposition();
- if (event && shouldSaveCommand)
+ if (event && shouldSaveCommand && !isFromInputMethod)
event->keypressCommands().append(KeypressCommand(NSStringFromSelector(selector)));
else {
// Make sure that only direct calls to doCommandBySelector: see the parameters by setting to 0.
@@ -5933,10 +6010,8 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
}
if (parameters)
- parameters->eventWasHandled = eventWasHandled;
+ parameters->eventInterpretationHadSideEffects |= eventWasHandled;
- // Restore the parameters so that other calls to doCommandBySelector: see them,
- // and other commands can participate in setting the "eventWasHandled" flag.
_private->interpretKeyEventsParameters = parameters;
}
}
@@ -5948,9 +6023,8 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
LOG(TextInput, "insertText:\"%@\"", isAttributedString ? [string string] : string);
WebHTMLViewInterpretKeyEventsParameters* parameters = _private->interpretKeyEventsParameters;
- _private->interpretKeyEventsParameters = 0;
if (parameters)
- parameters->consumedByIM = NO;
+ parameters->consumedByIM = false;
// We don't support inserting an attributed string but input methods don't appear to require this.
RefPtr<Frame> coreFrame = core([self _frame]);
@@ -5960,57 +6034,48 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
text = [string string];
// We deal with the NSTextInputReplacementRangeAttributeName attribute from NSAttributedString here
// simply because it is used by at least one Input Method -- it corresonds to the kEventParamTextInputSendReplaceRange
- // event in TSM. This behaviour matches that of -[WebHTMLView setMarkedText:selectedRange:] when it receives an
+ // event in TSM. This behavior matches that of -[WebHTMLView setMarkedText:selectedRange:] when it receives an
// NSAttributedString
- NSString *rangeString = [string attribute:NSTextInputReplacementRangeAttributeName atIndex:0 longestEffectiveRange:NULL inRange:NSMakeRange(0, [text length])];
+ NSString *rangeString = [string attribute:NSTextInputReplacementRangeAttributeName atIndex:0 longestEffectiveRange:0 inRange:NSMakeRange(0, [text length])];
LOG(TextInput, " ReplacementRange: %@", rangeString);
if (rangeString) {
[[self _frame] _selectNSRange:NSRangeFromString(rangeString)];
- isFromInputMethod = YES;
+ isFromInputMethod = true;
}
} else
text = string;
- bool eventHandled = false;
- if ([text length]) {
- KeyboardEvent* event = parameters ? parameters->event : 0;
-
- // insertText can be called from an input method or from normal key event processing
- // If its from normal key event processing, we may need to save the action to perform it later.
- // If its from an input method, then we should go ahead and insert the text now.
- // We assume it's from the input method if we have marked text.
- // FIXME: In theory, this could be wrong for some input methods, so we should try to find
- // another way to determine if the call is from the input method
- bool shouldSaveCommand = parameters && parameters->shouldSaveCommand;
- if (event && shouldSaveCommand && !isFromInputMethod) {
- event->keypressCommands().append(KeypressCommand("insertText:", text));
- _private->interpretKeyEventsParameters = parameters;
- return;
- }
-
- String eventText = text;
- eventText.replace(NSBackTabCharacter, NSTabCharacter); // same thing is done in KeyEventMac.mm in WebCore
- if (coreFrame && coreFrame->editor()->canEdit()) {
- if (!coreFrame->editor()->hasComposition())
- eventHandled = coreFrame->editor()->insertText(eventText, event);
- else {
- eventHandled = true;
- coreFrame->editor()->confirmComposition(eventText);
- }
- }
- }
-
- if (!parameters)
+ KeyboardEvent* event = parameters ? parameters->event : 0;
+
+ // insertText can be called for several reasons:
+ // - If it's from normal key event processing (including key bindings), we may need to save the action to perform it later.
+ // - If it's from an input method, then we should go ahead and insert the text now. We assume it's from the input method if we have marked text.
+ // FIXME: In theory, this could be wrong for some input methods, so we should try to find another way to determine if the call is from the input method.
+ // - If it's sent outside of keyboard event processing (e.g. from Character Viewer, or when confirming an inline input area with a mouse),
+ // then we also execute it immediately, as there will be no other chance.
+ bool shouldSaveCommand = parameters && parameters->shouldSaveCommands;
+ if (event && shouldSaveCommand && !isFromInputMethod) {
+ event->keypressCommands().append(KeypressCommand("insertText:", text));
return;
-
- if (isFromInputMethod) {
- // Allow doCommandBySelector: to be called after insertText: by resetting interpretKeyEventsParameters
- _private->interpretKeyEventsParameters = parameters;
- parameters->consumedByIM = YES;
+ }
+
+ if (!coreFrame || !coreFrame->editor()->canEdit())
return;
+
+ bool eventHandled = false;
+ String eventText = text;
+ eventText.replace(NSBackTabCharacter, NSTabCharacter); // same thing is done in KeyEventMac.mm in WebCore
+ if (!coreFrame->editor()->hasComposition()) {
+ // An insertText: might be handled by other responders in the chain if we don't handle it.
+ // One example is space bar that results in scrolling down the page.
+ eventHandled = coreFrame->editor()->insertText(eventText, event);
+ } else {
+ eventHandled = true;
+ coreFrame->editor()->confirmComposition(eventText);
}
- parameters->eventWasHandled = eventHandled;
+ if (parameters)
+ parameters->eventInterpretationHadSideEffects |= eventHandled;
}
- (void)_updateSelectionForInputManager