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

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

Issue 2558643003: [InputEvent] Move 'beforeinput' logic into |CompositeEditCommand::willApplyEditing()| (3/3) (Closed)
Patch Set: xiaocheng's review 3: Rebase and remove updateStyleAndLayoutIgnorePendingStylesheets() 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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 namespace { 99 namespace {
100 100
101 void dispatchInputEvent(Element* target, 101 void dispatchInputEvent(Element* target,
102 InputEvent::InputType inputType, 102 InputEvent::InputType inputType,
103 const String& data, 103 const String& data,
104 InputEvent::EventIsComposing isComposing) { 104 InputEvent::EventIsComposing isComposing) {
105 if (!RuntimeEnabledFeatures::inputEventEnabled()) 105 if (!RuntimeEnabledFeatures::inputEventEnabled())
106 return; 106 return;
107 if (!target) 107 if (!target)
108 return; 108 return;
109 // TODO(chongz): Pass appreciate |ranges| after it's defined on spec.
110 // http://w3c.github.io/editing/input-events.html#dom-inputevent-inputtype
111 InputEvent* inputEvent = 109 InputEvent* inputEvent =
112 InputEvent::createInput(inputType, data, isComposing, nullptr); 110 InputEvent::createInput(inputType, data, isComposing, nullptr);
113 target->dispatchScopedEvent(inputEvent); 111 target->dispatchScopedEvent(inputEvent);
114 } 112 }
115 113
116 void dispatchInputEventEditableContentChanged( 114 void dispatchInputEventEditableContentChanged(
117 Element* startRoot, 115 Element* startRoot,
118 Element* endRoot, 116 Element* endRoot,
119 InputEvent::InputType inputType, 117 InputEvent::InputType inputType,
120 const String& data, 118 const String& data,
121 InputEvent::EventIsComposing isComposing) { 119 InputEvent::EventIsComposing isComposing) {
122 if (startRoot) 120 if (startRoot)
123 dispatchInputEvent(startRoot, inputType, data, isComposing); 121 dispatchInputEvent(startRoot, inputType, data, isComposing);
124 if (endRoot && endRoot != startRoot) 122 if (endRoot && endRoot != startRoot)
125 dispatchInputEvent(endRoot, inputType, data, isComposing); 123 dispatchInputEvent(endRoot, inputType, data, isComposing);
126 } 124 }
127 125
128 InputEvent::EventIsComposing isComposingFromCommand(
129 const CompositeEditCommand* command) {
130 if (command->isTypingCommand() &&
131 toTypingCommand(command)->compositionType() !=
132 TypingCommand::TextCompositionNone)
133 return InputEvent::EventIsComposing::IsComposing;
134 return InputEvent::EventIsComposing::NotComposing;
135 }
136
137 } // anonymous namespace 126 } // anonymous namespace
138 127
139 Editor::RevealSelectionScope::RevealSelectionScope(Editor* editor) 128 Editor::RevealSelectionScope::RevealSelectionScope(Editor* editor)
140 : m_editor(editor) { 129 : m_editor(editor) {
141 ++m_editor->m_preventRevealSelection; 130 ++m_editor->m_preventRevealSelection;
142 } 131 }
143 132
144 Editor::RevealSelectionScope::~RevealSelectionScope() { 133 Editor::RevealSelectionScope::~RevealSelectionScope() {
145 DCHECK(m_editor->m_preventRevealSelection); 134 DCHECK(m_editor->m_preventRevealSelection);
146 --m_editor->m_preventRevealSelection; 135 --m_editor->m_preventRevealSelection;
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 if (insertMode == InsertMode::Smart) 605 if (insertMode == InsertMode::Smart)
617 options |= ReplaceSelectionCommand::SmartReplace; 606 options |= ReplaceSelectionCommand::SmartReplace;
618 if (dragSourceType == DragSourceType::PlainTextSource) 607 if (dragSourceType == DragSourceType::PlainTextSource)
619 options |= ReplaceSelectionCommand::MatchStyle; 608 options |= ReplaceSelectionCommand::MatchStyle;
620 DCHECK(frame().document()); 609 DCHECK(frame().document());
621 ReplaceSelectionCommand::create(*frame().document(), fragment, options, 610 ReplaceSelectionCommand::create(*frame().document(), fragment, options,
622 InputEvent::InputType::InsertFromDrop) 611 InputEvent::InputType::InsertFromDrop)
623 ->apply(EditCommandSource::kMenuOrKeyBinding); 612 ->apply(EditCommandSource::kMenuOrKeyBinding);
624 } 613 }
625 614
626 bool Editor::deleteSelectionAfterDraggingWithEvents(
627 Element* dragSource,
628 DeleteMode deleteMode,
629 const Position& referenceMovePosition) {
630 if (!dragSource || !dragSource->isConnected())
631 return true;
632
633 // Dispatch 'beforeinput'.
634 const bool shouldDelete = dispatchBeforeInputEditorCommand(
635 dragSource, InputEvent::InputType::DeleteByDrag,
636 nullptr) == DispatchEventResult::NotCanceled;
637
638 // 'beforeinput' event handler may destroy frame, return false to cancel
639 // remaining actions;
640 if (m_frame->document()->frame() != m_frame)
641 return false;
642
643 if (shouldDelete && dragSource->isConnected()) {
644 deleteSelectionWithSmartDelete(
645 EditCommandSource::kMenuOrKeyBinding, deleteMode,
646 InputEvent::InputType::DeleteByDrag, referenceMovePosition);
647 }
648
649 return true;
650 }
651
652 bool Editor::replaceSelectionAfterDraggingWithEvents(
653 Element* dropTarget,
654 DragData* dragData,
655 DocumentFragment* fragment,
656 Range* dropCaretRange,
657 InsertMode insertMode,
658 DragSourceType dragSourceType) {
659 if (!dropTarget || !dropTarget->isConnected())
660 return true;
661
662 // Dispatch 'beforeinput'.
663 DataTransfer* dataTransfer =
664 DataTransfer::create(DataTransfer::DragAndDrop, DataTransferReadable,
665 dragData->platformData());
666 dataTransfer->setSourceOperation(dragData->draggingSourceOperationMask());
667 const bool shouldInsert =
668 dispatchBeforeInputDataTransfer(
669 dropTarget, InputEvent::InputType::InsertFromDrop, dataTransfer,
670 nullptr) == DispatchEventResult::NotCanceled;
671
672 // 'beforeinput' event handler may destroy frame, return false to cancel
673 // remaining actions;
674 if (m_frame->document()->frame() != m_frame)
675 return false;
676
677 if (shouldInsert && dropTarget->isConnected())
678 replaceSelectionAfterDragging(fragment, insertMode, dragSourceType);
679
680 return true;
681 }
682
683 EphemeralRange Editor::selectedRange() { 615 EphemeralRange Editor::selectedRange() {
684 return frame().selection().selection().toNormalizedEphemeralRange(); 616 return frame().selection().selection().toNormalizedEphemeralRange();
685 } 617 }
686 618
687 bool Editor::canDeleteRange(const EphemeralRange& range) const { 619 bool Editor::canDeleteRange(const EphemeralRange& range) const {
688 if (range.isCollapsed()) 620 if (range.isCollapsed())
689 return false; 621 return false;
690 622
691 Node* startContainer = range.startPosition().computeContainerNode(); 623 Node* startContainer = range.startPosition().computeContainerNode();
692 Node* endContainer = range.endPosition().computeContainerNode(); 624 Node* endContainer = range.endPosition().computeContainerNode();
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 spellChecker().updateMarkersForWordsAffectedByEditing(true); 994 spellChecker().updateMarkersForWordsAffectedByEditing(true);
1063 if (enclosingTextControl(frame().selection().start())) { 995 if (enclosingTextControl(frame().selection().start())) {
1064 String plainText = frame().selectedTextForClipboard(); 996 String plainText = frame().selectedTextForClipboard();
1065 Pasteboard::generalPasteboard()->writePlainText( 997 Pasteboard::generalPasteboard()->writePlainText(
1066 plainText, canSmartCopyOrDelete() ? Pasteboard::CanSmartReplace 998 plainText, canSmartCopyOrDelete() ? Pasteboard::CanSmartReplace
1067 : Pasteboard::CannotSmartReplace); 999 : Pasteboard::CannotSmartReplace);
1068 } else { 1000 } else {
1069 writeSelectionToPasteboard(); 1001 writeSelectionToPasteboard();
1070 } 1002 }
1071 1003
1072 if (source == EditCommandSource::kMenuOrKeyBinding) {
1073 if (dispatchBeforeInputDataTransfer(findEventTargetFromSelection(),
1074 InputEvent::InputType::DeleteByCut,
1075 nullptr, nullptr) !=
1076 DispatchEventResult::NotCanceled)
1077 return;
1078 // 'beforeinput' event handler may destroy target frame.
1079 if (m_frame->document()->frame() != m_frame)
1080 return;
1081 }
1082 deleteSelectionWithSmartDelete( 1004 deleteSelectionWithSmartDelete(
1083 source, canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple, 1005 source, canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple,
1084 InputEvent::InputType::DeleteByCut); 1006 InputEvent::InputType::DeleteByCut);
1085 } 1007 }
1086 } 1008 }
1087 1009
1088 void Editor::copy() { 1010 void Editor::copy() {
1089 if (tryDHTMLCopy()) 1011 if (tryDHTMLCopy())
1090 return; // DHTML did the whole operation 1012 return; // DHTML did the whole operation
1091 if (!canCopy()) 1013 if (!canCopy())
(...skipping 14 matching lines...) Expand all
1106 Document* document = frame().document(); 1028 Document* document = frame().document();
1107 if (HTMLImageElement* imageElement = 1029 if (HTMLImageElement* imageElement =
1108 imageElementFromImageDocument(document)) 1030 imageElementFromImageDocument(document))
1109 writeImageNodeToPasteboard(Pasteboard::generalPasteboard(), imageElement, 1031 writeImageNodeToPasteboard(Pasteboard::generalPasteboard(), imageElement,
1110 document->title()); 1032 document->title());
1111 else 1033 else
1112 writeSelectionToPasteboard(); 1034 writeSelectionToPasteboard();
1113 } 1035 }
1114 } 1036 }
1115 1037
1116 void Editor::paste(EditCommandSource source) { 1038 // TODO(chongz): Pass |EditCommandSource| to |TextEvent| and don't fire
1039 // 'beforeinput' for JS triggered paste.
1040 void Editor::paste(EditCommandSource) {
1117 DCHECK(frame().document()); 1041 DCHECK(frame().document());
1118 if (tryDHTMLPaste(AllMimeTypes)) 1042 if (tryDHTMLPaste(AllMimeTypes))
1119 return; // DHTML did the whole operation 1043 return; // DHTML did the whole operation
1120 if (!canPaste()) 1044 if (!canPaste())
1121 return; 1045 return;
1122 spellChecker().updateMarkersForWordsAffectedByEditing(false); 1046 spellChecker().updateMarkersForWordsAffectedByEditing(false);
1123 ResourceFetcher* loader = frame().document()->fetcher(); 1047 ResourceFetcher* loader = frame().document()->fetcher();
1124 ResourceCacheValidationSuppressor validationSuppressor(loader); 1048 ResourceCacheValidationSuppressor validationSuppressor(loader);
1125 1049
1126 PasteMode pasteMode = frame().selection().isContentRichlyEditable() 1050 PasteMode pasteMode = frame().selection().isContentRichlyEditable()
1127 ? AllMimeTypes 1051 ? AllMimeTypes
1128 : PlainTextOnly; 1052 : PlainTextOnly;
1129 1053
1130 if (source == EditCommandSource::kMenuOrKeyBinding) {
1131 DataTransfer* dataTransfer =
1132 DataTransfer::create(DataTransfer::CopyAndPaste, DataTransferReadable,
1133 DataObject::createFromPasteboard(pasteMode));
1134
1135 if (dispatchBeforeInputDataTransfer(findEventTargetFromSelection(),
1136 InputEvent::InputType::InsertFromPaste,
1137 dataTransfer, nullptr) !=
1138 DispatchEventResult::NotCanceled)
1139 return;
1140 // 'beforeinput' event handler may destroy target frame.
1141 if (m_frame->document()->frame() != m_frame)
1142 return;
1143 }
1144
1145 if (pasteMode == AllMimeTypes) 1054 if (pasteMode == AllMimeTypes)
1146 pasteWithPasteboard(Pasteboard::generalPasteboard()); 1055 pasteWithPasteboard(Pasteboard::generalPasteboard());
1147 else 1056 else
1148 pasteAsPlainTextWithPasteboard(Pasteboard::generalPasteboard()); 1057 pasteAsPlainTextWithPasteboard(Pasteboard::generalPasteboard());
1149 } 1058 }
1150 1059
1151 void Editor::pasteAsPlainText(EditCommandSource source) { 1060 void Editor::pasteAsPlainText(EditCommandSource source) {
1152 if (tryDHTMLPaste(PlainTextOnly)) 1061 if (tryDHTMLPaste(PlainTextOnly))
1153 return; 1062 return;
1154 if (!canPaste()) 1063 if (!canPaste())
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1289 : direction == RightToLeftWritingDirection ? "rtl" : "inherit", 1198 : direction == RightToLeftWritingDirection ? "rtl" : "inherit",
1290 false); 1199 false);
1291 applyParagraphStyleToSelection( 1200 applyParagraphStyleToSelection(
1292 EditCommandSource::kMenuOrKeyBinding, style, 1201 EditCommandSource::kMenuOrKeyBinding, style,
1293 InputEvent::InputType::FormatSetBlockTextDirection); 1202 InputEvent::InputType::FormatSetBlockTextDirection);
1294 } 1203 }
1295 1204
1296 void Editor::revealSelectionAfterEditingOperation( 1205 void Editor::revealSelectionAfterEditingOperation(
1297 const ScrollAlignment& alignment, 1206 const ScrollAlignment& alignment,
1298 RevealExtentOption revealExtentOption) { 1207 RevealExtentOption revealExtentOption) {
1299 if (m_preventRevealSelection) 1208 if (m_preventRevealSelection || !m_frame->selection().isAvailable())
1300 return; 1209 return;
1301 frame().selection().revealSelection(alignment, revealExtentOption); 1210 frame().selection().revealSelection(alignment, revealExtentOption);
1302 } 1211 }
1303 1212
1304 void Editor::transpose(EditCommandSource source) { 1213 void Editor::transpose(EditCommandSource source) {
1305 if (!canEdit()) 1214 if (!canEdit())
1306 return; 1215 return;
1307 1216
1308 VisibleSelection selection = frame().selection().selection(); 1217 VisibleSelection selection = frame().selection().selection();
1309 if (!selection.isCaret()) 1218 if (!selection.isCaret())
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
1707 } 1616 }
1708 1617
1709 DEFINE_TRACE(Editor) { 1618 DEFINE_TRACE(Editor) {
1710 visitor->trace(m_frame); 1619 visitor->trace(m_frame);
1711 visitor->trace(m_lastEditCommand); 1620 visitor->trace(m_lastEditCommand);
1712 visitor->trace(m_undoStack); 1621 visitor->trace(m_undoStack);
1713 visitor->trace(m_mark); 1622 visitor->trace(m_mark);
1714 } 1623 }
1715 1624
1716 } // namespace blink 1625 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/editing/Editor.h ('k') | third_party/WebKit/Source/core/editing/EditorKeyBindings.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698