| 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 |