Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(202)

Side by Side Diff: third_party/WebKit/Source/core/editing/InputMethodController.cpp

Issue 2558643003: [InputEvent] Move 'beforeinput' logic into |CompositeEditCommand::willApplyEditing()| (3/3) (Closed)
Patch Set: Rebase on EditCommandSource and willApply() CLs Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 // Used to insert/replace text during composition update and confirm 84 // Used to insert/replace text during composition update and confirm
85 // composition. 85 // composition.
86 // Procedure: 86 // Procedure:
87 // 1. Fire 'beforeinput' event for (TODO(chongz): deleted composed text) and 87 // 1. Fire 'compositionupdate' event
88 // inserted text 88 // 2. Use TextEvent or TypingCommand to modify DOM, which will fire
89 // 2. Fire 'compositionupdate' event 89 // 'beforeinput' and 'input'
90 // 3. Fire TextEvent and modify DOM
91 // TODO(chongz): 4. Fire 'input' event
92 void insertTextDuringCompositionWithEvents( 90 void insertTextDuringCompositionWithEvents(
93 LocalFrame& frame, 91 LocalFrame& frame,
94 const String& text, 92 const String& text,
95 TypingCommand::Options options, 93 TypingCommand::Options options,
96 TypingCommand::TextCompositionType compositionType) { 94 TypingCommand::TextCompositionType compositionType) {
97 DCHECK(compositionType == 95 DCHECK(compositionType ==
98 TypingCommand::TextCompositionType::TextCompositionUpdate || 96 TypingCommand::TextCompositionType::TextCompositionUpdate ||
99 compositionType == 97 compositionType ==
100 TypingCommand::TextCompositionType::TextCompositionConfirm || 98 TypingCommand::TextCompositionType::TextCompositionConfirm ||
101 compositionType == 99 compositionType ==
102 TypingCommand::TextCompositionType::TextCompositionCancel) 100 TypingCommand::TextCompositionType::TextCompositionCancel)
103 << "compositionType should be TextCompositionUpdate or " 101 << "compositionType should be TextCompositionUpdate or "
104 "TextCompositionConfirm or TextCompositionCancel, but got " 102 "TextCompositionConfirm or TextCompositionCancel, but got "
105 << static_cast<int>(compositionType); 103 << static_cast<int>(compositionType);
106 if (!frame.document()) 104 if (!frame.document())
107 return; 105 return;
108 106
109 Element* target = frame.document()->focusedElement();
110 if (!target)
111 return;
112
113 // TODO(chongz): Fire 'beforeinput' for the composed text being
114 // replaced/deleted.
115
116 // Only the last confirmed text is cancelable.
117 InputEvent::EventCancelable beforeInputCancelable =
118 (compositionType ==
119 TypingCommand::TextCompositionType::TextCompositionUpdate)
120 ? InputEvent::EventCancelable::NotCancelable
121 : InputEvent::EventCancelable::IsCancelable;
122 DispatchEventResult result = dispatchBeforeInputFromComposition(
123 target, InputEvent::InputType::InsertText, text, beforeInputCancelable);
124
125 if (beforeInputCancelable == InputEvent::EventCancelable::IsCancelable &&
126 result != DispatchEventResult::NotCanceled)
127 return;
128
129 // 'beforeinput' event handler may destroy document.
130 if (!frame.document())
131 return;
132
133 dispatchCompositionUpdateEvent(frame, text); 107 dispatchCompositionUpdateEvent(frame, text);
134 // 'compositionupdate' event handler may destroy document. 108 // 'compositionupdate' event handler may destroy document.
135 if (!frame.document()) 109 if (!frame.document() || frame.document()->frame() != &frame)
136 return; 110 return;
137 111
138 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets 112 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
139 // needs to be audited. see http://crbug.com/590369 for more details. 113 // needs to be audited. see http://crbug.com/590369 for more details.
140 frame.document()->updateStyleAndLayoutIgnorePendingStylesheets(); 114 frame.document()->updateStyleAndLayoutIgnorePendingStylesheets();
141 115
142 const bool isIncrementalInsertion = needsIncrementalInsertion(frame, text); 116 const bool isIncrementalInsertion = needsIncrementalInsertion(frame, text);
143 117
144 switch (compositionType) { 118 switch (compositionType) {
145 case TypingCommand::TextCompositionType::TextCompositionUpdate: 119 case TypingCommand::TextCompositionType::TextCompositionUpdate:
146 case TypingCommand::TextCompositionType::TextCompositionConfirm: 120 case TypingCommand::TextCompositionType::TextCompositionConfirm:
147 TypingCommand::insertText( 121 TypingCommand::insertText(
148 *frame.document(), EditCommandSource::kMenuOrKeyBinding, text, 122 *frame.document(), EditCommandSource::kMenuOrKeyBinding, text,
149 options, compositionType, isIncrementalInsertion); 123 options, compositionType, isIncrementalInsertion);
150 break; 124 break;
151 case TypingCommand::TextCompositionType::TextCompositionCancel: 125 case TypingCommand::TextCompositionType::TextCompositionCancel:
152 // TODO(chongz): Use TypingCommand::insertText after TextEvent was 126 // TODO(chongz): Use TypingCommand::insertText after TextEvent was
153 // removed. (Removed from spec since 2012) 127 // removed. (Removed from spec since 2012)
154 // See TextEvent.idl. 128 // See TextEvent.idl.
155 frame.eventHandler().handleTextInputEvent(text, 0, 129 frame.eventHandler().handleTextInputEvent(text, 0,
156 TextEventInputComposition); 130 TextEventInputComposition);
157 break; 131 break;
158 default: 132 default:
159 NOTREACHED(); 133 NOTREACHED();
160 } 134 }
161 // TODO(chongz): Fire 'input' event.
162 } 135 }
163 136
164 AtomicString getInputModeAttribute(Element* element) { 137 AtomicString getInputModeAttribute(Element* element) {
165 if (!element) 138 if (!element)
166 return AtomicString(); 139 return AtomicString();
167 140
168 bool queryAttribute = false; 141 bool queryAttribute = false;
169 if (isHTMLInputElement(*element)) { 142 if (isHTMLInputElement(*element)) {
170 queryAttribute = toHTMLInputElement(*element).supportsInputModeAttribute(); 143 queryAttribute = toHTMLInputElement(*element).supportsInputModeAttribute();
171 } else if (isHTMLTextAreaElement(*element)) { 144 } else if (isHTMLTextAreaElement(*element)) {
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 if (!moveCaret(absoluteCaretPosition)) 318 if (!moveCaret(absoluteCaretPosition))
346 return false; 319 return false;
347 320
348 // No DOM update after 'compositionend'. 321 // No DOM update after 'compositionend'.
349 dispatchCompositionEndEvent(frame(), text); 322 dispatchCompositionEndEvent(frame(), text);
350 323
351 return true; 324 return true;
352 } 325 }
353 326
354 bool InputMethodController::insertText(const String& text) { 327 bool InputMethodController::insertText(const String& text) {
355 if (dispatchBeforeInputInsertText(document().focusedElement(), text) !=
356 DispatchEventResult::NotCanceled)
357 return false;
358 editor().insertText(text, 0); 328 editor().insertText(text, 0);
359 return true; 329 return true;
360 } 330 }
361 331
362 bool InputMethodController::insertTextAndMoveCaret(const String& text, 332 bool InputMethodController::insertTextAndMoveCaret(const String& text,
363 int relativeCaretPosition) { 333 int relativeCaretPosition) {
364 PlainTextRange selectionRange = getSelectionOffsets(); 334 PlainTextRange selectionRange = getSelectionOffsets();
365 if (selectionRange.isNull()) 335 if (selectionRange.isNull())
366 return false; 336 return false;
367 int textStart = selectionRange.start(); 337 int textStart = selectionRange.start();
(...skipping 12 matching lines...) Expand all
380 if (!hasComposition()) 350 if (!hasComposition())
381 return; 351 return;
382 352
383 Editor::RevealSelectionScope revealSelectionScope(&editor()); 353 Editor::RevealSelectionScope revealSelectionScope(&editor());
384 354
385 if (frame().selection().isNone()) 355 if (frame().selection().isNone())
386 return; 356 return;
387 357
388 clear(); 358 clear();
389 359
390 // TODO(chongz): Figure out which InputType should we use here.
391 dispatchBeforeInputFromComposition(
392 document().focusedElement(),
393 InputEvent::InputType::DeleteComposedCharacterBackward, nullAtom,
394 InputEvent::EventCancelable::NotCancelable);
395 dispatchCompositionUpdateEvent(frame(), emptyString()); 360 dispatchCompositionUpdateEvent(frame(), emptyString());
396 insertTextDuringCompositionWithEvents( 361 insertTextDuringCompositionWithEvents(
397 frame(), emptyString(), 0, 362 frame(), emptyString(), 0,
398 TypingCommand::TextCompositionType::TextCompositionCancel); 363 TypingCommand::TextCompositionType::TextCompositionCancel);
399 // Event handler might destroy document. 364 // Event handler might destroy document.
400 if (!isAvailable()) 365 if (!isAvailable())
401 return; 366 return;
402 367
403 // An open typing command that disagrees about current selection would cause 368 // An open typing command that disagrees about current selection would cause
404 // issues with typing later on. 369 // issues with typing later on.
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 do { 734 do {
770 if (!setSelectionOffsets(PlainTextRange( 735 if (!setSelectionOffsets(PlainTextRange(
771 std::max(static_cast<int>(selectionOffsets.start()) - before, 0), 736 std::max(static_cast<int>(selectionOffsets.start()) - before, 0),
772 selectionOffsets.end() + after))) 737 selectionOffsets.end() + after)))
773 return; 738 return;
774 if (before == 0) 739 if (before == 0)
775 break; 740 break;
776 ++before; 741 ++before;
777 } while (frame().selection().start() == frame().selection().end() && 742 } while (frame().selection().start() == frame().selection().end() &&
778 before <= static_cast<int>(selectionOffsets.start())); 743 before <= static_cast<int>(selectionOffsets.start()));
779 // TODO(chongz): Find a way to distinguish Forward and Backward.
780 dispatchBeforeInputEditorCommand(
781 document().focusedElement(), InputEvent::InputType::DeleteContentBackward,
782 new RangeVector(1, m_frame->selection().firstRange()));
783 TypingCommand::deleteSelection(document(), 744 TypingCommand::deleteSelection(document(),
784 EditCommandSource::kMenuOrKeyBinding); 745 EditCommandSource::kMenuOrKeyBinding);
785 } 746 }
786 747
787 // TODO(yabinh): We should reduce the number of selectionchange events. 748 // TODO(yabinh): We should reduce the number of selectionchange events.
788 void InputMethodController::deleteSurroundingText(int before, int after) { 749 void InputMethodController::deleteSurroundingText(int before, int after) {
789 if (!editor().canEdit()) 750 if (!editor().canEdit())
790 return; 751 return;
791 const PlainTextRange selectionOffsets(getSelectionOffsets()); 752 const PlainTextRange selectionOffsets(getSelectionOffsets());
792 if (selectionOffsets.isNull()) 753 if (selectionOffsets.isNull())
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
1063 frame().chromeClient().resetInputMethod(); 1024 frame().chromeClient().resetInputMethod();
1064 } 1025 }
1065 1026
1066 DEFINE_TRACE(InputMethodController) { 1027 DEFINE_TRACE(InputMethodController) {
1067 visitor->trace(m_frame); 1028 visitor->trace(m_frame);
1068 visitor->trace(m_compositionRange); 1029 visitor->trace(m_compositionRange);
1069 SynchronousMutationObserver::trace(visitor); 1030 SynchronousMutationObserver::trace(visitor);
1070 } 1031 }
1071 1032
1072 } // namespace blink 1033 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698