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

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: 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 #include "core/layout/HitTestResult.h" 79 #include "core/layout/HitTestResult.h"
80 #include "core/layout/LayoutImage.h" 80 #include "core/layout/LayoutImage.h"
81 #include "core/loader/EmptyClients.h" 81 #include "core/loader/EmptyClients.h"
82 #include "core/loader/resource/ImageResourceContent.h" 82 #include "core/loader/resource/ImageResourceContent.h"
83 #include "core/page/DragData.h" 83 #include "core/page/DragData.h"
84 #include "core/page/EditorClient.h" 84 #include "core/page/EditorClient.h"
85 #include "core/page/FocusController.h" 85 #include "core/page/FocusController.h"
86 #include "core/page/Page.h" 86 #include "core/page/Page.h"
87 #include "core/svg/SVGImageElement.h" 87 #include "core/svg/SVGImageElement.h"
88 #include "platform/KillRing.h" 88 #include "platform/KillRing.h"
89 #include "platform/clipboard/ClipboardMimeTypes.h"
Xiaocheng 2016/12/21 02:56:38 What needs it?
chongz 2016/12/21 23:59:24 My mistake, removed. It was added for |dispatchBef
89 #include "platform/weborigin/KURL.h" 90 #include "platform/weborigin/KURL.h"
90 #include "wtf/PtrUtil.h" 91 #include "wtf/PtrUtil.h"
91 #include "wtf/text/CharacterNames.h" 92 #include "wtf/text/CharacterNames.h"
92 93
93 namespace blink { 94 namespace blink {
94 95
95 using namespace HTMLNames; 96 using namespace HTMLNames;
96 using namespace WTF; 97 using namespace WTF;
97 using namespace Unicode; 98 using namespace Unicode;
98 99
99 namespace { 100 namespace {
100 101
101 void dispatchInputEvent(Element* target, 102 void dispatchInputEvent(Element* target,
102 InputEvent::InputType inputType, 103 InputEvent::InputType inputType,
103 const String& data, 104 const String& data,
104 InputEvent::EventIsComposing isComposing) { 105 InputEvent::EventIsComposing isComposing) {
105 if (!RuntimeEnabledFeatures::inputEventEnabled()) 106 if (!RuntimeEnabledFeatures::inputEventEnabled())
106 return; 107 return;
107 if (!target) 108 if (!target || !target->isConnected())
Xiaocheng 2016/12/21 02:56:38 This part doesn't seem relevant to beforeinput.
chongz 2016/12/21 23:59:24 Moved to the end of 'EditingUtilities.cpp::dispatc
108 return; 109 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 = 110 InputEvent* inputEvent =
112 InputEvent::createInput(inputType, data, isComposing, nullptr); 111 InputEvent::createInput(inputType, data, isComposing);
113 target->dispatchScopedEvent(inputEvent); 112 target->dispatchScopedEvent(inputEvent);
114 } 113 }
115 114
116 void dispatchInputEventEditableContentChanged( 115 void dispatchInputEventEditableContentChanged(
117 Element* startRoot, 116 Element* startRoot,
118 Element* endRoot, 117 Element* endRoot,
119 InputEvent::InputType inputType, 118 InputEvent::InputType inputType,
120 const String& data, 119 const String& data,
121 InputEvent::EventIsComposing isComposing) { 120 InputEvent::EventIsComposing isComposing) {
122 if (startRoot) 121 if (startRoot)
123 dispatchInputEvent(startRoot, inputType, data, isComposing); 122 dispatchInputEvent(startRoot, inputType, data, isComposing);
124 if (endRoot && endRoot != startRoot) 123 if (endRoot && endRoot != startRoot)
125 dispatchInputEvent(endRoot, inputType, data, isComposing); 124 dispatchInputEvent(endRoot, inputType, data, isComposing);
126 } 125 }
127 126
128 InputEvent::EventIsComposing isComposingFromCommand(
chongz 2016/12/20 23:27:51 Moved to |EditingUtilities.cpp::isComposingFromCom
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 127 } // anonymous namespace
138 128
139 Editor::RevealSelectionScope::RevealSelectionScope(Editor* editor) 129 Editor::RevealSelectionScope::RevealSelectionScope(Editor* editor)
140 : m_editor(editor) { 130 : m_editor(editor) {
141 ++m_editor->m_preventRevealSelection; 131 ++m_editor->m_preventRevealSelection;
142 } 132 }
143 133
144 Editor::RevealSelectionScope::~RevealSelectionScope() { 134 Editor::RevealSelectionScope::~RevealSelectionScope() {
145 DCHECK(m_editor->m_preventRevealSelection); 135 DCHECK(m_editor->m_preventRevealSelection);
146 --m_editor->m_preventRevealSelection; 136 --m_editor->m_preventRevealSelection;
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 if (insertMode == InsertMode::Smart) 606 if (insertMode == InsertMode::Smart)
617 options |= ReplaceSelectionCommand::SmartReplace; 607 options |= ReplaceSelectionCommand::SmartReplace;
618 if (dragSourceType == DragSourceType::PlainTextSource) 608 if (dragSourceType == DragSourceType::PlainTextSource)
619 options |= ReplaceSelectionCommand::MatchStyle; 609 options |= ReplaceSelectionCommand::MatchStyle;
620 DCHECK(frame().document()); 610 DCHECK(frame().document());
621 ReplaceSelectionCommand::create(*frame().document(), fragment, options, 611 ReplaceSelectionCommand::create(*frame().document(), fragment, options,
622 InputEvent::InputType::InsertFromDrop) 612 InputEvent::InputType::InsertFromDrop)
623 ->apply(EditCommandSource::kMenuOrKeyBinding); 613 ->apply(EditCommandSource::kMenuOrKeyBinding);
624 } 614 }
625 615
626 bool Editor::deleteSelectionAfterDraggingWithEvents(
chongz 2016/12/20 23:27:51 See header file.
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() { 616 EphemeralRange Editor::selectedRange() {
684 return frame().selection().selection().toNormalizedEphemeralRange(); 617 return frame().selection().selection().toNormalizedEphemeralRange();
685 } 618 }
686 619
687 bool Editor::canDeleteRange(const EphemeralRange& range) const { 620 bool Editor::canDeleteRange(const EphemeralRange& range) const {
688 if (range.isCollapsed()) 621 if (range.isCollapsed())
689 return false; 622 return false;
690 623
691 Node* startContainer = range.startPosition().computeContainerNode(); 624 Node* startContainer = range.startPosition().computeContainerNode();
692 Node* endContainer = range.endPosition().computeContainerNode(); 625 Node* endContainer = range.endPosition().computeContainerNode();
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 spellChecker().updateMarkersForWordsAffectedByEditing(true); 995 spellChecker().updateMarkersForWordsAffectedByEditing(true);
1063 if (enclosingTextControl(frame().selection().start())) { 996 if (enclosingTextControl(frame().selection().start())) {
1064 String plainText = frame().selectedTextForClipboard(); 997 String plainText = frame().selectedTextForClipboard();
1065 Pasteboard::generalPasteboard()->writePlainText( 998 Pasteboard::generalPasteboard()->writePlainText(
1066 plainText, canSmartCopyOrDelete() ? Pasteboard::CanSmartReplace 999 plainText, canSmartCopyOrDelete() ? Pasteboard::CanSmartReplace
1067 : Pasteboard::CannotSmartReplace); 1000 : Pasteboard::CannotSmartReplace);
1068 } else { 1001 } else {
1069 writeSelectionToPasteboard(); 1002 writeSelectionToPasteboard();
1070 } 1003 }
1071 1004
1072 if (source == EditCommandSource::kMenuOrKeyBinding) {
1073 if (dispatchBeforeInputDataTransfer(findEventTargetFromSelection(),
chongz 2016/12/20 23:27:51 Removed, cut was covered by |DeleteSelectionComman
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( 1005 deleteSelectionWithSmartDelete(
1083 source, canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple, 1006 source, canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple,
1084 InputEvent::InputType::DeleteByCut); 1007 InputEvent::InputType::DeleteByCut);
1085 } 1008 }
1086 } 1009 }
1087 1010
1088 void Editor::copy() { 1011 void Editor::copy() {
1089 if (tryDHTMLCopy()) 1012 if (tryDHTMLCopy())
1090 return; // DHTML did the whole operation 1013 return; // DHTML did the whole operation
1091 if (!canCopy()) 1014 if (!canCopy())
(...skipping 14 matching lines...) Expand all
1106 Document* document = frame().document(); 1029 Document* document = frame().document();
1107 if (HTMLImageElement* imageElement = 1030 if (HTMLImageElement* imageElement =
1108 imageElementFromImageDocument(document)) 1031 imageElementFromImageDocument(document))
1109 writeImageNodeToPasteboard(Pasteboard::generalPasteboard(), imageElement, 1032 writeImageNodeToPasteboard(Pasteboard::generalPasteboard(), imageElement,
1110 document->title()); 1033 document->title());
1111 else 1034 else
1112 writeSelectionToPasteboard(); 1035 writeSelectionToPasteboard();
1113 } 1036 }
1114 } 1037 }
1115 1038
1116 void Editor::paste(EditCommandSource source) { 1039 // TODO(chongz): Pass |EditCommandSource| to |TextEvent| and don't fire
1040 // 'beforeinput' for JS triggered paste.
1041 void Editor::paste(EditCommandSource) {
1117 DCHECK(frame().document()); 1042 DCHECK(frame().document());
1118 if (tryDHTMLPaste(AllMimeTypes)) 1043 if (tryDHTMLPaste(AllMimeTypes))
1119 return; // DHTML did the whole operation 1044 return; // DHTML did the whole operation
1120 if (!canPaste()) 1045 if (!canPaste())
1121 return; 1046 return;
1122 spellChecker().updateMarkersForWordsAffectedByEditing(false); 1047 spellChecker().updateMarkersForWordsAffectedByEditing(false);
1123 ResourceFetcher* loader = frame().document()->fetcher(); 1048 ResourceFetcher* loader = frame().document()->fetcher();
1124 ResourceCacheValidationSuppressor validationSuppressor(loader); 1049 ResourceCacheValidationSuppressor validationSuppressor(loader);
1125 1050
1126 PasteMode pasteMode = frame().selection().isContentRichlyEditable() 1051 PasteMode pasteMode = frame().selection().isContentRichlyEditable()
1127 ? AllMimeTypes 1052 ? AllMimeTypes
1128 : PlainTextOnly; 1053 : PlainTextOnly;
1129 1054
1130 if (source == EditCommandSource::kMenuOrKeyBinding) {
1131 DataTransfer* dataTransfer =
1132 DataTransfer::create(DataTransfer::CopyAndPaste, DataTransferReadable,
1133 DataObject::createFromPasteboard(pasteMode));
1134
1135 if (dispatchBeforeInputDataTransfer(findEventTargetFromSelection(),
chongz 2016/12/20 23:27:51 Removed, paste was covered by |ReplaceSelectionCom
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) 1055 if (pasteMode == AllMimeTypes)
1146 pasteWithPasteboard(Pasteboard::generalPasteboard()); 1056 pasteWithPasteboard(Pasteboard::generalPasteboard());
1147 else 1057 else
1148 pasteAsPlainTextWithPasteboard(Pasteboard::generalPasteboard()); 1058 pasteAsPlainTextWithPasteboard(Pasteboard::generalPasteboard());
1149 } 1059 }
1150 1060
1151 void Editor::pasteAsPlainText(EditCommandSource source) { 1061 void Editor::pasteAsPlainText(EditCommandSource source) {
1152 if (tryDHTMLPaste(PlainTextOnly)) 1062 if (tryDHTMLPaste(PlainTextOnly))
1153 return; 1063 return;
1154 if (!canPaste()) 1064 if (!canPaste())
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1289 : direction == RightToLeftWritingDirection ? "rtl" : "inherit", 1199 : direction == RightToLeftWritingDirection ? "rtl" : "inherit",
1290 false); 1200 false);
1291 applyParagraphStyleToSelection( 1201 applyParagraphStyleToSelection(
1292 EditCommandSource::kMenuOrKeyBinding, style, 1202 EditCommandSource::kMenuOrKeyBinding, style,
1293 InputEvent::InputType::FormatSetBlockTextDirection); 1203 InputEvent::InputType::FormatSetBlockTextDirection);
1294 } 1204 }
1295 1205
1296 void Editor::revealSelectionAfterEditingOperation( 1206 void Editor::revealSelectionAfterEditingOperation(
1297 const ScrollAlignment& alignment, 1207 const ScrollAlignment& alignment,
1298 RevealExtentOption revealExtentOption) { 1208 RevealExtentOption revealExtentOption) {
1299 if (m_preventRevealSelection) 1209 if (m_preventRevealSelection || !m_frame->selection().isAvailable())
Xiaocheng 2016/12/21 02:56:38 This part seems to be a bug fix. Does any test cas
chongz 2016/12/21 23:59:24 The test case is "fast/events/inputevents/beforein
1300 return; 1210 return;
1301 frame().selection().revealSelection(alignment, revealExtentOption); 1211 frame().selection().revealSelection(alignment, revealExtentOption);
1302 } 1212 }
1303 1213
1304 void Editor::transpose(EditCommandSource source) { 1214 void Editor::transpose(EditCommandSource source) {
1305 if (!canEdit()) 1215 if (!canEdit())
1306 return; 1216 return;
1307 1217
1308 VisibleSelection selection = frame().selection().selection(); 1218 VisibleSelection selection = frame().selection().selection();
1309 if (!selection.isCaret()) 1219 if (!selection.isCaret())
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
1707 } 1617 }
1708 1618
1709 DEFINE_TRACE(Editor) { 1619 DEFINE_TRACE(Editor) {
1710 visitor->trace(m_frame); 1620 visitor->trace(m_frame);
1711 visitor->trace(m_lastEditCommand); 1621 visitor->trace(m_lastEditCommand);
1712 visitor->trace(m_undoStack); 1622 visitor->trace(m_undoStack);
1713 visitor->trace(m_mark); 1623 visitor->trace(m_mark);
1714 } 1624 }
1715 1625
1716 } // namespace blink 1626 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698