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 167 matching lines...) Loading... | |
178 | 178 |
179 // The composition can start inside a composed character sequence, so we hav e to override checks. | 179 // The composition can start inside a composed character sequence, so we hav e to override checks. |
180 // See <http://bugs.webkit.org/show_bug.cgi?id=15781> | 180 // See <http://bugs.webkit.org/show_bug.cgi?id=15781> |
181 VisibleSelection selection; | 181 VisibleSelection selection; |
182 selection.setWithoutValidation(range.startPosition(), range.endPosition()); | 182 selection.setWithoutValidation(range.startPosition(), range.endPosition()); |
183 frame().selection().setSelection(selection, 0); | 183 frame().selection().setSelection(selection, 0); |
184 } | 184 } |
185 | 185 |
186 bool InputMethodController::confirmComposition() | 186 bool InputMethodController::confirmComposition() |
187 { | 187 { |
188 return confirmComposition(composingText()); | 188 return replaceComposition(composingText(), KeepSelection); |
189 } | 189 } |
190 | 190 |
191 bool InputMethodController::confirmComposition(const String& text, ConfirmCompos itionBehavior confirmBehavior) | 191 bool InputMethodController::replaceComposition(const String& text, ConfirmCompos itionBehavior confirmBehavior) |
192 { | 192 { |
193 if (!hasComposition()) | 193 if (!hasComposition()) |
194 return false; | 194 return false; |
195 | 195 |
196 Optional<Editor::RevealSelectionScope> revealSelectionScope; | 196 Optional<Editor::RevealSelectionScope> revealSelectionScope; |
197 if (confirmBehavior == KeepSelection) | 197 if (confirmBehavior == KeepSelection) |
198 revealSelectionScope.emplace(&editor()); | 198 revealSelectionScope.emplace(&editor()); |
199 | 199 |
200 // If the composition was set from existing text and didn't change, then | 200 // If the composition was set from existing text and didn't change, then |
201 // there's nothing to do here (and we should avoid doing anything as that | 201 // there's nothing to do here (and we should avoid doing anything as that |
(...skipping 24 matching lines...) Loading... | |
226 // Event handler might destroy document. | 226 // Event handler might destroy document. |
227 if (!frame().document()) | 227 if (!frame().document()) |
228 return false; | 228 return false; |
229 | 229 |
230 // No DOM update after 'compositionend'. | 230 // No DOM update after 'compositionend'. |
231 dispatchCompositionEndEvent(frame(), text); | 231 dispatchCompositionEndEvent(frame(), text); |
232 | 232 |
233 return true; | 233 return true; |
234 } | 234 } |
235 | 235 |
236 bool InputMethodController::confirmCompositionOrInsertText(const String& text, C onfirmCompositionBehavior confirmBehavior) | 236 bool InputMethodController::replaceCompositionAndMoveCaret(const String& text, i nt relativeCaretPosition) |
237 { | 237 { |
238 if (!hasComposition()) { | 238 Element* rootEditableElement = frame().selection().rootEditableElement(); |
239 if (!text.length()) | 239 if (!rootEditableElement) |
240 return false; | 240 return false; |
241 PlainTextRange compositionRange = PlainTextRange::create(*rootEditableElemen t, *m_compositionRange); | |
242 if (compositionRange.isNull()) | |
243 return false; | |
241 | 244 |
242 if (dispatchBeforeInputInsertText(frame().document()->focusedElement(), text) != DispatchEventResult::NotCanceled) | 245 int absoluteCaretPosition = getAbsoluteCaretPosition(compositionRange.start( ), text.length(), relativeCaretPosition); |
243 return false; | 246 return replaceComposition(text, DoNotKeepSelection) && moveCaret(absoluteCar etPosition); |
247 } | |
244 | 248 |
245 editor().insertText(text, 0); | 249 bool InputMethodController::commitComposition(const String& text) |
250 { | |
251 if (!hasComposition()) | |
252 return insertText(text); | |
253 | |
254 if (text.length()) { | |
255 replaceComposition(text, KeepSelection); | |
246 return true; | 256 return true; |
247 } | 257 } |
248 | 258 |
249 if (text.length()) { | |
250 confirmComposition(text); | |
251 return true; | |
252 } | |
253 | |
254 if (confirmBehavior == DoNotKeepSelection) | |
255 return confirmComposition(composingText(), DoNotKeepSelection); | |
256 | |
257 SelectionOffsetsScope selectionOffsetsScope(this); | 259 SelectionOffsetsScope selectionOffsetsScope(this); |
258 return confirmComposition(); | 260 return confirmComposition(); |
259 } | 261 } |
260 | 262 |
263 bool InputMethodController::commitCompositionAndMoveCaret(const String& text, in t relativeCaretPosition) | |
264 { | |
265 if (!hasComposition()) | |
266 return insertTextAndMoveCaret(text, relativeCaretPosition); | |
267 | |
yosin_UTC9
2016/08/29 07:02:01
nit: no need to have an extra blank line.
yabinh
2016/08/29 08:44:00
Done.
| |
268 if (text.length()) | |
269 return replaceCompositionAndMoveCaret(text, relativeCaretPosition); | |
270 | |
yosin_UTC9
2016/08/29 07:02:02
nit: no need to have an extra blank line.
yabinh
2016/08/29 08:44:01
Done.
| |
271 return replaceCompositionAndMoveCaret(composingText(), relativeCaretPosition ); | |
272 } | |
273 | |
274 bool InputMethodController::insertText(const String& text) | |
275 { | |
276 if (!text.length()) | |
277 return false; | |
278 | |
yosin_UTC9
2016/08/29 07:02:02
nit: no need to have an extra blank line.
yabinh
2016/08/29 08:44:01
Done.
| |
279 if (dispatchBeforeInputInsertText(frame().document()->focusedElement(), text ) != DispatchEventResult::NotCanceled) | |
280 return false; | |
281 | |
yosin_UTC9
2016/08/29 07:02:02
nit: no need to have an extra blank line.
yabinh
2016/08/29 08:44:01
Done.
| |
282 editor().insertText(text, 0); | |
283 return true; | |
284 } | |
285 | |
286 bool InputMethodController::insertTextAndMoveCaret(const String& text, int relat iveCaretPosition) | |
287 { | |
288 PlainTextRange selectionRange = getSelectionOffsets(); | |
289 if (selectionRange.isNull()) | |
290 return false; | |
291 | |
yosin_UTC9
2016/08/29 07:02:02
nit: no need to have an extra blank line.
yabinh
2016/08/29 08:44:01
Done.
| |
292 int absoluteCaretPosition = getAbsoluteCaretPosition(selectionRange.start(), text.length(), relativeCaretPosition); | |
yosin_UTC9
2016/08/29 07:02:01
s/getAbsoluteCaretPosition/computeAbsoluteCaretPos
yabinh
2016/08/29 08:44:01
Done.
| |
293 return insertText(text) && moveCaret(absoluteCaretPosition); | |
yosin_UTC9
2016/08/29 07:02:02
We should not compute |absoluteCaretPosition| when
yabinh
2016/08/29 08:44:01
Done.
BTW, we should restore the selection and com
| |
294 } | |
295 | |
261 void InputMethodController::cancelComposition() | 296 void InputMethodController::cancelComposition() |
262 { | 297 { |
263 if (!hasComposition()) | 298 if (!hasComposition()) |
264 return; | 299 return; |
265 | 300 |
266 Editor::RevealSelectionScope revealSelectionScope(&editor()); | 301 Editor::RevealSelectionScope revealSelectionScope(&editor()); |
267 | 302 |
268 if (frame().selection().isNone()) | 303 if (frame().selection().isNone()) |
269 return; | 304 return; |
270 | 305 |
(...skipping 65 matching lines...) Loading... | |
336 // Sending a compositionupdate event at this time ensures that at least o ne | 371 // Sending a compositionupdate event at this time ensures that at least o ne |
337 // compositionupdate event is dispatched. | 372 // compositionupdate event is dispatched. |
338 // 2. Updating the existing composition node. | 373 // 2. Updating the existing composition node. |
339 // Send a compositionupdate event when this function updates the existing composition | 374 // Send a compositionupdate event when this function updates the existing composition |
340 // node, i.e. hasComposition() && !text.isEmpty(). | 375 // node, i.e. hasComposition() && !text.isEmpty(). |
341 // 3. Canceling the ongoing composition. | 376 // 3. Canceling the ongoing composition. |
342 // Send a compositionend event when function deletes the existing composi tion node, i.e. | 377 // Send a compositionend event when function deletes the existing composi tion node, i.e. |
343 // !hasComposition() && test.isEmpty(). | 378 // !hasComposition() && test.isEmpty(). |
344 if (text.isEmpty()) { | 379 if (text.isEmpty()) { |
345 if (hasComposition()) { | 380 if (hasComposition()) { |
346 confirmComposition(emptyString()); | 381 replaceComposition(emptyString(), KeepSelection); |
347 } else { | 382 } else { |
348 // It's weird to call |setComposition()| with empty text outside com position, however some IME | 383 // It's weird to call |setComposition()| with empty text outside com position, however some IME |
349 // (e.g. Japanese IBus-Anthy) did this, so we simply delete selectio n without sending extra events. | 384 // (e.g. Japanese IBus-Anthy) did this, so we simply delete selectio n without sending extra events. |
350 TypingCommand::deleteSelection(*frame().document(), TypingCommand::P reventSpellChecking); | 385 TypingCommand::deleteSelection(*frame().document(), TypingCommand::P reventSpellChecking); |
351 } | 386 } |
352 | 387 |
353 setEditableSelectionOffsets(selectedRange); | 388 setEditableSelectionOffsets(selectedRange); |
354 return; | 389 return; |
355 } | 390 } |
356 | 391 |
(...skipping 179 matching lines...) Loading... | |
536 | 571 |
537 rightBoundary += textLength; | 572 rightBoundary += textLength; |
538 | 573 |
539 // In case of exceeding the right boundary. | 574 // In case of exceeding the right boundary. |
540 start = std::min(start, rightBoundary); | 575 start = std::min(start, rightBoundary); |
541 end = std::min(end, rightBoundary); | 576 end = std::min(end, rightBoundary); |
542 | 577 |
543 return PlainTextRange(start, end); | 578 return PlainTextRange(start, end); |
544 } | 579 } |
545 | 580 |
581 int InputMethodController::getAbsoluteCaretPosition(size_t textStart, size_t tex tLength, int relativeCaretPosition) const | |
yosin_UTC9
2016/08/29 07:02:02
This function should be a local static function in
yabinh
2016/08/29 08:44:00
Done.
| |
582 { | |
583 // If relativeCaretPosition > 0, it's relative to the end of the text - 1; | |
yosin_UTC9
2016/08/29 07:02:01
Please put this comment in .h file.
yabinh
2016/08/29 08:44:01
Since this function is not declared in .h file in
| |
584 // if relativeCaretPosition <= 0, it is relative to the start of the text. | |
585 // This is to match Android behavior. See | |
586 // https://developer.android.com/reference/android/view/inputmethod/InputCon nection.html#commitText(java.lang.CharSequence, int) | |
587 if (relativeCaretPosition > 0) | |
588 relativeCaretPosition += textLength - 1; | |
589 return textStart + relativeCaretPosition; | |
590 } | |
591 | |
592 bool InputMethodController::moveCaret(int newCaretPosition) | |
593 { | |
594 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); | |
595 | |
596 PlainTextRange selectedRange = createRangeForSelection(newCaretPosition, new CaretPosition, 0); | |
597 if (selectedRange.isNull()) | |
598 return false; | |
599 return setEditableSelectionOffsets(selectedRange); | |
600 } | |
601 | |
546 void InputMethodController::extendSelectionAndDelete(int before, int after) | 602 void InputMethodController::extendSelectionAndDelete(int before, int after) |
547 { | 603 { |
548 if (!editor().canEdit()) | 604 if (!editor().canEdit()) |
549 return; | 605 return; |
550 PlainTextRange selectionOffsets(getSelectionOffsets()); | 606 PlainTextRange selectionOffsets(getSelectionOffsets()); |
551 if (selectionOffsets.isNull()) | 607 if (selectionOffsets.isNull()) |
552 return; | 608 return; |
553 | 609 |
554 // A common call of before=1 and after=0 will fail if the last character | 610 // A common call of before=1 and after=0 will fail if the last character |
555 // is multi-code-word UTF-16, including both multi-16bit code-points and | 611 // is multi-code-word UTF-16, including both multi-16bit code-points and |
(...skipping 19 matching lines...) Loading... | |
575 TypingCommand::deleteSelection(*frame().document()); | 631 TypingCommand::deleteSelection(*frame().document()); |
576 } | 632 } |
577 | 633 |
578 DEFINE_TRACE(InputMethodController) | 634 DEFINE_TRACE(InputMethodController) |
579 { | 635 { |
580 visitor->trace(m_frame); | 636 visitor->trace(m_frame); |
581 visitor->trace(m_compositionRange); | 637 visitor->trace(m_compositionRange); |
582 } | 638 } |
583 | 639 |
584 } // namespace blink | 640 } // namespace blink |
OLD | NEW |