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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
75 bool InputMethodController::hasComposition() const | 75 bool InputMethodController::hasComposition() const |
76 { | 76 { |
77 return m_hasComposition; | 77 return m_hasComposition; |
78 } | 78 } |
79 | 79 |
80 inline Editor& InputMethodController::editor() const | 80 inline Editor& InputMethodController::editor() const |
81 { | 81 { |
82 return frame().editor(); | 82 return frame().editor(); |
83 } | 83 } |
84 | 84 |
85 static void dispatchCompositionEvent(LocalFrame& frame, const AtomicString& type , const String& text) | |
aelias_OOO_until_Jul13
2016/01/16 01:48:50
nit: Could you position this method where the prev
| |
86 { | |
87 // We should send this event before sending a TextEvent as written in | |
88 // Section 6.2.2 and 6.2.3 of the DOM Event specification. | |
89 Element* target = frame.document()->focusedElement(); | |
90 if (!target) | |
91 return; | |
92 | |
93 RefPtrWillBeRawPtr<CompositionEvent> event = | |
94 CompositionEvent::create(EventTypeNames::compositionend, frame.domWindow (), text); | |
aelias_OOO_until_Jul13
2016/01/16 01:48:50
Looks like you intended to use "type" here, instea
| |
95 target->dispatchEvent(event); | |
96 } | |
97 | |
85 void InputMethodController::clear() | 98 void InputMethodController::clear() |
86 { | 99 { |
87 m_hasComposition = false; | 100 m_hasComposition = false; |
88 if (m_compositionRange) { | 101 if (m_compositionRange) { |
89 m_compositionRange->setStart(frame().document(), 0); | 102 m_compositionRange->setStart(frame().document(), 0); |
90 m_compositionRange->collapse(true); | 103 m_compositionRange->collapse(true); |
91 } | 104 } |
92 frame().document()->markers().removeMarkers(DocumentMarker::Composition); | 105 frame().document()->markers().removeMarkers(DocumentMarker::Composition); |
93 m_isDirty = false; | 106 m_isDirty = false; |
94 } | 107 } |
(...skipping 20 matching lines...) Expand all Loading... | |
115 VisibleSelection selection; | 128 VisibleSelection selection; |
116 selection.setWithoutValidation(range.startPosition(), range.endPosition()); | 129 selection.setWithoutValidation(range.startPosition(), range.endPosition()); |
117 frame().selection().setSelection(selection, 0); | 130 frame().selection().setSelection(selection, 0); |
118 } | 131 } |
119 | 132 |
120 bool InputMethodController::confirmComposition() | 133 bool InputMethodController::confirmComposition() |
121 { | 134 { |
122 return confirmComposition(composingText()); | 135 return confirmComposition(composingText()); |
123 } | 136 } |
124 | 137 |
125 static void dispatchCompositionEndEvent(LocalFrame& frame, const String& text) | |
126 { | |
127 // We should send this event before sending a TextEvent as written in | |
128 // Section 6.2.2 and 6.2.3 of the DOM Event specification. | |
129 Element* target = frame.document()->focusedElement(); | |
130 if (!target) | |
131 return; | |
132 | |
133 RefPtrWillBeRawPtr<CompositionEvent> event = | |
134 CompositionEvent::create(EventTypeNames::compositionend, frame.domWindow (), text); | |
135 target->dispatchEvent(event); | |
136 } | |
137 | |
138 bool InputMethodController::confirmComposition(const String& text) | 138 bool InputMethodController::confirmComposition(const String& text) |
139 { | 139 { |
140 #if OS(ANDROID) | |
aelias_OOO_until_Jul13
2016/01/16 01:48:50
Let's avoid introducing any OS(ANDROID) in Blink.
| |
141 // On Android, we want to trigger compositionstart/end even for | |
142 // confirmComposition since it does not accompany actual keycodes. | |
143 if (!hasComposition() && text.isEmpty()) | |
144 return false; | |
145 #else | |
140 if (!hasComposition()) | 146 if (!hasComposition()) |
141 return false; | 147 return false; |
148 #endif | |
142 | 149 |
143 Editor::RevealSelectionScope revealSelectionScope(&editor()); | 150 Editor::RevealSelectionScope revealSelectionScope(&editor()); |
144 | 151 |
145 // If the composition was set from existing text and didn't change, then | 152 // If the composition was set from existing text and didn't change, then |
146 // there's nothing to do here (and we should avoid doing anything as that | 153 // there's nothing to do here (and we should avoid doing anything as that |
147 // may clobber multi-node styled text). | 154 // may clobber multi-node styled text). |
148 if (!m_isDirty && composingText() == text) { | 155 if (!m_isDirty && composingText() == text) { |
149 clear(); | 156 clear(); |
150 return true; | 157 return true; |
151 } | 158 } |
152 | 159 |
153 // Select the text that will be deleted or replaced. | 160 // Select the text that will be deleted or replaced. |
154 selectComposition(); | 161 selectComposition(); |
155 | 162 |
156 if (frame().selection().isNone()) | 163 if (frame().selection().isNone()) |
157 return false; | 164 return false; |
158 | 165 |
159 dispatchCompositionEndEvent(frame(), text); | 166 if (!hasComposition()) |
167 dispatchCompositionEvent(frame(), EventTypeNames::compositionstart, fram e().selectedText()); | |
168 dispatchCompositionEvent(frame(), EventTypeNames::compositionend, text); | |
160 | 169 |
161 if (!frame().document()) | 170 if (!frame().document()) |
162 return false; | 171 return false; |
163 | 172 |
164 // If text is empty, then delete the old composition here. If text is | 173 // If text is empty, then delete the old composition here. If text is |
165 // non-empty, InsertTextCommand::input will delete the old composition with | 174 // non-empty, InsertTextCommand::input will delete the old composition with |
166 // an optimized replace operation. | 175 // an optimized replace operation. |
167 if (text.isEmpty()) | 176 if (text.isEmpty()) |
168 TypingCommand::deleteSelection(*frame().document(), 0); | 177 TypingCommand::deleteSelection(*frame().document(), 0); |
169 | 178 |
170 clear(); | 179 clear(); |
171 | 180 |
172 insertTextForConfirmedComposition(text); | 181 insertTextForConfirmedComposition(text); |
173 | 182 |
174 return true; | 183 return true; |
175 } | 184 } |
176 | 185 |
177 bool InputMethodController::confirmCompositionOrInsertText(const String& text, C onfirmCompositionBehavior confirmBehavior) | 186 bool InputMethodController::confirmCompositionOrInsertText(const String& text, C onfirmCompositionBehavior confirmBehavior) |
178 { | 187 { |
179 if (!hasComposition()) { | 188 if (!hasComposition()) { |
180 if (!text.length()) | 189 if (!text.length()) |
181 return false; | 190 return false; |
191 #if !OS(ANDROID) | |
182 editor().insertText(text, 0); | 192 editor().insertText(text, 0); |
aelias_OOO_until_Jul13
2016/01/16 01:48:50
Hmm, wouldn't it work just as well to add the comp
| |
183 return true; | 193 return true; |
194 #endif | |
184 } | 195 } |
185 | 196 |
186 if (text.length()) { | 197 if (text.length()) { |
187 confirmComposition(text); | 198 confirmComposition(text); |
188 return true; | 199 return true; |
189 } | 200 } |
190 | 201 |
191 if (confirmBehavior != KeepSelection) | 202 if (confirmBehavior != KeepSelection) |
192 return confirmComposition(); | 203 return confirmComposition(); |
193 | 204 |
194 SelectionOffsetsScope selectionOffsetsScope(this); | 205 SelectionOffsetsScope selectionOffsetsScope(this); |
195 return confirmComposition(); | 206 return confirmComposition(); |
196 } | 207 } |
197 | 208 |
198 void InputMethodController::cancelComposition() | 209 void InputMethodController::cancelComposition() |
199 { | 210 { |
200 if (!hasComposition()) | 211 if (!hasComposition()) |
201 return; | 212 return; |
202 | 213 |
203 Editor::RevealSelectionScope revealSelectionScope(&editor()); | 214 Editor::RevealSelectionScope revealSelectionScope(&editor()); |
204 | 215 |
205 if (frame().selection().isNone()) | 216 if (frame().selection().isNone()) |
206 return; | 217 return; |
207 | 218 |
208 dispatchCompositionEndEvent(frame(), emptyString()); | 219 dispatchCompositionEvent(frame(), EventTypeNames::compositionend, emptyStrin g()); |
209 clear(); | 220 clear(); |
210 insertTextForConfirmedComposition(emptyString()); | 221 insertTextForConfirmedComposition(emptyString()); |
211 | 222 |
212 // An open typing command that disagrees about current selection would cause | 223 // An open typing command that disagrees about current selection would cause |
213 // issues with typing later on. | 224 // issues with typing later on. |
214 TypingCommand::closeTyping(m_frame); | 225 TypingCommand::closeTyping(m_frame); |
215 } | 226 } |
216 | 227 |
217 void InputMethodController::cancelCompositionIfSelectionIsInvalid() | 228 void InputMethodController::cancelCompositionIfSelectionIsInvalid() |
218 { | 229 { |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
453 TypingCommand::deleteSelection(*frame().document()); | 464 TypingCommand::deleteSelection(*frame().document()); |
454 } | 465 } |
455 | 466 |
456 DEFINE_TRACE(InputMethodController) | 467 DEFINE_TRACE(InputMethodController) |
457 { | 468 { |
458 visitor->trace(m_frame); | 469 visitor->trace(m_frame); |
459 visitor->trace(m_compositionRange); | 470 visitor->trace(m_compositionRange); |
460 } | 471 } |
461 | 472 |
462 } // namespace blink | 473 } // namespace blink |
OLD | NEW |