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

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: xiaocheng's review: Isolate |UndoStep| code; Move attribuates to private 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
Xiaocheng 2016/12/21 02:56:39 Please revise the comments here.
chongz 2016/12/21 23:59:24 Reverted comments since there is no behavior chang
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(); 107 // TODO(chongz): Remove the following code after we have ensured it's OK to
110 if (!target) 108 // fire 'beforeinput' after 'compositionupdate'.
111 return; 109 // https://crbug.com/675820
112 110 if (compositionType == TypingCommand::TextCompositionUpdate ||
113 // TODO(chongz): Fire 'beforeinput' for the composed text being 111 compositionType == TypingCommand::TextCompositionConfirm) {
114 // replaced/deleted. 112 Element* target = frame.document()->focusedElement();
115 113 if (!target)
116 // Only the last confirmed text is cancelable. 114 return;
117 InputEvent::EventCancelable beforeInputCancelable = 115 // Only the last confirmed text is cancelable.
118 (compositionType == 116 const InputEvent::EventCancelable beforeInputCancelable =
119 TypingCommand::TextCompositionType::TextCompositionUpdate) 117 (compositionType == TypingCommand::TextCompositionUpdate)
120 ? InputEvent::EventCancelable::NotCancelable 118 ? InputEvent::EventCancelable::NotCancelable
121 : InputEvent::EventCancelable::IsCancelable; 119 : InputEvent::EventCancelable::IsCancelable;
122 DispatchEventResult result = dispatchBeforeInputFromComposition( 120 RangeVector* targetRanges = nullptr;
chongz 2016/12/20 23:27:52 Kept, still fire 'beforeinput' before 'composition
123 target, InputEvent::InputType::InsertText, text, beforeInputCancelable); 121 if (frame.editor().canEditRichly())
124 122 targetRanges = new RangeVector(1, frame.selection().firstRange());
125 if (beforeInputCancelable == InputEvent::EventCancelable::IsCancelable && 123 const bool isCanceled = !dispatchBeforeInputEvent(
126 result != DispatchEventResult::NotCanceled) 124 EditCommandSource::kMenuOrKeyBinding, &frame, target,
127 return; 125 InputEvent::InputType::InsertText, text, nullptr, beforeInputCancelable,
128 126 InputEvent::IsComposing, targetRanges);
129 // 'beforeinput' event handler may destroy document. 127 if (isCanceled)
130 if (!frame.document()) 128 return;
131 return; 129 }
132 130
133 dispatchCompositionUpdateEvent(frame, text); 131 dispatchCompositionUpdateEvent(frame, text);
134 // 'compositionupdate' event handler may destroy document. 132 // 'compositionupdate' event handler may destroy document.
135 if (!frame.document()) 133 if (!frame.document() || frame.document()->frame() != &frame)
Xiaocheng 2016/12/21 02:56:38 This seems irrelevant to beforeinput. If it's a b
chongz 2016/12/21 23:59:24 Reverted, will put in another patch.
136 return; 134 return;
137 135
138 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets 136 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
139 // needs to be audited. see http://crbug.com/590369 for more details. 137 // needs to be audited. see http://crbug.com/590369 for more details.
140 frame.document()->updateStyleAndLayoutIgnorePendingStylesheets(); 138 frame.document()->updateStyleAndLayoutIgnorePendingStylesheets();
141 139
142 const bool isIncrementalInsertion = needsIncrementalInsertion(frame, text); 140 const bool isIncrementalInsertion = needsIncrementalInsertion(frame, text);
143 141
144 switch (compositionType) { 142 switch (compositionType) {
145 case TypingCommand::TextCompositionType::TextCompositionUpdate: 143 case TypingCommand::TextCompositionType::TextCompositionUpdate:
146 case TypingCommand::TextCompositionType::TextCompositionConfirm: 144 case TypingCommand::TextCompositionType::TextCompositionConfirm:
147 TypingCommand::insertText( 145 TypingCommand::insertText(
148 *frame.document(), EditCommandSource::kMenuOrKeyBinding, text, 146 *frame.document(), EditCommandSource::kMenuOrKeyBinding, text,
149 options, compositionType, isIncrementalInsertion); 147 options, compositionType, isIncrementalInsertion);
150 break; 148 break;
151 case TypingCommand::TextCompositionType::TextCompositionCancel: 149 case TypingCommand::TextCompositionType::TextCompositionCancel:
152 // TODO(chongz): Use TypingCommand::insertText after TextEvent was 150 // TODO(chongz): Use TypingCommand::insertText after TextEvent was
153 // removed. (Removed from spec since 2012) 151 // removed. (Removed from spec since 2012)
154 // See TextEvent.idl. 152 // See TextEvent.idl.
155 frame.eventHandler().handleTextInputEvent(text, 0, 153 frame.eventHandler().handleTextInputEvent(text, 0,
156 TextEventInputComposition); 154 TextEventInputComposition);
157 break; 155 break;
158 default: 156 default:
159 NOTREACHED(); 157 NOTREACHED();
160 } 158 }
161 // TODO(chongz): Fire 'input' event.
Xiaocheng 2016/12/21 02:56:39 Is it a drive-by removal of a stale TODO? If so,
chongz 2016/12/21 23:59:24 Yes, will isolate into another patch.
162 } 159 }
163 160
164 AtomicString getInputModeAttribute(Element* element) { 161 AtomicString getInputModeAttribute(Element* element) {
165 if (!element) 162 if (!element)
166 return AtomicString(); 163 return AtomicString();
167 164
168 bool queryAttribute = false; 165 bool queryAttribute = false;
169 if (isHTMLInputElement(*element)) { 166 if (isHTMLInputElement(*element)) {
170 queryAttribute = toHTMLInputElement(*element).supportsInputModeAttribute(); 167 queryAttribute = toHTMLInputElement(*element).supportsInputModeAttribute();
171 } else if (isHTMLTextAreaElement(*element)) { 168 } else if (isHTMLTextAreaElement(*element)) {
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 if (!moveCaret(absoluteCaretPosition)) 342 if (!moveCaret(absoluteCaretPosition))
346 return false; 343 return false;
347 344
348 // No DOM update after 'compositionend'. 345 // No DOM update after 'compositionend'.
349 dispatchCompositionEndEvent(frame(), text); 346 dispatchCompositionEndEvent(frame(), text);
350 347
351 return true; 348 return true;
352 } 349 }
353 350
354 bool InputMethodController::insertText(const String& text) { 351 bool InputMethodController::insertText(const String& text) {
355 if (dispatchBeforeInputInsertText(document().focusedElement(), text) !=
chongz 2016/12/20 23:27:52 Removed, inserting text was covered by |TypingComm
356 DispatchEventResult::NotCanceled)
357 return false;
358 editor().insertText(text, 0); 352 editor().insertText(text, 0);
359 return true; 353 return true;
360 } 354 }
361 355
362 bool InputMethodController::insertTextAndMoveCaret(const String& text, 356 bool InputMethodController::insertTextAndMoveCaret(const String& text,
363 int relativeCaretPosition) { 357 int relativeCaretPosition) {
364 PlainTextRange selectionRange = getSelectionOffsets(); 358 PlainTextRange selectionRange = getSelectionOffsets();
365 if (selectionRange.isNull()) 359 if (selectionRange.isNull())
366 return false; 360 return false;
367 int textStart = selectionRange.start(); 361 int textStart = selectionRange.start();
(...skipping 12 matching lines...) Expand all
380 if (!hasComposition()) 374 if (!hasComposition())
381 return; 375 return;
382 376
383 Editor::RevealSelectionScope revealSelectionScope(&editor()); 377 Editor::RevealSelectionScope revealSelectionScope(&editor());
384 378
385 if (frame().selection().isNone()) 379 if (frame().selection().isNone())
386 return; 380 return;
387 381
388 clear(); 382 clear();
389 383
390 // TODO(chongz): Figure out which InputType should we use here.
391 dispatchBeforeInputFromComposition(
chongz 2016/12/20 23:27:52 Removed. This is a dummy 'beforeinput' with no act
392 document().focusedElement(),
393 InputEvent::InputType::DeleteComposedCharacterBackward, nullAtom,
394 InputEvent::EventCancelable::NotCancelable);
395 dispatchCompositionUpdateEvent(frame(), emptyString()); 384 dispatchCompositionUpdateEvent(frame(), emptyString());
396 insertTextDuringCompositionWithEvents( 385 insertTextDuringCompositionWithEvents(
397 frame(), emptyString(), 0, 386 frame(), emptyString(), 0,
398 TypingCommand::TextCompositionType::TextCompositionCancel); 387 TypingCommand::TextCompositionType::TextCompositionCancel);
399 // Event handler might destroy document. 388 // Event handler might destroy document.
400 if (!isAvailable()) 389 if (!isAvailable())
401 return; 390 return;
402 391
403 // An open typing command that disagrees about current selection would cause 392 // An open typing command that disagrees about current selection would cause
404 // issues with typing later on. 393 // issues with typing later on.
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 do { 758 do {
770 if (!setSelectionOffsets(PlainTextRange( 759 if (!setSelectionOffsets(PlainTextRange(
771 std::max(static_cast<int>(selectionOffsets.start()) - before, 0), 760 std::max(static_cast<int>(selectionOffsets.start()) - before, 0),
772 selectionOffsets.end() + after))) 761 selectionOffsets.end() + after)))
773 return; 762 return;
774 if (before == 0) 763 if (before == 0)
775 break; 764 break;
776 ++before; 765 ++before;
777 } while (frame().selection().start() == frame().selection().end() && 766 } while (frame().selection().start() == frame().selection().end() &&
778 before <= static_cast<int>(selectionOffsets.start())); 767 before <= static_cast<int>(selectionOffsets.start()));
779 // TODO(chongz): Find a way to distinguish Forward and Backward.
780 dispatchBeforeInputEditorCommand(
chongz 2016/12/20 23:27:52 Removed, deleting text was covered by |TypingComma
781 document().focusedElement(), InputEvent::InputType::DeleteContentBackward,
782 new RangeVector(1, m_frame->selection().firstRange()));
783 TypingCommand::deleteSelection(document(), 768 TypingCommand::deleteSelection(document(),
784 EditCommandSource::kMenuOrKeyBinding); 769 EditCommandSource::kMenuOrKeyBinding);
785 } 770 }
786 771
787 // TODO(yabinh): We should reduce the number of selectionchange events. 772 // TODO(yabinh): We should reduce the number of selectionchange events.
788 void InputMethodController::deleteSurroundingText(int before, int after) { 773 void InputMethodController::deleteSurroundingText(int before, int after) {
789 if (!editor().canEdit()) 774 if (!editor().canEdit())
790 return; 775 return;
791 const PlainTextRange selectionOffsets(getSelectionOffsets()); 776 const PlainTextRange selectionOffsets(getSelectionOffsets());
792 if (selectionOffsets.isNull()) 777 if (selectionOffsets.isNull())
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
1063 frame().chromeClient().resetInputMethod(); 1048 frame().chromeClient().resetInputMethod();
1064 } 1049 }
1065 1050
1066 DEFINE_TRACE(InputMethodController) { 1051 DEFINE_TRACE(InputMethodController) {
1067 visitor->trace(m_frame); 1052 visitor->trace(m_frame);
1068 visitor->trace(m_compositionRange); 1053 visitor->trace(m_compositionRange);
1069 SynchronousMutationObserver::trace(visitor); 1054 SynchronousMutationObserver::trace(visitor);
1070 } 1055 }
1071 1056
1072 } // namespace blink 1057 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698