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

Side by Side Diff: third_party/WebKit/Source/core/editing/Editor.cpp

Issue 2374743002: [InputEvent] Support |deleteByDrag|, |insertFromDrop| and fire in sequential order (Closed)
Patch Set: Yosin's review 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
OLDNEW
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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 #include "core/html/HTMLHtmlElement.h" 74 #include "core/html/HTMLHtmlElement.h"
75 #include "core/html/HTMLImageElement.h" 75 #include "core/html/HTMLImageElement.h"
76 #include "core/html/HTMLInputElement.h" 76 #include "core/html/HTMLInputElement.h"
77 #include "core/html/HTMLTextAreaElement.h" 77 #include "core/html/HTMLTextAreaElement.h"
78 #include "core/html/parser/HTMLParserIdioms.h" 78 #include "core/html/parser/HTMLParserIdioms.h"
79 #include "core/input/EventHandler.h" 79 #include "core/input/EventHandler.h"
80 #include "core/inspector/ConsoleMessage.h" 80 #include "core/inspector/ConsoleMessage.h"
81 #include "core/layout/HitTestResult.h" 81 #include "core/layout/HitTestResult.h"
82 #include "core/layout/LayoutImage.h" 82 #include "core/layout/LayoutImage.h"
83 #include "core/loader/EmptyClients.h" 83 #include "core/loader/EmptyClients.h"
84 #include "core/page/DragData.h"
84 #include "core/page/EditorClient.h" 85 #include "core/page/EditorClient.h"
85 #include "core/page/FocusController.h" 86 #include "core/page/FocusController.h"
86 #include "core/page/Page.h" 87 #include "core/page/Page.h"
87 #include "core/svg/SVGImageElement.h" 88 #include "core/svg/SVGImageElement.h"
88 #include "platform/KillRing.h" 89 #include "platform/KillRing.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 {
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 342
342 // FIXME: We should to move this down into deleteKeyPressed. 343 // FIXME: We should to move this down into deleteKeyPressed.
343 // clear the "start new kill ring sequence" setting, because it was set to t rue 344 // clear the "start new kill ring sequence" setting, because it was set to t rue
344 // when the selection was updated by deleting the range 345 // when the selection was updated by deleting the range
345 if (killRing) 346 if (killRing)
346 setStartNewKillRingSequence(false); 347 setStartNewKillRingSequence(false);
347 348
348 return true; 349 return true;
349 } 350 }
350 351
351 void Editor::deleteSelectionWithSmartDelete(bool smartDelete, InputEvent::InputT ype inputType) 352 void Editor::deleteSelectionWithSmartDelete(bool smartDelete, InputEvent::InputT ype inputType, const Position& referenceMovePosition)
352 { 353 {
353 if (frame().selection().isNone()) 354 if (frame().selection().isNone())
354 return; 355 return;
355 356
356 const bool kMergeBlocksAfterDelete = true; 357 const bool kMergeBlocksAfterDelete = true;
357 const bool kExpandForSpecialElements = false; 358 const bool kExpandForSpecialElements = false;
358 const bool kSanitizeMarkup = true; 359 const bool kSanitizeMarkup = true;
359 DCHECK(frame().document()); 360 DCHECK(frame().document());
360 DeleteSelectionCommand::create(*frame().document(), smartDelete, kMergeBlock sAfterDelete, kExpandForSpecialElements, kSanitizeMarkup, inputType)->apply(); 361 DeleteSelectionCommand::create(*frame().document(), smartDelete, kMergeBlock sAfterDelete, kExpandForSpecialElements, kSanitizeMarkup, inputType, referenceMo vePosition)->apply();
361 } 362 }
362 363
363 void Editor::pasteAsPlainText(const String& pastingText, bool smartReplace) 364 void Editor::pasteAsPlainText(const String& pastingText, bool smartReplace)
364 { 365 {
365 Element* target = findEventTargetFromSelection(); 366 Element* target = findEventTargetFromSelection();
366 if (!target) 367 if (!target)
367 return; 368 return;
368 target->dispatchEvent(TextEvent::createForPlainTextPaste(frame().domWindow() , pastingText, smartReplace)); 369 target->dispatchEvent(TextEvent::createForPlainTextPaste(frame().domWindow() , pastingText, smartReplace));
369 } 370 }
370 371
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 545
545 // TODO(xiaochengh): Merge it with |replaceSelectionWithFragment()|. 546 // TODO(xiaochengh): Merge it with |replaceSelectionWithFragment()|.
546 void Editor::replaceSelectionAfterDragging(DocumentFragment* fragment, bool smar tReplace, bool plainText) 547 void Editor::replaceSelectionAfterDragging(DocumentFragment* fragment, bool smar tReplace, bool plainText)
547 { 548 {
548 ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::S electReplacement | ReplaceSelectionCommand::PreventNesting; 549 ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::S electReplacement | ReplaceSelectionCommand::PreventNesting;
549 if (smartReplace) 550 if (smartReplace)
550 options |= ReplaceSelectionCommand::SmartReplace; 551 options |= ReplaceSelectionCommand::SmartReplace;
551 if (plainText) 552 if (plainText)
552 options |= ReplaceSelectionCommand::MatchStyle; 553 options |= ReplaceSelectionCommand::MatchStyle;
553 DCHECK(frame().document()); 554 DCHECK(frame().document());
554 ReplaceSelectionCommand::create(*frame().document(), fragment, options, Inpu tEvent::InputType::Drag)->apply(); 555 ReplaceSelectionCommand::create(*frame().document(), fragment, options, Inpu tEvent::InputType::InsertFromDrop)->apply();
555 } 556 }
556 557
557 void Editor::moveSelectionAfterDragging(DocumentFragment* fragment, const Positi on& pos, bool smartInsert, bool smartDelete) 558 bool Editor::deleteSelectionAfterDraggingWithEvents(Element* dragSource, SmartDe lete smartDelete, const Position& referenceMovePosition)
558 { 559 {
559 MoveSelectionCommand::create(fragment, pos, smartInsert, smartDelete)->apply (); 560 if (!dragSource || !dragSource->isConnected())
561 return true;
562
563 // Dispatch 'beforeinput'.
564 const bool shouldDelete = dispatchBeforeInputEditorCommand(dragSource, Input Event::InputType::DeleteByDrag, nullptr) == DispatchEventResult::NotCanceled;
565
566 // 'beforeinput' event handler may destroy frame, return false to cancel rem aining actions;
567 if (m_frame->document()->frame() != m_frame)
568 return false;
569
570 if (shouldDelete && dragSource->isConnected())
571 deleteSelectionWithSmartDelete(smartDelete == SmartDelete::Yes, InputEve nt::InputType::DeleteByDrag, referenceMovePosition);
572
573 return true;
574 }
575
576 bool Editor::replaceSelectionAfterDraggingWithEvents(Element* dropTarget, DragDa ta* dragData, DocumentFragment* fragment, Range* dropCaretRange, SmartInsert sma rtInsert, ChosePlainText chosePlainText)
577 {
578 if (!dropTarget || !dropTarget->isConnected())
579 return true;
580
581 // Dispatch 'beforeinput'.
582 DataTransfer* dataTransfer = DataTransfer::create(DataTransfer::DragAndDrop, DataTransferReadable, dragData->platformData());
583 dataTransfer->setSourceOperation(dragData->draggingSourceOperationMask());
584 const bool shouldInsert = dispatchBeforeInputDataTransfer(dropTarget, InputE vent::InputType::InsertFromDrop, dataTransfer, nullptr) == DispatchEventResult:: NotCanceled;
585
586 // 'beforeinput' event handler may destroy frame, return false to cancel rem aining actions;
587 if (m_frame->document()->frame() != m_frame)
588 return false;
589
590 if (shouldInsert && dropTarget->isConnected())
591 replaceSelectionAfterDragging(fragment, smartInsert == SmartInsert::Yes, chosePlainText == ChosePlainText::Yes);
592
593 return true;
560 } 594 }
561 595
562 EphemeralRange Editor::selectedRange() 596 EphemeralRange Editor::selectedRange()
563 { 597 {
564 return frame().selection().selection().toNormalizedEphemeralRange(); 598 return frame().selection().selection().toNormalizedEphemeralRange();
565 } 599 }
566 600
567 bool Editor::canDeleteRange(const EphemeralRange& range) const 601 bool Editor::canDeleteRange(const EphemeralRange& range) const
568 { 602 {
569 if (range.isCollapsed()) 603 if (range.isCollapsed())
(...skipping 24 matching lines...) Expand all
594 spellChecker().updateMarkersForWordsAffectedByEditing(true); 628 spellChecker().updateMarkersForWordsAffectedByEditing(true);
595 client().respondToChangedContents(); 629 client().respondToChangedContents();
596 } 630 }
597 631
598 void Editor::removeFormattingAndStyle() 632 void Editor::removeFormattingAndStyle()
599 { 633 {
600 DCHECK(frame().document()); 634 DCHECK(frame().document());
601 RemoveFormatCommand::create(*frame().document())->apply(); 635 RemoveFormatCommand::create(*frame().document())->apply();
602 } 636 }
603 637
638 void Editor::registerCommandGroup(CompositeEditCommand* commandGroupWrapper)
639 {
640 DCHECK(commandGroupWrapper->isCommandGroupWrapper());
641 m_lastEditCommand = commandGroupWrapper;
642 }
643
604 void Editor::clearLastEditCommand() 644 void Editor::clearLastEditCommand()
605 { 645 {
606 m_lastEditCommand.clear(); 646 m_lastEditCommand.clear();
607 } 647 }
608 648
609 Element* Editor::findEventTargetFrom(const VisibleSelection& selection) const 649 Element* Editor::findEventTargetFrom(const VisibleSelection& selection) const
610 { 650 {
611 Element* target = associatedElementOf(selection.start()); 651 Element* target = associatedElementOf(selection.start());
612 if (!target) 652 if (!target)
613 target = frame().document()->body(); 653 target = frame().document()->body();
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 static void dispatchEditableContentChangedEvents(Element* startRoot, Element* en dRoot) 730 static void dispatchEditableContentChangedEvents(Element* startRoot, Element* en dRoot)
691 { 731 {
692 if (startRoot) 732 if (startRoot)
693 startRoot->dispatchEvent(Event::create(EventTypeNames::webkitEditableCon tentChanged)); 733 startRoot->dispatchEvent(Event::create(EventTypeNames::webkitEditableCon tentChanged));
694 if (endRoot && endRoot != startRoot) 734 if (endRoot && endRoot != startRoot)
695 endRoot->dispatchEvent(Event::create(EventTypeNames::webkitEditableConte ntChanged)); 735 endRoot->dispatchEvent(Event::create(EventTypeNames::webkitEditableConte ntChanged));
696 } 736 }
697 737
698 void Editor::appliedEditing(CompositeEditCommand* cmd) 738 void Editor::appliedEditing(CompositeEditCommand* cmd)
699 { 739 {
740 DCHECK(!cmd->isCommandGroupWrapper());
700 EventQueueScope scope; 741 EventQueueScope scope;
701 frame().document()->updateStyleAndLayout(); 742 frame().document()->updateStyleAndLayout();
702 743
703 // Request spell checking before any further DOM change. 744 // Request spell checking before any further DOM change.
704 spellChecker().markMisspellingsAfterApplyingCommand(*cmd); 745 spellChecker().markMisspellingsAfterApplyingCommand(*cmd);
705 746
706 EditCommandComposition* composition = cmd->composition(); 747 EditCommandComposition* composition = cmd->composition();
707 DCHECK(composition); 748 DCHECK(composition);
708 dispatchEditableContentChangedEvents(composition->startingRootEditableElemen t(), composition->endingRootEditableElement()); 749 dispatchEditableContentChangedEvents(composition->startingRootEditableElemen t(), composition->endingRootEditableElement());
709 // TODO(chongz): Filter empty InputType after spec is finalized. 750 // TODO(chongz): Filter empty InputType after spec is finalized.
710 dispatchInputEventEditableContentChanged(composition->startingRootEditableEl ement(), composition->endingRootEditableElement(), cmd->inputType(), cmd->textDa taForInputEvent(), isComposingFromCommand(cmd)); 751 dispatchInputEventEditableContentChanged(composition->startingRootEditableEl ement(), composition->endingRootEditableElement(), cmd->inputType(), cmd->textDa taForInputEvent(), isComposingFromCommand(cmd));
711 VisibleSelection newSelection(cmd->endingSelection()); 752 VisibleSelection newSelection(cmd->endingSelection());
712 753
713 // Don't clear the typing style with this selection change. We do those thin gs elsewhere if necessary. 754 // Don't clear the typing style with this selection change. We do those thin gs elsewhere if necessary.
714 changeSelectionAfterCommand(newSelection, 0); 755 changeSelectionAfterCommand(newSelection, 0);
715 756
716 if (!cmd->preservesTypingStyle()) 757 if (!cmd->preservesTypingStyle())
717 frame().selection().clearTypingStyle(); 758 frame().selection().clearTypingStyle();
718 759
719 // Command will be equal to last edit command only in the case of typing 760 // Command will be equal to last edit command only in the case of typing
720 if (m_lastEditCommand.get() == cmd) { 761 if (m_lastEditCommand.get() == cmd) {
721 DCHECK(cmd->isTypingCommand()); 762 DCHECK(cmd->isTypingCommand());
763 } else if (m_lastEditCommand && m_lastEditCommand->isDragAndDropCommand() && (cmd->inputType() == InputEvent::InputType::DeleteByDrag || cmd->inputType() == InputEvent::InputType::InsertFromDrop)) {
764 // Only register undo entry when combined with other commands.
765 if (!m_lastEditCommand->composition())
766 m_undoStack->registerUndoStep(m_lastEditCommand->ensureComposition() );
767 m_lastEditCommand->appendCommandToComposite(cmd);
722 } else { 768 } else {
723 // Only register a new undo command if the command passed in is 769 // Only register a new undo command if the command passed in is
724 // different from the last command 770 // different from the last command
725 m_lastEditCommand = cmd; 771 m_lastEditCommand = cmd;
726 m_undoStack->registerUndoStep(m_lastEditCommand->ensureComposition()); 772 m_undoStack->registerUndoStep(m_lastEditCommand->ensureComposition());
727 } 773 }
728 774
729 respondToChangedContents(newSelection); 775 respondToChangedContents(newSelection);
730 } 776 }
731 777
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after
1417 1463
1418 DEFINE_TRACE(Editor) 1464 DEFINE_TRACE(Editor)
1419 { 1465 {
1420 visitor->trace(m_frame); 1466 visitor->trace(m_frame);
1421 visitor->trace(m_lastEditCommand); 1467 visitor->trace(m_lastEditCommand);
1422 visitor->trace(m_undoStack); 1468 visitor->trace(m_undoStack);
1423 visitor->trace(m_mark); 1469 visitor->trace(m_mark);
1424 } 1470 }
1425 1471
1426 } // namespace blink 1472 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698