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

Side by Side Diff: third_party/WebKit/Source/core/page/DragController.cpp

Issue 2374743002: [InputEvent] Support |deleteByDrag|, |insertFromDrop| and fire in sequential order (Closed)
Patch Set: Yosin's review 2 Created 4 years, 2 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
« no previous file with comments | « third_party/WebKit/Source/core/events/InputEvent.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007, 2009, 2010 Apple Inc. All rights reserved. 2 * Copyright (C) 2007, 2009, 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Google Inc. 3 * Copyright (C) 2008 Google Inc.
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 24 matching lines...) Expand all
35 #include "core/dom/Document.h" 35 #include "core/dom/Document.h"
36 #include "core/dom/DocumentFragment.h" 36 #include "core/dom/DocumentFragment.h"
37 #include "core/dom/Element.h" 37 #include "core/dom/Element.h"
38 #include "core/dom/Node.h" 38 #include "core/dom/Node.h"
39 #include "core/dom/Text.h" 39 #include "core/dom/Text.h"
40 #include "core/dom/shadow/ShadowRoot.h" 40 #include "core/dom/shadow/ShadowRoot.h"
41 #include "core/editing/DragCaretController.h" 41 #include "core/editing/DragCaretController.h"
42 #include "core/editing/EditingUtilities.h" 42 #include "core/editing/EditingUtilities.h"
43 #include "core/editing/Editor.h" 43 #include "core/editing/Editor.h"
44 #include "core/editing/FrameSelection.h" 44 #include "core/editing/FrameSelection.h"
45 #include "core/editing/commands/DragAndDropCommand.h"
45 #include "core/editing/serializers/Serialization.h" 46 #include "core/editing/serializers/Serialization.h"
46 #include "core/events/TextEvent.h" 47 #include "core/events/TextEvent.h"
47 #include "core/fetch/ImageResource.h" 48 #include "core/fetch/ImageResource.h"
48 #include "core/fetch/ResourceFetcher.h" 49 #include "core/fetch/ResourceFetcher.h"
49 #include "core/frame/FrameHost.h" 50 #include "core/frame/FrameHost.h"
50 #include "core/frame/FrameView.h" 51 #include "core/frame/FrameView.h"
51 #include "core/frame/LocalFrame.h" 52 #include "core/frame/LocalFrame.h"
52 #include "core/frame/Settings.h" 53 #include "core/frame/Settings.h"
53 #include "core/html/HTMLAnchorElement.h" 54 #include "core/html/HTMLAnchorElement.h"
54 #include "core/html/HTMLFormElement.h" 55 #include "core/html/HTMLFormElement.h"
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 m_dragInitiator(nullptr), 137 m_dragInitiator(nullptr),
137 m_fileInputElementUnderMouse(nullptr), 138 m_fileInputElementUnderMouse(nullptr),
138 m_documentIsHandlingDrag(false), 139 m_documentIsHandlingDrag(false),
139 m_dragDestinationAction(DragDestinationActionNone), 140 m_dragDestinationAction(DragDestinationActionNone),
140 m_didInitiateDrag(false) {} 141 m_didInitiateDrag(false) {}
141 142
142 DragController* DragController::create(Page* page) { 143 DragController* DragController::create(Page* page) {
143 return new DragController(page); 144 return new DragController(page);
144 } 145 }
145 146
146 static DocumentFragment* documentFragmentFromDragData(DragData* dragData, 147 static DocumentFragment* documentFragmentFromDragData(
147 LocalFrame* frame, 148 DragData* dragData,
148 Range* context, 149 LocalFrame* frame,
149 bool allowPlainText, 150 Range* context,
150 bool& chosePlainText) { 151 bool allowPlainText,
151 ASSERT(dragData); 152 DragSourceType& dragSourceType) {
152 chosePlainText = false; 153 DCHECK(dragData);
154 dragSourceType = DragSourceType::HTMLSource;
153 155
154 Document& document = context->ownerDocument(); 156 Document& document = context->ownerDocument();
155 if (dragData->containsCompatibleContent()) { 157 if (dragData->containsCompatibleContent()) {
156 if (DocumentFragment* fragment = dragData->asFragment(frame)) 158 if (DocumentFragment* fragment = dragData->asFragment(frame))
157 return fragment; 159 return fragment;
158 160
159 if (dragData->containsURL(DragData::DoNotConvertFilenames)) { 161 if (dragData->containsURL(DragData::DoNotConvertFilenames)) {
160 String title; 162 String title;
161 String url = dragData->asURL(DragData::DoNotConvertFilenames, &title); 163 String url = dragData->asURL(DragData::DoNotConvertFilenames, &title);
162 if (!url.isEmpty()) { 164 if (!url.isEmpty()) {
163 HTMLAnchorElement* anchor = HTMLAnchorElement::create(document); 165 HTMLAnchorElement* anchor = HTMLAnchorElement::create(document);
164 anchor->setHref(AtomicString(url)); 166 anchor->setHref(AtomicString(url));
165 if (title.isEmpty()) { 167 if (title.isEmpty()) {
166 // Try the plain text first because the url might be normalized or esc aped. 168 // Try the plain text first because the url might be normalized or esc aped.
167 if (dragData->containsPlainText()) 169 if (dragData->containsPlainText())
168 title = dragData->asPlainText(); 170 title = dragData->asPlainText();
169 if (title.isEmpty()) 171 if (title.isEmpty())
170 title = url; 172 title = url;
171 } 173 }
172 Node* anchorText = document.createTextNode(title); 174 Node* anchorText = document.createTextNode(title);
173 anchor->appendChild(anchorText); 175 anchor->appendChild(anchorText);
174 DocumentFragment* fragment = document.createDocumentFragment(); 176 DocumentFragment* fragment = document.createDocumentFragment();
175 fragment->appendChild(anchor); 177 fragment->appendChild(anchor);
176 return fragment; 178 return fragment;
177 } 179 }
178 } 180 }
179 } 181 }
180 if (allowPlainText && dragData->containsPlainText()) { 182 if (allowPlainText && dragData->containsPlainText()) {
181 chosePlainText = true; 183 dragSourceType = DragSourceType::PlainTextSource;
182 return createFragmentFromText(EphemeralRange(context), 184 return createFragmentFromText(EphemeralRange(context),
183 dragData->asPlainText()); 185 dragData->asPlainText());
184 } 186 }
185 187
186 return nullptr; 188 return nullptr;
187 } 189 }
188 190
189 bool DragController::dragIsMove(FrameSelection& selection, DragData* dragData) { 191 bool DragController::dragIsMove(FrameSelection& selection, DragData* dragData) {
190 return m_documentUnderMouse == m_dragInitiator && 192 return m_documentUnderMouse == m_dragInitiator &&
191 selection.isContentEditable() && selection.isRange() && 193 selection.isContentEditable() && selection.isRange() &&
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 } 536 }
535 Range* range = createRange(dragCaret.toNormalizedEphemeralRange()); 537 Range* range = createRange(dragCaret.toNormalizedEphemeralRange());
536 Element* rootEditableElement = innerFrame->selection().rootEditableElement(); 538 Element* rootEditableElement = innerFrame->selection().rootEditableElement();
537 539
538 // For range to be null a WebKit client must have done something bad while 540 // For range to be null a WebKit client must have done something bad while
539 // manually controlling drag behaviour 541 // manually controlling drag behaviour
540 if (!range) 542 if (!range)
541 return false; 543 return false;
542 ResourceFetcher* fetcher = range->ownerDocument().fetcher(); 544 ResourceFetcher* fetcher = range->ownerDocument().fetcher();
543 ResourceCacheValidationSuppressor validationSuppressor(fetcher); 545 ResourceCacheValidationSuppressor validationSuppressor(fetcher);
546
547 // Start new Drag&Drop command group, invalidate previous command group.
548 // Assume no other places is firing |DeleteByDrag| and |InsertFromDrop|.
549 innerFrame->editor().registerCommandGroup(
550 DragAndDropCommand::create(*innerFrame->document()));
551
544 if (dragIsMove(innerFrame->selection(), dragData) || 552 if (dragIsMove(innerFrame->selection(), dragData) ||
545 dragCaret.isContentRichlyEditable()) { 553 dragCaret.isContentRichlyEditable()) {
546 bool chosePlainText = false; 554 DragSourceType dragSourceType = DragSourceType::HTMLSource;
547 DocumentFragment* fragment = documentFragmentFromDragData( 555 DocumentFragment* fragment = documentFragmentFromDragData(
548 dragData, innerFrame, range, true, chosePlainText); 556 dragData, innerFrame, range, true, dragSourceType);
549 if (!fragment) 557 if (!fragment)
550 return false; 558 return false;
551 559
552 if (dragIsMove(innerFrame->selection(), dragData)) { 560 if (dragIsMove(innerFrame->selection(), dragData)) {
553 // NSTextView behavior is to always smart delete on moving a selection, 561 // NSTextView behavior is to always smart delete on moving a selection,
554 // but only to smart insert if the selection granularity is word granulari ty. 562 // but only to smart insert if the selection granularity is word granulari ty.
555 bool smartDelete = innerFrame->editor().smartInsertDeleteEnabled(); 563 const DeleteMode deleteMode =
556 bool smartInsert = 564 innerFrame->editor().smartInsertDeleteEnabled() ? DeleteMode::Smart
557 smartDelete && 565 : DeleteMode::Simple;
558 innerFrame->selection().granularity() == WordGranularity && 566 const InsertMode insertMode =
559 dragData->canSmartReplace(); 567 (deleteMode == DeleteMode::Smart &&
560 innerFrame->editor().moveSelectionAfterDragging( 568 innerFrame->selection().granularity() == WordGranularity &&
561 fragment, dragCaret.base(), smartInsert, smartDelete); 569 dragData->canSmartReplace())
570 ? InsertMode::Smart
571 : InsertMode::Simple;
572
573 if (!innerFrame->editor().deleteSelectionAfterDraggingWithEvents(
574 innerFrame->editor().findEventTargetFromSelection(), deleteMode,
575 dragCaret.base()))
576 return false;
577
578 innerFrame->selection().setSelection(createVisibleSelectionDeprecated(
579 range->startPosition(), range->endPosition()));
580 if (innerFrame->selection().isAvailable()) {
581 DCHECK(m_documentUnderMouse);
582 if (!innerFrame->editor().replaceSelectionAfterDraggingWithEvents(
583 element, dragData, fragment, range, insertMode, dragSourceType))
584 return false;
585 }
562 } else { 586 } else {
563 if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) { 587 if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) {
564 ASSERT(m_documentUnderMouse); 588 DCHECK(m_documentUnderMouse);
565 m_documentUnderMouse->frame()->editor().replaceSelectionAfterDragging( 589 if (!innerFrame->editor().replaceSelectionAfterDraggingWithEvents(
566 fragment, dragData->canSmartReplace(), chosePlainText); 590 element, dragData, fragment, range,
591 dragData->canSmartReplace() ? InsertMode::Smart
592 : InsertMode::Simple,
593 dragSourceType))
594 return false;
567 } 595 }
568 } 596 }
569 } else { 597 } else {
570 String text = dragData->asPlainText(); 598 String text = dragData->asPlainText();
571 if (text.isEmpty()) 599 if (text.isEmpty())
572 return false; 600 return false;
573 601
574 if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) { 602 if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) {
575 const bool canSmartReplace = false; 603 DCHECK(m_documentUnderMouse);
576 const bool chosePlainText = true; 604 if (!innerFrame->editor().replaceSelectionAfterDraggingWithEvents(
577 ASSERT(m_documentUnderMouse); 605 element, dragData,
578 m_documentUnderMouse->frame()->editor().replaceSelectionAfterDragging( 606 createFragmentFromText(EphemeralRange(range), text), range,
579 createFragmentFromText(EphemeralRange(range), text), canSmartReplace, 607 InsertMode::Simple, DragSourceType::PlainTextSource))
580 chosePlainText); 608 return false;
581 } 609 }
582 } 610 }
583 611
584 if (rootEditableElement) { 612 if (rootEditableElement) {
585 if (LocalFrame* frame = rootEditableElement->document().frame()) 613 if (LocalFrame* frame = rootEditableElement->document().frame())
586 frame->eventHandler().updateDragStateAfterEditDragIfNeeded( 614 frame->eventHandler().updateDragStateAfterEditDragIfNeeded(
587 rootEditableElement); 615 rootEditableElement);
588 } 616 }
589 617
590 return true; 618 return true;
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after
1117 } 1145 }
1118 1146
1119 DEFINE_TRACE(DragController) { 1147 DEFINE_TRACE(DragController) {
1120 visitor->trace(m_page); 1148 visitor->trace(m_page);
1121 visitor->trace(m_documentUnderMouse); 1149 visitor->trace(m_documentUnderMouse);
1122 visitor->trace(m_dragInitiator); 1150 visitor->trace(m_dragInitiator);
1123 visitor->trace(m_fileInputElementUnderMouse); 1151 visitor->trace(m_fileInputElementUnderMouse);
1124 } 1152 }
1125 1153
1126 } // namespace blink 1154 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/events/InputEvent.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698