Changeset 208090 in webkit
- Timestamp:
- Oct 28, 2016, 6:06:13 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r208087 r208090 1 2016-10-28 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 iOS autocorrection does not trigger an input event of inputType "insertReplacementText" 4 https://bugs.webkit.org/show_bug.cgi?id=164077 5 <rdar://problem/28987810> 6 7 Reviewed by Simon Fraser. 8 9 Adds 2 new unit tests verifying that candidate text insertion can be prevented via beforeinput events, and that 10 beforeinput and input events of type "insertReplacementText" are fired when inserting candidate text on iOS. 11 12 * fast/events/ios/before-input-events-prevent-candidate-insertion-expected.txt: Added. 13 * fast/events/ios/before-input-events-prevent-candidate-insertion.html: Added. 14 * fast/events/ios/input-events-insert-replacement-text-expected.txt: Added. 15 * fast/events/ios/input-events-insert-replacement-text.html: Added. 16 1 17 2016-10-28 Alex Christensen <achristensen@webkit.org> 2 18 -
trunk/Source/WebCore/ChangeLog
r208089 r208090 1 2016-10-28 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 iOS autocorrection does not trigger an input event of inputType "insertReplacementText" 4 https://bugs.webkit.org/show_bug.cgi?id=164077 5 <rdar://problem/28987810> 6 7 Reviewed by Simon Fraser. 8 9 Fixes candidate insertion on iOS, so that it fires input events of type "insertReplacementText" and adds two 10 iOS unit tests covering this change as well as the test infrastructure needed to support these tests. See 11 comments below for more details. 12 13 Tests: fast/events/ios/before-input-events-prevent-candidate-insertion.html 14 fast/events/ios/input-events-insert-replacement-text.html 15 16 * dom/TextEvent.h: 17 18 Adds isAutocompletion() to TextEvent, as well as the TextEventInputAutocompletion text input type. When the 19 Editor handles this TextEvent, it will use this information when creating or modifying the corresponding typing 20 command. 21 22 * dom/TextEventInputType.h: 23 * editing/Editor.cpp: 24 (WebCore::Editor::insertText): 25 (WebCore::Editor::insertTextWithoutSendingTextEvent): 26 * editing/Editor.h: 27 * editing/TypingCommand.cpp: 28 (WebCore::editActionForTypingCommand): 29 30 Now takes whether the command is autocorrection into account. If so, the corresponding edit action should be 31 EditActionInsertReplacement rather than EditActionTypingInsertText. 32 33 (WebCore::TypingCommand::TypingCommand): 34 (WebCore::TypingCommand::deleteSelection): 35 (WebCore::TypingCommand::deleteKeyPressed): 36 (WebCore::TypingCommand::forwardDeleteKeyPressed): 37 (WebCore::TypingCommand::insertText): 38 (WebCore::TypingCommand::insertLineBreak): 39 (WebCore::TypingCommand::insertParagraphSeparatorInQuotedContent): 40 (WebCore::TypingCommand::insertParagraphSeparator): 41 (WebCore::TypingCommand::inputEventData): 42 (WebCore::TypingCommand::willAddTypingToOpenCommand): 43 * editing/TypingCommand.h: 44 45 Adds a new TypingCommand option, IsAutocompletion. 46 1 47 2016-10-28 Commit Queue <commit-queue@webkit.org> 2 48 -
trunk/Source/WebCore/dom/TextEvent.h
r204717 r208090 60 60 bool isDrop() const { return m_inputType == TextEventInputDrop; } 61 61 bool isDictation() const { return m_inputType == TextEventInputDictation; } 62 bool isAutocompletion() const { return m_inputType == TextEventInputAutocompletion; } 62 63 63 64 bool shouldSmartReplace() const { return m_shouldSmartReplace; } -
trunk/Source/WebCore/dom/TextEventInputType.h
r114220 r208090 31 31 enum TextEventInputType { 32 32 TextEventInputKeyboard, // any newline characters in the text are line breaks only, not paragraph separators. 33 TextEventInputAutocompletion, 33 34 TextEventInputLineBreak, // any tab characters in the text are backtabs. 34 35 TextEventInputComposition, -
trunk/Source/WebCore/editing/Editor.cpp
r208014 r208090 1214 1214 } 1215 1215 1216 bool Editor::insertText(const String& text, Event* triggeringEvent )1217 { 1218 return m_frame.eventHandler().handleTextInputEvent(text, triggeringEvent );1216 bool Editor::insertText(const String& text, Event* triggeringEvent, TextEventInputType inputType) 1217 { 1218 return m_frame.eventHandler().handleTextInputEvent(text, triggeringEvent, inputType); 1219 1219 } 1220 1220 … … 1270 1270 if (autocorrectionWasApplied) 1271 1271 options |= TypingCommand::RetainAutocorrectionIndicator; 1272 if (triggeringEvent && triggeringEvent->isAutocompletion()) 1273 options |= TypingCommand::IsAutocompletion; 1272 1274 TypingCommand::insertText(document, text, selection, options, triggeringEvent && triggeringEvent->isComposition() ? TypingCommand::TextCompositionFinal : TypingCommand::TextCompositionNone); 1273 1275 } -
trunk/Source/WebCore/editing/Editor.h
r207797 r208090 37 37 #include "FrameSelection.h" 38 38 #include "TextChecking.h" 39 #include "TextEventInputType.h" 39 40 #include "TextIteratorBehavior.h" 40 41 #include "VisibleSelection.h" … … 240 241 WEBCORE_EXPORT static bool commandIsSupportedFromMenuOrKeyBinding(const String& commandName); // Works without a frame. 241 242 242 WEBCORE_EXPORT bool insertText(const String&, Event* triggeringEvent );243 WEBCORE_EXPORT bool insertText(const String&, Event* triggeringEvent, TextEventInputType = TextEventInputKeyboard); 243 244 bool insertTextForConfirmedComposition(const String& text); 244 245 WEBCORE_EXPORT bool insertDictatedText(const String&, const Vector<DictationAlternative>& dictationAlternatives, Event* triggeringEvent); -
trunk/Source/WebCore/editing/TypingCommand.cpp
r207698 r208090 78 78 }; 79 79 80 static inline EditAction editActionForTypingCommand(TypingCommand::ETypingCommand command, TextGranularity granularity, TypingCommand::TextCompositionType compositionType )80 static inline EditAction editActionForTypingCommand(TypingCommand::ETypingCommand command, TextGranularity granularity, TypingCommand::TextCompositionType compositionType, bool isAutocompletion) 81 81 { 82 82 if (compositionType == TypingCommand::TextCompositionPending) { … … 113 113 return EditActionTypingDeleteForward; 114 114 case TypingCommand::InsertText: 115 return EditActionTypingInsertText;115 return isAutocompletion ? EditActionInsertReplacement : EditActionTypingInsertText; 116 116 case TypingCommand::InsertLineBreak: 117 117 return EditActionTypingInsertLineBreak; … … 141 141 142 142 TypingCommand::TypingCommand(Document& document, ETypingCommand commandType, const String &textToInsert, Options options, TextGranularity granularity, TextCompositionType compositionType) 143 : TextInsertionBaseCommand(document, editActionForTypingCommand(commandType, granularity, compositionType ))143 : TextInsertionBaseCommand(document, editActionForTypingCommand(commandType, granularity, compositionType, options & IsAutocompletion)) 144 144 , m_commandType(commandType) 145 145 , m_textToInsert(textToInsert) … … 151 151 , m_compositionType(compositionType) 152 152 , m_shouldAddToKillRing(options & AddsToKillRing) 153 , m_isAutocompletion(options & IsAutocompletion) 153 154 , m_openedByBackwardDelete(false) 154 155 , m_shouldRetainAutocorrectionIndicator(options & RetainAutocorrectionIndicator) … … 168 169 169 170 if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(*frame)) { 171 lastTypingCommand->setIsAutocompletion(options & IsAutocompletion); 170 172 lastTypingCommand->setCompositionType(compositionType); 171 173 lastTypingCommand->setShouldPreventSpellChecking(options & PreventSpellChecking); … … 182 184 if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(*document.frame())) { 183 185 updateSelectionIfDifferentFromCurrentSelection(lastTypingCommand.get(), document.frame()); 186 lastTypingCommand->setIsAutocompletion(options & IsAutocompletion); 184 187 lastTypingCommand->setCompositionType(TextCompositionNone); 185 188 lastTypingCommand->setShouldPreventSpellChecking(options & PreventSpellChecking); … … 199 202 if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(*frame)) { 200 203 updateSelectionIfDifferentFromCurrentSelection(lastTypingCommand.get(), frame); 204 lastTypingCommand->setIsAutocompletion(options & IsAutocompletion); 201 205 lastTypingCommand->setCompositionType(TextCompositionNone); 202 206 lastTypingCommand->setShouldPreventSpellChecking(options & PreventSpellChecking); … … 252 256 } 253 257 258 lastTypingCommand->setIsAutocompletion(options & IsAutocompletion); 254 259 lastTypingCommand->setCompositionType(compositionType); 255 260 lastTypingCommand->setShouldRetainAutocorrectionIndicator(options & RetainAutocorrectionIndicator); … … 266 271 { 267 272 if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(*document.frame())) { 273 lastTypingCommand->setIsAutocompletion(options & IsAutocompletion); 268 274 lastTypingCommand->setCompositionType(TextCompositionNone); 269 275 lastTypingCommand->setShouldRetainAutocorrectionIndicator(options & RetainAutocorrectionIndicator); … … 278 284 { 279 285 if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(*document.frame())) { 286 lastTypingCommand->setIsAutocompletion(false); 280 287 lastTypingCommand->setCompositionType(TextCompositionNone); 281 288 lastTypingCommand->insertParagraphSeparatorInQuotedContentAndNotifyAccessibility(); … … 289 296 { 290 297 if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(*document.frame())) { 298 lastTypingCommand->setIsAutocompletion(options & IsAutocompletion); 291 299 lastTypingCommand->setCompositionType(TextCompositionNone); 292 300 lastTypingCommand->setShouldRetainAutocorrectionIndicator(options & RetainAutocorrectionIndicator); … … 399 407 switch (m_currentTypingEditAction) { 400 408 case EditActionTypingInsertText: 409 case EditActionInsertReplacement: 401 410 case EditActionTypingInsertPendingComposition: 402 411 case EditActionTypingInsertFinalComposition: … … 470 479 { 471 480 m_currentTextToInsert = text; 472 m_currentTypingEditAction = editActionForTypingCommand(commandType, granularity, m_compositionType );481 m_currentTypingEditAction = editActionForTypingCommand(commandType, granularity, m_compositionType, m_isAutocompletion); 473 482 474 483 if (!shouldDeferWillApplyCommandUntilAddingTypingCommand()) -
trunk/Source/WebCore/editing/TypingCommand.h
r207698 r208090 54 54 RetainAutocorrectionIndicator = 1 << 2, 55 55 PreventSpellChecking = 1 << 3, 56 SmartDelete = 1 << 4 56 SmartDelete = 1 << 4, 57 IsAutocompletion = 1 << 5, 57 58 }; 58 59 typedef unsigned Options; … … 80 81 void deleteSelection(bool smartDelete); 81 82 void setCompositionType(TextCompositionType type) { m_compositionType = type; } 83 void setIsAutocompletion(bool isAutocompletion) { m_isAutocompletion = isAutocompletion; } 82 84 83 85 #if PLATFORM(IOS) … … 152 154 bool m_shouldAddToKillRing; 153 155 bool m_preservesTypingStyle; 156 bool m_isAutocompletion; 154 157 155 158 // Undoing a series of backward deletes will restore a selection around all of the -
trunk/Source/WebKit2/ChangeLog
r208081 r208090 1 2016-10-28 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 iOS autocorrection does not trigger an input event of inputType "insertReplacementText" 4 https://bugs.webkit.org/show_bug.cgi?id=164077 5 <rdar://problem/28987810> 6 7 Reviewed by Simon Fraser. 8 9 Small tweak to mark text insertion when autocorrecting as such, as opposed to regular keyboard input. 10 11 * WebProcess/WebPage/ios/WebPageIOS.mm: 12 (WebKit::WebPage::syncApplyAutocorrection): 13 1 14 2016-10-28 Megan Gardner <megan_gardner@apple.com> 2 15 -
trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm
r208020 r208090 2172 2172 frame.selection().setSelectedRange(range.get(), UPSTREAM, true); 2173 2173 if (correction.length()) 2174 frame.editor().insertText(correction, 0 );2174 frame.editor().insertText(correction, 0, originalText.isEmpty() ? TextEventInputKeyboard : TextEventInputAutocompletion); 2175 2175 else 2176 2176 frame.editor().deleteWithDirection(DirectionBackward, CharacterGranularity, false, true); -
trunk/Tools/ChangeLog
r208089 r208090 1 2016-10-28 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 iOS autocorrection does not trigger an input event of inputType "insertReplacementText" 4 https://bugs.webkit.org/show_bug.cgi?id=164077 5 <rdar://problem/28987810> 6 7 Reviewed by Simon Fraser. 8 9 Adds test support for inserting text candidates on iOS in the form of 10 UIScriptController.selectTextCandidateAtIndex(index, callback), which selects the text candidate at a given 11 index (this needs to be a value between 0-2 on iOS) and fires the callback when done. 12 13 To implement this, we wait for the text prediction view to have predictions (we determine this by polling at a 14 given interval) and then tap the center of the text prediction view at the given index. 15 16 * DumpRenderTree/ios/UIScriptControllerIOS.mm: 17 (WTR::UIScriptController::selectTextCandidateAtIndex): 18 * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: 19 * TestRunnerShared/UIScriptContext/UIScriptController.cpp: 20 (WTR::UIScriptController::selectTextCandidateAtIndex): 21 (WTR::UIScriptController::waitForTextPredictionsViewAndSelectCandidateAtIndex): 22 * TestRunnerShared/UIScriptContext/UIScriptController.h: 23 * WebKitTestRunner/ios/UIKitSPI.h: 24 * WebKitTestRunner/ios/UIScriptControllerIOS.mm: 25 (WTR::UIScriptController::selectTextCandidateAtIndex): 26 (WTR::UIScriptController::waitForTextPredictionsViewAndSelectCandidateAtIndex): 27 1 28 2016-10-28 Commit Queue <commit-queue@webkit.org> 2 29 -
trunk/Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm
r207447 r208090 117 117 } 118 118 119 void UIScriptController::selectTextCandidateAtIndex(long, JSValueRef) 120 { 121 } 122 119 123 void UIScriptController::keyDownUsingHardwareKeyboard(JSStringRef character, JSValueRef callback) 120 124 { -
trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl
r207447 r208090 49 49 void keyDownUsingHardwareKeyboard(DOMString character, object callback); 50 50 void keyUpUsingHardwareKeyboard(DOMString character, object callback); 51 52 void selectTextCandidateAtIndex(long index, object callback); 51 53 52 54 // eventsJSON describes a series of user events in JSON form. For the keys, see HIDEventGenerator.mm. -
trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp
r207447 r208090 215 215 } 216 216 217 void UIScriptController::selectTextCandidateAtIndex(long, JSValueRef) 218 { 219 } 220 221 void UIScriptController::waitForTextPredictionsViewAndSelectCandidateAtIndex(long, unsigned, float) 222 { 223 } 224 217 225 void UIScriptController::keyDownUsingHardwareKeyboard(JSStringRef, JSValueRef) 218 226 { -
trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h
r207447 r208090 71 71 void keyUpUsingHardwareKeyboard(JSStringRef character, JSValueRef callback); 72 72 73 void selectTextCandidateAtIndex(long index, JSValueRef callback); 74 73 75 void keyboardAccessoryBarNext(); 74 76 void keyboardAccessoryBarPrevious(); … … 137 139 138 140 JSObjectRef objectFromRect(const WebCore::FloatRect&) const; 141 void waitForTextPredictionsViewAndSelectCandidateAtIndex(long index, unsigned callbackID, float interval); 139 142 140 143 UIScriptContext* m_context; -
trunk/Tools/WebKitTestRunner/ios/UIKitSPI.h
r190841 r208090 38 38 #import <UIKit/UIWindow_Private.h> 39 39 40 @interface UIKeyboardPredictionView : UIView 41 + (UIKeyboardPredictionView *)activeInstance; 42 - (BOOL)hasPredictions; 43 @end 44 40 45 #else 41 46 -
trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm
r207447 r208090 256 256 } 257 257 258 void UIScriptController::selectTextCandidateAtIndex(long index, JSValueRef callback) 259 { 260 #if USE(APPLE_INTERNAL_SDK) 261 static const float textPredictionsPollingInterval = 0.1; 262 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 263 waitForTextPredictionsViewAndSelectCandidateAtIndex(index, callbackID, textPredictionsPollingInterval); 264 #else 265 // FIXME: This is a no-op on non-internal builds due to UIKeyboardPredictionView being unavailable. Ideally, there should be a better way to 266 // retrieve information and interact with the predictive text view that will be compatible with OpenSource. 267 UNUSED_PARAM(index); 268 UNUSED_PARAM(callback); 269 #endif 270 } 271 272 void UIScriptController::waitForTextPredictionsViewAndSelectCandidateAtIndex(long index, unsigned callbackID, float interval) 273 { 274 #if USE(APPLE_INTERNAL_SDK) 275 if (![UIKeyboardPredictionView activeInstance].hasPredictions) { 276 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, interval * NSEC_PER_SEC), dispatch_get_main_queue(), ^() { 277 waitForTextPredictionsViewAndSelectCandidateAtIndex(index, callbackID, interval); 278 }); 279 return; 280 } 281 282 PlatformWKView webView = TestController::singleton().mainWebView()->platformView(); 283 CGRect predictionViewFrame = [UIKeyboardPredictionView activeInstance].frame; 284 // This assumes there are 3 predicted text cells of equal width, which is the case on iOS. 285 float offsetX = (index * 2 + 1) * CGRectGetWidth(predictionViewFrame) / 6; 286 float offsetY = CGRectGetHeight(webView.window.frame) - CGRectGetHeight([UIKeyboardPredictionView activeInstance].superview.frame) + CGRectGetHeight(predictionViewFrame) / 2; 287 [[HIDEventGenerator sharedHIDEventGenerator] tap:CGPointMake(offsetX, offsetY) completionBlock:^{ 288 if (m_context) 289 m_context->asyncTaskComplete(callbackID); 290 }]; 291 #else 292 UNUSED_PARAM(index); 293 UNUSED_PARAM(callbackID); 294 UNUSED_PARAM(interval); 295 #endif 296 } 297 258 298 void UIScriptController::dismissFormAccessoryView() 259 299 {
Note:
See TracChangeset
for help on using the changeset viewer.