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

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 2 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
46 using namespace HTMLNames; 47 using namespace HTMLNames;
47 48
48 static bool isTableCellEmpty(Node* cell) { 49 static bool isTableCellEmpty(Node* cell) {
49 DCHECK(isTableCell(cell)) << cell; 50 DCHECK(isTableCell(cell)) << cell;
50 return VisiblePosition::firstPositionInNode(cell).deepEquivalent() == 51 return VisiblePosition::firstPositionInNode(cell).deepEquivalent() ==
51 VisiblePosition::lastPositionInNode(cell).deepEquivalent(); 52 VisiblePosition::lastPositionInNode(cell).deepEquivalent();
52 } 53 }
53 54
54 static bool isTableRowEmpty(Node* row) { 55 static bool isTableRowEmpty(Node* row) {
55 if (!isHTMLTableRowElement(row)) 56 if (!isHTMLTableRowElement(row))
56 return false; 57 return false;
57 58
58 for (Node* child = row->firstChild(); child; child = child->nextSibling()) { 59 for (Node* child = row->firstChild(); child; child = child->nextSibling()) {
59 if (isTableCell(child) && !isTableCellEmpty(child)) 60 if (isTableCell(child) && !isTableCellEmpty(child))
60 return false; 61 return false;
61 } 62 }
62 return true; 63 return true;
63 } 64 }
64 65
65 DeleteSelectionCommand::DeleteSelectionCommand(Document& document, 66 DeleteSelectionCommand::DeleteSelectionCommand(
66 bool smartDelete, 67 Document& document,
67 bool mergeBlocksAfterDelete, 68 bool smartDelete,
68 bool expandForSpecialElements, 69 bool mergeBlocksAfterDelete,
69 bool sanitizeMarkup, 70 bool expandForSpecialElements,
70 InputEvent::InputType inputType) 71 bool sanitizeMarkup,
72 InputEvent::InputType inputType,
73 const Position& referenceMovePosition)
71 : CompositeEditCommand(document), 74 : CompositeEditCommand(document),
72 m_hasSelectionToDelete(false), 75 m_hasSelectionToDelete(false),
73 m_smartDelete(smartDelete), 76 m_smartDelete(smartDelete),
74 m_mergeBlocksAfterDelete(mergeBlocksAfterDelete), 77 m_mergeBlocksAfterDelete(mergeBlocksAfterDelete),
75 m_needPlaceholder(false), 78 m_needPlaceholder(false),
76 m_expandForSpecialElements(expandForSpecialElements), 79 m_expandForSpecialElements(expandForSpecialElements),
77 m_pruneStartBlockIfNecessary(false), 80 m_pruneStartBlockIfNecessary(false),
78 m_startsAtEmptyLine(false), 81 m_startsAtEmptyLine(false),
79 m_sanitizeMarkup(sanitizeMarkup), 82 m_sanitizeMarkup(sanitizeMarkup),
80 m_inputType(inputType), 83 m_inputType(inputType),
84 m_referenceMovePosition(referenceMovePosition),
81 m_startBlock(nullptr), 85 m_startBlock(nullptr),
82 m_endBlock(nullptr), 86 m_endBlock(nullptr),
83 m_typingStyle(nullptr), 87 m_typingStyle(nullptr),
84 m_deleteIntoBlockquoteStyle(nullptr) {} 88 m_deleteIntoBlockquoteStyle(nullptr) {}
85 89
86 DeleteSelectionCommand::DeleteSelectionCommand( 90 DeleteSelectionCommand::DeleteSelectionCommand(
87 const VisibleSelection& selection, 91 const VisibleSelection& selection,
88 bool smartDelete, 92 bool smartDelete,
89 bool mergeBlocksAfterDelete, 93 bool mergeBlocksAfterDelete,
90 bool expandForSpecialElements, 94 bool expandForSpecialElements,
(...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 945
942 void DeleteSelectionCommand::clearTransientState() { 946 void DeleteSelectionCommand::clearTransientState() {
943 m_selectionToDelete = VisibleSelection(); 947 m_selectionToDelete = VisibleSelection();
944 m_upstreamStart = Position(); 948 m_upstreamStart = Position();
945 m_downstreamStart = Position(); 949 m_downstreamStart = Position();
946 m_upstreamEnd = Position(); 950 m_upstreamEnd = Position();
947 m_downstreamEnd = Position(); 951 m_downstreamEnd = Position();
948 m_endingPosition = Position(); 952 m_endingPosition = Position();
949 m_leadingWhitespace = Position(); 953 m_leadingWhitespace = Position();
950 m_trailingWhitespace = Position(); 954 m_trailingWhitespace = Position();
955 m_referenceMovePosition = Position();
951 } 956 }
952 957
953 // This method removes div elements with no attributes that have only one child or no children at all. 958 // This method removes div elements with no attributes that have only one child or no children at all.
954 void DeleteSelectionCommand::removeRedundantBlocks(EditingState* editingState) { 959 void DeleteSelectionCommand::removeRedundantBlocks(EditingState* editingState) {
955 Node* node = m_endingPosition.computeContainerNode(); 960 Node* node = m_endingPosition.computeContainerNode();
956 Element* rootElement = rootEditableElement(*node); 961 Element* rootElement = rootEditableElement(*node);
957 962
958 while (node != rootElement) { 963 while (node != rootElement) {
959 if (isRemovableBlock(node)) { 964 if (isRemovableBlock(node)) {
960 if (node == m_endingPosition.anchorNode()) 965 if (node == m_endingPosition.anchorNode())
(...skipping 12 matching lines...) Expand all
973 void DeleteSelectionCommand::doApply(EditingState* editingState) { 978 void DeleteSelectionCommand::doApply(EditingState* editingState) {
974 // If selection has not been set to a custom selection when the command was cr eated, 979 // If selection has not been set to a custom selection when the command was cr eated,
975 // use the current ending selection. 980 // use the current ending selection.
976 if (!m_hasSelectionToDelete) 981 if (!m_hasSelectionToDelete)
977 m_selectionToDelete = endingSelection(); 982 m_selectionToDelete = endingSelection();
978 983
979 if (!m_selectionToDelete.isNonOrphanedRange() || 984 if (!m_selectionToDelete.isNonOrphanedRange() ||
980 !m_selectionToDelete.isContentEditable()) 985 !m_selectionToDelete.isContentEditable())
981 return; 986 return;
982 987
988 RelocatablePosition relocatableReferencePosition(m_referenceMovePosition);
989
983 // save this to later make the selection with 990 // save this to later make the selection with
984 TextAffinity affinity = m_selectionToDelete.affinity(); 991 TextAffinity affinity = m_selectionToDelete.affinity();
985 992
986 Position downstreamEnd = mostForwardCaretPosition(m_selectionToDelete.end()); 993 Position downstreamEnd = mostForwardCaretPosition(m_selectionToDelete.end());
987 bool rootWillStayOpenWithoutPlaceholder = 994 bool rootWillStayOpenWithoutPlaceholder =
988 downstreamEnd.computeContainerNode() == 995 downstreamEnd.computeContainerNode() ==
989 rootEditableElement(*downstreamEnd.computeContainerNode()) || 996 rootEditableElement(*downstreamEnd.computeContainerNode()) ||
990 (downstreamEnd.computeContainerNode()->isTextNode() && 997 (downstreamEnd.computeContainerNode()->isTextNode() &&
991 downstreamEnd.computeContainerNode()->parentNode() == 998 downstreamEnd.computeContainerNode()->parentNode() ==
992 rootEditableElement(*downstreamEnd.computeContainerNode())); 999 rootEditableElement(*downstreamEnd.computeContainerNode()));
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1079 return; 1086 return;
1080 } 1087 }
1081 } 1088 }
1082 1089
1083 rebalanceWhitespaceAt(m_endingPosition); 1090 rebalanceWhitespaceAt(m_endingPosition);
1084 1091
1085 calculateTypingStyleAfterDelete(); 1092 calculateTypingStyleAfterDelete();
1086 1093
1087 setEndingSelection(createVisibleSelectionDeprecated( 1094 setEndingSelection(createVisibleSelectionDeprecated(
1088 m_endingPosition, affinity, endingSelection().isDirectional())); 1095 m_endingPosition, affinity, endingSelection().isDirectional()));
1096
1097 if (relocatableReferencePosition.position().isNull()) {
1098 clearTransientState();
1099 return;
1100 }
1101
1102 // This deletion command is part of a move operation, we need to cleanup after deletion.
1103 m_referenceMovePosition = relocatableReferencePosition.position();
1104 // If the node for the destination has been removed as a result of the deletio n,
1105 // set the destination to the ending point after the deletion.
1106 // Fixes: <rdar://problem/3910425> REGRESSION (Mail): Crash in ReplaceSelectio nCommand;
1107 // selection is empty, leading to null deref
1108 if (!m_referenceMovePosition.isConnected())
1109 m_referenceMovePosition = endingSelection().start();
1110
1111 // Move selection shouldn't left empty <li> block.
1112 cleanupAfterDeletion(
1113 editingState, createVisiblePositionDeprecated(m_referenceMovePosition));
1114 if (editingState->isAborted())
1115 return;
1116
1089 clearTransientState(); 1117 clearTransientState();
1090 } 1118 }
1091 1119
1092 InputEvent::InputType DeleteSelectionCommand::inputType() const { 1120 InputEvent::InputType DeleteSelectionCommand::inputType() const {
1093 // |DeleteSelectionCommand| could be used with Cut, Menu Bar deletion and |Typ ingCommand|. 1121 // |DeleteSelectionCommand| could be used with Cut, Menu Bar deletion and |Typ ingCommand|.
1094 // 1. Cut and Menu Bar deletion should rely on correct |m_inputType|. 1122 // 1. Cut and Menu Bar deletion should rely on correct |m_inputType|.
1095 // 2. |TypingCommand| will supply the |inputType()|, so |m_inputType| could de fault to |InputType::None|. 1123 // 2. |TypingCommand| will supply the |inputType()|, so |m_inputType| could de fault to |InputType::None|.
1096 return m_inputType; 1124 return m_inputType;
1097 } 1125 }
1098 1126
1099 // Normally deletion doesn't preserve the typing style that was present before i t. For example, 1127 // Normally deletion doesn't preserve the typing style that was present before i t. For example,
1100 // type a character, Bold, then delete the character and start typing. The Bold typing style shouldn't 1128 // type a character, Bold, then delete the character and start typing. The Bold typing style shouldn't
1101 // stick around. Deletion should preserve a typing style that *it* sets, howeve r. 1129 // stick around. Deletion should preserve a typing style that *it* sets, howeve r.
1102 bool DeleteSelectionCommand::preservesTypingStyle() const { 1130 bool DeleteSelectionCommand::preservesTypingStyle() const {
1103 return m_typingStyle; 1131 return m_typingStyle;
1104 } 1132 }
1105 1133
1106 DEFINE_TRACE(DeleteSelectionCommand) { 1134 DEFINE_TRACE(DeleteSelectionCommand) {
1107 visitor->trace(m_selectionToDelete); 1135 visitor->trace(m_selectionToDelete);
1108 visitor->trace(m_upstreamStart); 1136 visitor->trace(m_upstreamStart);
1109 visitor->trace(m_downstreamStart); 1137 visitor->trace(m_downstreamStart);
1110 visitor->trace(m_upstreamEnd); 1138 visitor->trace(m_upstreamEnd);
1111 visitor->trace(m_downstreamEnd); 1139 visitor->trace(m_downstreamEnd);
1112 visitor->trace(m_endingPosition); 1140 visitor->trace(m_endingPosition);
1113 visitor->trace(m_leadingWhitespace); 1141 visitor->trace(m_leadingWhitespace);
1114 visitor->trace(m_trailingWhitespace); 1142 visitor->trace(m_trailingWhitespace);
1143 visitor->trace(m_referenceMovePosition);
1115 visitor->trace(m_startBlock); 1144 visitor->trace(m_startBlock);
1116 visitor->trace(m_endBlock); 1145 visitor->trace(m_endBlock);
1117 visitor->trace(m_typingStyle); 1146 visitor->trace(m_typingStyle);
1118 visitor->trace(m_deleteIntoBlockquoteStyle); 1147 visitor->trace(m_deleteIntoBlockquoteStyle);
1119 visitor->trace(m_startRoot); 1148 visitor->trace(m_startRoot);
1120 visitor->trace(m_endRoot); 1149 visitor->trace(m_endRoot);
1121 visitor->trace(m_startTableRow); 1150 visitor->trace(m_startTableRow);
1122 visitor->trace(m_endTableRow); 1151 visitor->trace(m_endTableRow);
1123 visitor->trace(m_temporaryPlaceholder); 1152 visitor->trace(m_temporaryPlaceholder);
1124 CompositeEditCommand::trace(visitor); 1153 CompositeEditCommand::trace(visitor);
1125 } 1154 }
1126 1155
1127 } // namespace blink 1156 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698