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

Unified Diff: third_party/WebKit/Source/core/page/DragController.cpp

Issue 2374743002: [InputEvent] Support |deleteByDrag|, |insertFromDrop| and fire in sequential order (Closed)
Patch Set: Created 4 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/page/DragController.cpp
diff --git a/third_party/WebKit/Source/core/page/DragController.cpp b/third_party/WebKit/Source/core/page/DragController.cpp
index 70e4290a77a1b481e6320b4fce4f54f1837486a4..296f88e4d52f5f188edead036c4e0001f19cdabc 100644
--- a/third_party/WebKit/Source/core/page/DragController.cpp
+++ b/third_party/WebKit/Source/core/page/DragController.cpp
@@ -92,6 +92,96 @@
namespace blink {
+namespace {
+
+DataTransfer* createDraggingDataTransfer(DataTransferAccessPolicy policy, DragData* dragData)
+{
+ return DataTransfer::create(DataTransfer::DragAndDrop, policy, dragData->platformData());
+}
+
+DocumentFragment* documentFragmentFromDragData(DragData* dragData, LocalFrame* frame, Range* context, bool allowPlainText, bool& chosePlainText)
+{
+ DCHECK(dragData);
+ chosePlainText = false;
+
+ Document& document = context->ownerDocument();
+ if (dragData->containsCompatibleContent()) {
+ if (DocumentFragment* fragment = dragData->asFragment(frame))
+ return fragment;
+
+ if (dragData->containsURL(DragData::DoNotConvertFilenames)) {
+ String title;
+ String url = dragData->asURL(DragData::DoNotConvertFilenames, &title);
+ if (!url.isEmpty()) {
+ HTMLAnchorElement* anchor = HTMLAnchorElement::create(document);
+ anchor->setHref(AtomicString(url));
+ if (title.isEmpty()) {
+ // Try the plain text first because the url might be normalized or escaped.
+ if (dragData->containsPlainText())
+ title = dragData->asPlainText();
+ if (title.isEmpty())
+ title = url;
+ }
+ Node* anchorText = document.createTextNode(title);
+ anchor->appendChild(anchorText);
+ DocumentFragment* fragment = document.createDocumentFragment();
+ fragment->appendChild(anchor);
+ return fragment;
+ }
+ }
+ }
+ if (allowPlainText && dragData->containsPlainText()) {
+ chosePlainText = true;
+ return createFragmentFromText(EphemeralRange(context), dragData->asPlainText());
+ }
+
+ return nullptr;
+}
+
+bool doDeleteByDragWithEvents(Element* dragTarget, bool smartDelete, const Position& referenceMovePosition)
yosin_UTC9 2016/09/28 04:19:03 Please add comment about |bool| return value.
chongz 2016/09/29 02:36:22 Done.
+{
yosin_UTC9 2016/09/28 04:19:03 This function should be in Editor class and avoid
chongz 2016/09/29 02:36:22 Done.
+ if (!dragTarget || !dragTarget->isConnected())
+ return true;
+
+ LocalFrame* dragFrame = dragTarget->document().frame();
+
+ // Dispatch 'beforeinput'.
+ const bool shouldDelete = dispatchBeforeInputEditorCommand(dragTarget, InputEvent::InputType::DeleteByDrag, nullptr) == DispatchEventResult::NotCanceled;
yosin_UTC9 2016/09/28 04:19:03 I think we should dispatch event to drag source ra
chongz 2016/09/29 02:36:22 Sorry for the confusion, I've renamed it to |dragS
+
+ // 'beforeinput' event handler may destroy frame, return false to cancel remaining actions;
+ if (dragFrame != dragTarget->document().frame())
+ return false;
+
+ if (shouldDelete && dragTarget->isConnected())
+ dragFrame->editor().deleteSelectionWithSmartDelete(smartDelete, InputEvent::InputType::DeleteByDrag, referenceMovePosition);
+
+ return true;
+}
+
+bool doInsertFromDropWithEvents(Element* dropTarget, DragData* dragData, DocumentFragment* fragment, Range* dropCaretRange, bool smartInsert, bool chosePlainText)
yosin_UTC9 2016/09/28 04:19:03 Please add comment about |bool| return value.
chongz 2016/09/29 02:36:22 Done.
+{
yosin_UTC9 2016/09/28 04:19:03 This function should be in Editor class and avoid
chongz 2016/09/29 02:36:22 Done.
+ if (!dropTarget || !dropTarget->isConnected())
+ return true;
+
+ LocalFrame* dropFrame = dropTarget->document().frame();
+
+ // Dispatch 'beforeinput'.
+ DataTransfer* dataTransfer = createDraggingDataTransfer(DataTransferReadable, dragData);
+ dataTransfer->setSourceOperation(dragData->draggingSourceOperationMask());
+ const bool shouldInsert = dispatchBeforeInputDataTransfer(dropTarget, InputEvent::InputType::InsertFromDrop, dataTransfer, nullptr) == DispatchEventResult::NotCanceled;
+
+ // 'beforeinput' event handler may destroy frame, return false to cancel remaining actions;
+ if (dropFrame != dropTarget->document().frame())
+ return false;
+
+ if (shouldInsert && dropTarget->isConnected())
+ dropFrame->editor().replaceSelectionAfterDragging(fragment, smartInsert, chosePlainText);
+
+ return true;
+}
+
+} // anonymous namespace
+
const int DragController::DragIconRightInset = 7;
const int DragController::DragIconBottomInset = 3;
@@ -124,11 +214,6 @@ static PlatformMouseEvent createMouseEvent(DragData* dragData)
PlatformMouseEvent::RealOrIndistinguishable, monotonicallyIncreasingTime());
}
-static DataTransfer* createDraggingDataTransfer(DataTransferAccessPolicy policy, DragData* dragData)
-{
- return DataTransfer::create(DataTransfer::DragAndDrop, policy, dragData->platformData());
-}
-
DragController::DragController(Page* page)
: m_page(page)
, m_documentUnderMouse(nullptr)
@@ -145,45 +230,6 @@ DragController* DragController::create(Page* page)
return new DragController(page);
}
-static DocumentFragment* documentFragmentFromDragData(DragData* dragData, LocalFrame* frame, Range* context, bool allowPlainText, bool& chosePlainText)
-{
- ASSERT(dragData);
- chosePlainText = false;
-
- Document& document = context->ownerDocument();
- if (dragData->containsCompatibleContent()) {
- if (DocumentFragment* fragment = dragData->asFragment(frame))
- return fragment;
-
- if (dragData->containsURL(DragData::DoNotConvertFilenames)) {
- String title;
- String url = dragData->asURL(DragData::DoNotConvertFilenames, &title);
- if (!url.isEmpty()) {
- HTMLAnchorElement* anchor = HTMLAnchorElement::create(document);
- anchor->setHref(AtomicString(url));
- if (title.isEmpty()) {
- // Try the plain text first because the url might be normalized or escaped.
- if (dragData->containsPlainText())
- title = dragData->asPlainText();
- if (title.isEmpty())
- title = url;
- }
- Node* anchorText = document.createTextNode(title);
- anchor->appendChild(anchorText);
- DocumentFragment* fragment = document.createDocumentFragment();
- fragment->appendChild(anchor);
- return fragment;
- }
- }
- }
- if (allowPlainText && dragData->containsPlainText()) {
- chosePlainText = true;
- return createFragmentFromText(EphemeralRange(context), dragData->asPlainText());
- }
-
- return nullptr;
-}
-
bool DragController::dragIsMove(FrameSelection& selection, DragData* dragData)
{
return m_documentUnderMouse == m_dragInitiator && selection.isContentEditable() && selection.isRange() && !isCopyKeyDown(dragData);
@@ -513,13 +559,23 @@ bool DragController::concludeEditDrag(DragData* dragData)
if (dragIsMove(innerFrame->selection(), dragData)) {
// NSTextView behavior is to always smart delete on moving a selection,
// but only to smart insert if the selection granularity is word granularity.
- bool smartDelete = innerFrame->editor().smartInsertDeleteEnabled();
- bool smartInsert = smartDelete && innerFrame->selection().granularity() == WordGranularity && dragData->canSmartReplace();
- innerFrame->editor().moveSelectionAfterDragging(fragment, dragCaret.base(), smartInsert, smartDelete);
+ const bool smartDelete = innerFrame->editor().smartInsertDeleteEnabled();
+ const bool smartInsert = smartDelete && innerFrame->selection().granularity() == WordGranularity && dragData->canSmartReplace();
+
+ if (!doDeleteByDragWithEvents(innerFrame->editor().findEventTargetFromSelection(), smartDelete, dragCaret.base()))
+ return false;
+
+ innerFrame->selection().setSelection(VisibleSelection(range->startPosition(), range->endPosition()));
+ if (innerFrame->selection().isAvailable()) {
+ DCHECK(m_documentUnderMouse);
+ if (!doInsertFromDropWithEvents(element, dragData, fragment, range, smartInsert, chosePlainText))
+ return false;
+ }
} else {
if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) {
- ASSERT(m_documentUnderMouse);
- m_documentUnderMouse->frame()->editor().replaceSelectionAfterDragging(fragment, dragData->canSmartReplace(), chosePlainText);
+ DCHECK(m_documentUnderMouse);
+ if (!doInsertFromDropWithEvents(element, dragData, fragment, range, dragData->canSmartReplace(), chosePlainText))
+ return false;
}
}
} else {
@@ -530,8 +586,9 @@ bool DragController::concludeEditDrag(DragData* dragData)
if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) {
const bool canSmartReplace = false;
const bool chosePlainText = true;
- ASSERT(m_documentUnderMouse);
- m_documentUnderMouse->frame()->editor().replaceSelectionAfterDragging(createFragmentFromText(EphemeralRange(range), text), canSmartReplace, chosePlainText);
+ DCHECK(m_documentUnderMouse);
+ if (!doInsertFromDropWithEvents(element, dragData, createFragmentFromText(EphemeralRange(range), text), range, canSmartReplace, chosePlainText))
+ return false;
}
}

Powered by Google App Engine
This is Rietveld 408576698