OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. |
3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 return false; | 74 return false; |
75 | 75 |
76 // No need to apply incremental insertion if the old text (text to be | 76 // No need to apply incremental insertion if the old text (text to be |
77 // replaced) or the new text (text to be inserted) is empty. | 77 // replaced) or the new text (text to be inserted) is empty. |
78 if (frame.selectedText().isEmpty() || newText.isEmpty()) | 78 if (frame.selectedText().isEmpty() || newText.isEmpty()) |
79 return false; | 79 return false; |
80 | 80 |
81 return true; | 81 return true; |
82 } | 82 } |
83 | 83 |
84 DispatchEventResult dispatchBeforeInputFromComposition( | 84 void dispatchBeforeInputFromComposition(EventTarget* target, |
85 EventTarget* target, | 85 InputEvent::InputType inputType, |
86 InputEvent::InputType inputType, | 86 const String& data) { |
87 const String& data, | |
88 InputEvent::EventCancelable cancelable) { | |
89 if (!RuntimeEnabledFeatures::inputEventEnabled()) | 87 if (!RuntimeEnabledFeatures::inputEventEnabled()) |
90 return DispatchEventResult::NotCanceled; | 88 return; |
91 if (!target) | 89 if (!target) |
92 return DispatchEventResult::NotCanceled; | 90 return; |
93 // TODO(chongz): Pass appropriate |ranges| after it's defined on spec. | 91 // TODO(chongz): Pass appropriate |ranges| after it's defined on spec. |
94 // http://w3c.github.io/editing/input-events.html#dom-inputevent-inputtype | 92 // http://w3c.github.io/editing/input-events.html#dom-inputevent-inputtype |
95 InputEvent* beforeInputEvent = InputEvent::createBeforeInput( | 93 InputEvent* beforeInputEvent = InputEvent::createBeforeInput( |
96 inputType, data, cancelable, InputEvent::EventIsComposing::IsComposing, | 94 inputType, data, InputEvent::NotCancelable, |
97 nullptr); | 95 InputEvent::EventIsComposing::IsComposing, nullptr); |
98 return target->dispatchEvent(beforeInputEvent); | 96 target->dispatchEvent(beforeInputEvent); |
99 } | 97 } |
100 | 98 |
101 // Used to insert/replace text during composition update and confirm | 99 // Used to insert/replace text during composition update and confirm |
102 // composition. | 100 // composition. |
103 // Procedure: | 101 // Procedure: |
104 // 1. Fire 'beforeinput' event for (TODO(chongz): deleted composed text) and | 102 // 1. Fire 'beforeinput' event for (TODO(chongz): deleted composed text) and |
105 // inserted text | 103 // inserted text |
106 // 2. Fire 'compositionupdate' event | 104 // 2. Fire 'compositionupdate' event |
107 // 3. Fire TextEvent and modify DOM | 105 // 3. Fire TextEvent and modify DOM |
108 // TODO(chongz): 4. Fire 'input' event | 106 // TODO(chongz): 4. Fire 'input' event |
(...skipping 11 matching lines...) Expand all Loading... |
120 << "compositionType should be TextCompositionUpdate or " | 118 << "compositionType should be TextCompositionUpdate or " |
121 "TextCompositionConfirm or TextCompositionCancel, but got " | 119 "TextCompositionConfirm or TextCompositionCancel, but got " |
122 << static_cast<int>(compositionType); | 120 << static_cast<int>(compositionType); |
123 if (!frame.document()) | 121 if (!frame.document()) |
124 return; | 122 return; |
125 | 123 |
126 Element* target = frame.document()->focusedElement(); | 124 Element* target = frame.document()->focusedElement(); |
127 if (!target) | 125 if (!target) |
128 return; | 126 return; |
129 | 127 |
130 // TODO(chongz): Fire 'beforeinput' for the composed text being | 128 dispatchBeforeInputFromComposition( |
131 // replaced/deleted. | 129 target, InputEvent::InputType::InsertCompositionText, text); |
132 | |
133 // Only the last confirmed text is cancelable. | |
134 InputEvent::EventCancelable beforeInputCancelable = | |
135 (compositionType == | |
136 TypingCommand::TextCompositionType::TextCompositionUpdate) | |
137 ? InputEvent::EventCancelable::NotCancelable | |
138 : InputEvent::EventCancelable::IsCancelable; | |
139 DispatchEventResult result = dispatchBeforeInputFromComposition( | |
140 target, InputEvent::InputType::InsertText, text, beforeInputCancelable); | |
141 | |
142 if (beforeInputCancelable == InputEvent::EventCancelable::IsCancelable && | |
143 result != DispatchEventResult::NotCanceled) | |
144 return; | |
145 | 130 |
146 // 'beforeinput' event handler may destroy document. | 131 // 'beforeinput' event handler may destroy document. |
147 if (!frame.document()) | 132 if (!frame.document()) |
148 return; | 133 return; |
149 | 134 |
150 dispatchCompositionUpdateEvent(frame, text); | 135 dispatchCompositionUpdateEvent(frame, text); |
151 // 'compositionupdate' event handler may destroy document. | 136 // 'compositionupdate' event handler may destroy document. |
152 if (!frame.document()) | 137 if (!frame.document()) |
153 return; | 138 return; |
154 | 139 |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 | 292 |
308 // Select the text that will be deleted or replaced. | 293 // Select the text that will be deleted or replaced. |
309 selectComposition(); | 294 selectComposition(); |
310 | 295 |
311 if (frame().selection().isNone()) | 296 if (frame().selection().isNone()) |
312 return false; | 297 return false; |
313 | 298 |
314 if (!isAvailable()) | 299 if (!isAvailable()) |
315 return false; | 300 return false; |
316 | 301 |
317 // If text is empty, then delete the old composition here. If text is | |
318 // non-empty, InsertTextCommand::input will delete the old composition with | |
319 // an optimized replace operation. | |
320 if (text.isEmpty()) | |
321 TypingCommand::deleteSelection(document(), 0); | |
322 | |
323 clear(); | 302 clear(); |
324 | 303 |
325 insertTextDuringCompositionWithEvents( | 304 insertTextDuringCompositionWithEvents( |
326 frame(), text, 0, | 305 frame(), text, 0, |
327 TypingCommand::TextCompositionType::TextCompositionConfirm); | 306 TypingCommand::TextCompositionType::TextCompositionConfirm); |
328 // Event handler might destroy document. | 307 // Event handler might destroy document. |
329 if (!isAvailable()) | 308 if (!isAvailable()) |
330 return false; | 309 return false; |
331 | 310 |
332 // No DOM update after 'compositionend'. | 311 // No DOM update after 'compositionend'. |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 if (!hasComposition()) | 405 if (!hasComposition()) |
427 return; | 406 return; |
428 | 407 |
429 Editor::RevealSelectionScope revealSelectionScope(&editor()); | 408 Editor::RevealSelectionScope revealSelectionScope(&editor()); |
430 | 409 |
431 if (frame().selection().isNone()) | 410 if (frame().selection().isNone()) |
432 return; | 411 return; |
433 | 412 |
434 clear(); | 413 clear(); |
435 | 414 |
436 // TODO(chongz): Figure out which InputType should we use here. | |
437 dispatchBeforeInputFromComposition( | |
438 document().focusedElement(), | |
439 InputEvent::InputType::DeleteComposedCharacterBackward, nullAtom, | |
440 InputEvent::EventCancelable::NotCancelable); | |
441 dispatchCompositionUpdateEvent(frame(), emptyString); | |
442 insertTextDuringCompositionWithEvents( | 415 insertTextDuringCompositionWithEvents( |
443 frame(), emptyString, 0, | 416 frame(), emptyString, 0, |
444 TypingCommand::TextCompositionType::TextCompositionCancel); | 417 TypingCommand::TextCompositionType::TextCompositionCancel); |
445 // Event handler might destroy document. | 418 // Event handler might destroy document. |
446 if (!isAvailable()) | 419 if (!isAvailable()) |
447 return; | 420 return; |
448 | 421 |
449 // An open typing command that disagrees about current selection would cause | 422 // An open typing command that disagrees about current selection would cause |
450 // issues with typing later on. | 423 // issues with typing later on. |
451 TypingCommand::closeTyping(m_frame); | 424 TypingCommand::closeTyping(m_frame); |
(...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 frame().chromeClient().resetInputMethod(); | 1064 frame().chromeClient().resetInputMethod(); |
1092 } | 1065 } |
1093 | 1066 |
1094 DEFINE_TRACE(InputMethodController) { | 1067 DEFINE_TRACE(InputMethodController) { |
1095 visitor->trace(m_frame); | 1068 visitor->trace(m_frame); |
1096 visitor->trace(m_compositionRange); | 1069 visitor->trace(m_compositionRange); |
1097 SynchronousMutationObserver::trace(visitor); | 1070 SynchronousMutationObserver::trace(visitor); |
1098 } | 1071 } |
1099 | 1072 |
1100 } // namespace blink | 1073 } // namespace blink |
OLD | NEW |