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

Side by Side Diff: third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.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) 2005 Apple Computer, Inc. All rights reserved. 2 * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 15 matching lines...) Expand all
26 #include "core/editing/commands/DeleteSelectionCommand.h" 26 #include "core/editing/commands/DeleteSelectionCommand.h"
27 27
28 #include "core/HTMLNames.h" 28 #include "core/HTMLNames.h"
29 #include "core/dom/Document.h" 29 #include "core/dom/Document.h"
30 #include "core/dom/Element.h" 30 #include "core/dom/Element.h"
31 #include "core/dom/NodeTraversal.h" 31 #include "core/dom/NodeTraversal.h"
32 #include "core/dom/Text.h" 32 #include "core/dom/Text.h"
33 #include "core/editing/EditingBoundary.h" 33 #include "core/editing/EditingBoundary.h"
34 #include "core/editing/EditingUtilities.h" 34 #include "core/editing/EditingUtilities.h"
35 #include "core/editing/Editor.h" 35 #include "core/editing/Editor.h"
36 #include "core/editing/RelocatablePosition.h"
36 #include "core/editing/VisibleUnits.h" 37 #include "core/editing/VisibleUnits.h"
37 #include "core/frame/LocalFrame.h" 38 #include "core/frame/LocalFrame.h"
38 #include "core/html/HTMLBRElement.h" 39 #include "core/html/HTMLBRElement.h"
39 #include "core/html/HTMLInputElement.h" 40 #include "core/html/HTMLInputElement.h"
40 #include "core/html/HTMLStyleElement.h" 41 #include "core/html/HTMLStyleElement.h"
41 #include "core/html/HTMLTableRowElement.h" 42 #include "core/html/HTMLTableRowElement.h"
42 #include "core/layout/LayoutTableCell.h" 43 #include "core/layout/LayoutTableCell.h"
43 44
44 namespace blink { 45 namespace blink {
45 46
(...skipping 10 matching lines...) Expand all
56 if (!isHTMLTableRowElement(row)) 57 if (!isHTMLTableRowElement(row))
57 return false; 58 return false;
58 59
59 for (Node* child = row->firstChild(); child; child = child->nextSibling()) { 60 for (Node* child = row->firstChild(); child; child = child->nextSibling()) {
60 if (isTableCell(child) && !isTableCellEmpty(child)) 61 if (isTableCell(child) && !isTableCellEmpty(child))
61 return false; 62 return false;
62 } 63 }
63 return true; 64 return true;
64 } 65 }
65 66
66 DeleteSelectionCommand::DeleteSelectionCommand(Document& document, bool smartDel ete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool sanitizeMa rkup, InputEvent::InputType inputType) 67 DeleteSelectionCommand::DeleteSelectionCommand(Document& document, bool smartDel ete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool sanitizeMa rkup, InputEvent::InputType inputType, const Position& referenceMovePosition)
67 : CompositeEditCommand(document) 68 : CompositeEditCommand(document)
68 , m_hasSelectionToDelete(false) 69 , m_hasSelectionToDelete(false)
69 , m_smartDelete(smartDelete) 70 , m_smartDelete(smartDelete)
70 , m_mergeBlocksAfterDelete(mergeBlocksAfterDelete) 71 , m_mergeBlocksAfterDelete(mergeBlocksAfterDelete)
71 , m_needPlaceholder(false) 72 , m_needPlaceholder(false)
72 , m_expandForSpecialElements(expandForSpecialElements) 73 , m_expandForSpecialElements(expandForSpecialElements)
73 , m_pruneStartBlockIfNecessary(false) 74 , m_pruneStartBlockIfNecessary(false)
74 , m_startsAtEmptyLine(false) 75 , m_startsAtEmptyLine(false)
75 , m_sanitizeMarkup(sanitizeMarkup) 76 , m_sanitizeMarkup(sanitizeMarkup)
76 , m_inputType(inputType) 77 , m_inputType(inputType)
78 , m_referenceMovePosition(referenceMovePosition)
77 , m_startBlock(nullptr) 79 , m_startBlock(nullptr)
78 , m_endBlock(nullptr) 80 , m_endBlock(nullptr)
79 , m_typingStyle(nullptr) 81 , m_typingStyle(nullptr)
80 , m_deleteIntoBlockquoteStyle(nullptr) 82 , m_deleteIntoBlockquoteStyle(nullptr)
81 { 83 {
82 } 84 }
83 85
84 DeleteSelectionCommand::DeleteSelectionCommand(const VisibleSelection& selection , bool smartDelete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool sanitizeMarkup, InputEvent::InputType inputType) 86 DeleteSelectionCommand::DeleteSelectionCommand(const VisibleSelection& selection , bool smartDelete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool sanitizeMarkup, InputEvent::InputType inputType)
85 : CompositeEditCommand(*selection.start().document()) 87 : CompositeEditCommand(*selection.start().document())
86 , m_hasSelectionToDelete(true) 88 , m_hasSelectionToDelete(true)
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 void DeleteSelectionCommand::clearTransientState() 803 void DeleteSelectionCommand::clearTransientState()
802 { 804 {
803 m_selectionToDelete = VisibleSelection(); 805 m_selectionToDelete = VisibleSelection();
804 m_upstreamStart = Position(); 806 m_upstreamStart = Position();
805 m_downstreamStart = Position(); 807 m_downstreamStart = Position();
806 m_upstreamEnd = Position(); 808 m_upstreamEnd = Position();
807 m_downstreamEnd = Position(); 809 m_downstreamEnd = Position();
808 m_endingPosition = Position(); 810 m_endingPosition = Position();
809 m_leadingWhitespace = Position(); 811 m_leadingWhitespace = Position();
810 m_trailingWhitespace = Position(); 812 m_trailingWhitespace = Position();
813 m_referenceMovePosition = Position();
811 } 814 }
812 815
813 // This method removes div elements with no attributes that have only one child or no children at all. 816 // This method removes div elements with no attributes that have only one child or no children at all.
814 void DeleteSelectionCommand::removeRedundantBlocks(EditingState* editingState) 817 void DeleteSelectionCommand::removeRedundantBlocks(EditingState* editingState)
815 { 818 {
816 Node* node = m_endingPosition.computeContainerNode(); 819 Node* node = m_endingPosition.computeContainerNode();
817 Element* rootElement = rootEditableElement(*node); 820 Element* rootElement = rootEditableElement(*node);
818 821
819 while (node != rootElement) { 822 while (node != rootElement) {
820 if (isRemovableBlock(node)) { 823 if (isRemovableBlock(node)) {
(...skipping 13 matching lines...) Expand all
834 void DeleteSelectionCommand::doApply(EditingState* editingState) 837 void DeleteSelectionCommand::doApply(EditingState* editingState)
835 { 838 {
836 // If selection has not been set to a custom selection when the command was created, 839 // If selection has not been set to a custom selection when the command was created,
837 // use the current ending selection. 840 // use the current ending selection.
838 if (!m_hasSelectionToDelete) 841 if (!m_hasSelectionToDelete)
839 m_selectionToDelete = endingSelection(); 842 m_selectionToDelete = endingSelection();
840 843
841 if (!m_selectionToDelete.isNonOrphanedRange() || !m_selectionToDelete.isCont entEditable()) 844 if (!m_selectionToDelete.isNonOrphanedRange() || !m_selectionToDelete.isCont entEditable())
842 return; 845 return;
843 846
847 RelocatablePosition relocatableReferencePosition(m_referenceMovePosition);
yosin_UTC9 2016/10/03 09:19:03 Good usage!
chongz 2016/10/04 02:18:39 Thanks!
848
844 // save this to later make the selection with 849 // save this to later make the selection with
845 TextAffinity affinity = m_selectionToDelete.affinity(); 850 TextAffinity affinity = m_selectionToDelete.affinity();
846 851
847 Position downstreamEnd = mostForwardCaretPosition(m_selectionToDelete.end()) ; 852 Position downstreamEnd = mostForwardCaretPosition(m_selectionToDelete.end()) ;
848 bool rootWillStayOpenWithoutPlaceholder = downstreamEnd.computeContainerNode () == rootEditableElement(*downstreamEnd.computeContainerNode()) 853 bool rootWillStayOpenWithoutPlaceholder = downstreamEnd.computeContainerNode () == rootEditableElement(*downstreamEnd.computeContainerNode())
849 || (downstreamEnd.computeContainerNode()->isTextNode() && downstreamEnd. computeContainerNode()->parentNode() == rootEditableElement(*downstreamEnd.compu teContainerNode())); 854 || (downstreamEnd.computeContainerNode()->isTextNode() && downstreamEnd. computeContainerNode()->parentNode() == rootEditableElement(*downstreamEnd.compu teContainerNode()));
850 bool lineBreakAtEndOfSelectionToDelete = lineBreakExistsAtVisiblePosition(m_ selectionToDelete.visibleEndDeprecated()); 855 bool lineBreakAtEndOfSelectionToDelete = lineBreakExistsAtVisiblePosition(m_ selectionToDelete.visibleEndDeprecated());
851 m_needPlaceholder = !rootWillStayOpenWithoutPlaceholder 856 m_needPlaceholder = !rootWillStayOpenWithoutPlaceholder
852 && isStartOfParagraphDeprecated(m_selectionToDelete.visibleStartDeprecat ed(), CanCrossEditingBoundary) 857 && isStartOfParagraphDeprecated(m_selectionToDelete.visibleStartDeprecat ed(), CanCrossEditingBoundary)
853 && isEndOfParagraphDeprecated(m_selectionToDelete.visibleEndDeprecated() , CanCrossEditingBoundary) 858 && isEndOfParagraphDeprecated(m_selectionToDelete.visibleEndDeprecated() , CanCrossEditingBoundary)
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 if (editingState->isAborted()) 929 if (editingState->isAborted())
925 return; 930 return;
926 } 931 }
927 } 932 }
928 933
929 rebalanceWhitespaceAt(m_endingPosition); 934 rebalanceWhitespaceAt(m_endingPosition);
930 935
931 calculateTypingStyleAfterDelete(); 936 calculateTypingStyleAfterDelete();
932 937
933 setEndingSelection(VisibleSelection(m_endingPosition, affinity, endingSelect ion().isDirectional())); 938 setEndingSelection(VisibleSelection(m_endingPosition, affinity, endingSelect ion().isDirectional()));
939
940 // This deletion command is part or a move operation.
941 if (relocatableReferencePosition.position().isNotNull()) {
yosin_UTC9 2016/10/03 09:19:03 Could you use early-return style? if (relocatable
chongz 2016/10/04 02:18:39 Done.
942 m_referenceMovePosition = relocatableReferencePosition.position();
943 // If the node for the destination has been removed as a result of the d eletion,
944 // set the destination to the ending point after the deletion.
945 // Fixes: <rdar://problem/3910425> REGRESSION (Mail): Crash in ReplaceSe lectionCommand;
946 // selection is empty, leading to null deref
947 if (!m_referenceMovePosition.isConnected())
948 m_referenceMovePosition = endingSelection().start();
949
950 // Move selection shouldn't left empty <li> block.
951 cleanupAfterDeletion(editingState, createVisiblePositionDeprecated(m_ref erenceMovePosition));
952 if (editingState->isAborted())
953 return;
954 }
955
934 clearTransientState(); 956 clearTransientState();
935 } 957 }
936 958
937 InputEvent::InputType DeleteSelectionCommand::inputType() const 959 InputEvent::InputType DeleteSelectionCommand::inputType() const
938 { 960 {
939 // |DeleteSelectionCommand| could be used with Cut, Menu Bar deletion and |T ypingCommand|. 961 // |DeleteSelectionCommand| could be used with Cut, Menu Bar deletion and |T ypingCommand|.
940 // 1. Cut and Menu Bar deletion should rely on correct |m_inputType|. 962 // 1. Cut and Menu Bar deletion should rely on correct |m_inputType|.
941 // 2. |TypingCommand| will supply the |inputType()|, so |m_inputType| could default to |InputType::None|. 963 // 2. |TypingCommand| will supply the |inputType()|, so |m_inputType| could default to |InputType::None|.
942 return m_inputType; 964 return m_inputType;
943 } 965 }
944 966
945 // Normally deletion doesn't preserve the typing style that was present before i t. For example, 967 // Normally deletion doesn't preserve the typing style that was present before i t. For example,
946 // type a character, Bold, then delete the character and start typing. The Bold typing style shouldn't 968 // type a character, Bold, then delete the character and start typing. The Bold typing style shouldn't
947 // stick around. Deletion should preserve a typing style that *it* sets, howeve r. 969 // stick around. Deletion should preserve a typing style that *it* sets, howeve r.
948 bool DeleteSelectionCommand::preservesTypingStyle() const 970 bool DeleteSelectionCommand::preservesTypingStyle() const
949 { 971 {
950 return m_typingStyle; 972 return m_typingStyle;
951 } 973 }
952 974
953 DEFINE_TRACE(DeleteSelectionCommand) 975 DEFINE_TRACE(DeleteSelectionCommand)
954 { 976 {
955 visitor->trace(m_selectionToDelete); 977 visitor->trace(m_selectionToDelete);
956 visitor->trace(m_upstreamStart); 978 visitor->trace(m_upstreamStart);
957 visitor->trace(m_downstreamStart); 979 visitor->trace(m_downstreamStart);
958 visitor->trace(m_upstreamEnd); 980 visitor->trace(m_upstreamEnd);
959 visitor->trace(m_downstreamEnd); 981 visitor->trace(m_downstreamEnd);
960 visitor->trace(m_endingPosition); 982 visitor->trace(m_endingPosition);
961 visitor->trace(m_leadingWhitespace); 983 visitor->trace(m_leadingWhitespace);
962 visitor->trace(m_trailingWhitespace); 984 visitor->trace(m_trailingWhitespace);
985 visitor->trace(m_referenceMovePosition);
963 visitor->trace(m_startBlock); 986 visitor->trace(m_startBlock);
964 visitor->trace(m_endBlock); 987 visitor->trace(m_endBlock);
965 visitor->trace(m_typingStyle); 988 visitor->trace(m_typingStyle);
966 visitor->trace(m_deleteIntoBlockquoteStyle); 989 visitor->trace(m_deleteIntoBlockquoteStyle);
967 visitor->trace(m_startRoot); 990 visitor->trace(m_startRoot);
968 visitor->trace(m_endRoot); 991 visitor->trace(m_endRoot);
969 visitor->trace(m_startTableRow); 992 visitor->trace(m_startTableRow);
970 visitor->trace(m_endTableRow); 993 visitor->trace(m_endTableRow);
971 visitor->trace(m_temporaryPlaceholder); 994 visitor->trace(m_temporaryPlaceholder);
972 CompositeEditCommand::trace(visitor); 995 CompositeEditCommand::trace(visitor);
973 } 996 }
974 997
975 } // namespace blink 998 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698