OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |