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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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" | |
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()) |
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( | |
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 Loading... | |
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( | |
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 Loading... | |
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(), | |
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 Loading... | |
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. | |
chongz
2016/12/20 04:48:58
See comments in "inputevent-execcommand.html".
| |
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(), | |
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 Loading... | |
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()) |
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 Loading... | |
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 |
OLD | NEW |