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

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: 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 if (!isHTMLTableRowElement(row)) 56 if (!isHTMLTableRowElement(row))
57 return false; 57 return false;
58 58
59 for (Node* child = row->firstChild(); child; child = child->nextSibling()) { 59 for (Node* child = row->firstChild(); child; child = child->nextSibling()) {
60 if (isTableCell(child) && !isTableCellEmpty(child)) 60 if (isTableCell(child) && !isTableCellEmpty(child))
61 return false; 61 return false;
62 } 62 }
63 return true; 63 return true;
64 } 64 }
65 65
66 DeleteSelectionCommand::DeleteSelectionCommand(Document& document, bool smartDel ete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool sanitizeMa rkup, InputEvent::InputType inputType) 66 DeleteSelectionCommand::DeleteSelectionCommand(Document& document, bool smartDel ete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool sanitizeMa rkup, InputEvent::InputType inputType, const Position& referenceMovePosition)
67 : CompositeEditCommand(document) 67 : CompositeEditCommand(document)
68 , m_hasSelectionToDelete(false) 68 , m_hasSelectionToDelete(false)
69 , m_smartDelete(smartDelete) 69 , m_smartDelete(smartDelete)
70 , m_mergeBlocksAfterDelete(mergeBlocksAfterDelete) 70 , m_mergeBlocksAfterDelete(mergeBlocksAfterDelete)
71 , m_needPlaceholder(false) 71 , m_needPlaceholder(false)
72 , m_expandForSpecialElements(expandForSpecialElements) 72 , m_expandForSpecialElements(expandForSpecialElements)
73 , m_pruneStartBlockIfNecessary(false) 73 , m_pruneStartBlockIfNecessary(false)
74 , m_startsAtEmptyLine(false) 74 , m_startsAtEmptyLine(false)
75 , m_sanitizeMarkup(sanitizeMarkup) 75 , m_sanitizeMarkup(sanitizeMarkup)
76 , m_inputType(inputType) 76 , m_inputType(inputType)
77 , m_referenceMovePosition(referenceMovePosition)
77 , m_startBlock(nullptr) 78 , m_startBlock(nullptr)
78 , m_endBlock(nullptr) 79 , m_endBlock(nullptr)
79 , m_typingStyle(nullptr) 80 , m_typingStyle(nullptr)
80 , m_deleteIntoBlockquoteStyle(nullptr) 81 , m_deleteIntoBlockquoteStyle(nullptr)
81 { 82 {
82 } 83 }
83 84
84 DeleteSelectionCommand::DeleteSelectionCommand(const VisibleSelection& selection , bool smartDelete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool sanitizeMarkup, InputEvent::InputType inputType) 85 DeleteSelectionCommand::DeleteSelectionCommand(const VisibleSelection& selection , bool smartDelete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool sanitizeMarkup, InputEvent::InputType inputType)
85 : CompositeEditCommand(*selection.start().document()) 86 : CompositeEditCommand(*selection.start().document())
86 , m_hasSelectionToDelete(true) 87 , m_hasSelectionToDelete(true)
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 void DeleteSelectionCommand::clearTransientState() 799 void DeleteSelectionCommand::clearTransientState()
799 { 800 {
800 m_selectionToDelete = VisibleSelection(); 801 m_selectionToDelete = VisibleSelection();
801 m_upstreamStart = Position(); 802 m_upstreamStart = Position();
802 m_downstreamStart = Position(); 803 m_downstreamStart = Position();
803 m_upstreamEnd = Position(); 804 m_upstreamEnd = Position();
804 m_downstreamEnd = Position(); 805 m_downstreamEnd = Position();
805 m_endingPosition = Position(); 806 m_endingPosition = Position();
806 m_leadingWhitespace = Position(); 807 m_leadingWhitespace = Position();
807 m_trailingWhitespace = Position(); 808 m_trailingWhitespace = Position();
809 m_referenceMovePosition = Position();
808 } 810 }
809 811
810 // This method removes div elements with no attributes that have only one child or no children at all. 812 // This method removes div elements with no attributes that have only one child or no children at all.
811 void DeleteSelectionCommand::removeRedundantBlocks(EditingState* editingState) 813 void DeleteSelectionCommand::removeRedundantBlocks(EditingState* editingState)
812 { 814 {
813 Node* node = m_endingPosition.computeContainerNode(); 815 Node* node = m_endingPosition.computeContainerNode();
814 Element* rootElement = rootEditableElement(*node); 816 Element* rootElement = rootEditableElement(*node);
815 817
816 while (node != rootElement) { 818 while (node != rootElement) {
817 if (isRemovableBlock(node)) { 819 if (isRemovableBlock(node)) {
(...skipping 13 matching lines...) Expand all
831 void DeleteSelectionCommand::doApply(EditingState* editingState) 833 void DeleteSelectionCommand::doApply(EditingState* editingState)
832 { 834 {
833 // If selection has not been set to a custom selection when the command was created, 835 // If selection has not been set to a custom selection when the command was created,
834 // use the current ending selection. 836 // use the current ending selection.
835 if (!m_hasSelectionToDelete) 837 if (!m_hasSelectionToDelete)
836 m_selectionToDelete = endingSelection(); 838 m_selectionToDelete = endingSelection();
837 839
838 if (!m_selectionToDelete.isNonOrphanedRange() || !m_selectionToDelete.isCont entEditable()) 840 if (!m_selectionToDelete.isNonOrphanedRange() || !m_selectionToDelete.isCont entEditable())
839 return; 841 return;
840 842
843 if (!m_referenceMovePosition.isNull()) {
yosin_UTC9 2016/09/28 04:19:03 nit: s/!m_referenceMovePosition.isNull()/m_referen
chongz 2016/09/29 02:36:22 Done.
844 // Update the position otherwise it may become invalid after the selecti on is deleted.
yosin_UTC9 2016/09/28 04:19:03 Could you utilize |RelocatablePosition|?
chongz 2016/09/29 02:36:22 Done.
845 Position selectionEnd = endingSelection().end();
846 if (m_referenceMovePosition.isOffsetInAnchor() && selectionEnd.isOffsetI nAnchor()
847 && selectionEnd.computeContainerNode() == m_referenceMovePosition.co mputeContainerNode() && selectionEnd.offsetInContainerNode() < m_referenceMovePo sition.offsetInContainerNode()) {
848 m_referenceMovePosition = Position(m_referenceMovePosition.computeCo ntainerNode(), m_referenceMovePosition.offsetInContainerNode() - selectionEnd.of fsetInContainerNode());
849
850 Position selectionStart = endingSelection().start();
851 if (selectionStart.isOffsetInAnchor() && selectionStart.computeConta inerNode() == m_referenceMovePosition.computeContainerNode())
852 m_referenceMovePosition = Position(m_referenceMovePosition.compu teContainerNode(), m_referenceMovePosition.offsetInContainerNode() + selectionSt art.offsetInContainerNode());
853 }
854 }
855
841 // save this to later make the selection with 856 // save this to later make the selection with
842 TextAffinity affinity = m_selectionToDelete.affinity(); 857 TextAffinity affinity = m_selectionToDelete.affinity();
843 858
844 Position downstreamEnd = mostForwardCaretPosition(m_selectionToDelete.end()) ; 859 Position downstreamEnd = mostForwardCaretPosition(m_selectionToDelete.end()) ;
845 bool rootWillStayOpenWithoutPlaceholder = downstreamEnd.computeContainerNode () == rootEditableElement(*downstreamEnd.computeContainerNode()) 860 bool rootWillStayOpenWithoutPlaceholder = downstreamEnd.computeContainerNode () == rootEditableElement(*downstreamEnd.computeContainerNode())
846 || (downstreamEnd.computeContainerNode()->isTextNode() && downstreamEnd. computeContainerNode()->parentNode() == rootEditableElement(*downstreamEnd.compu teContainerNode())); 861 || (downstreamEnd.computeContainerNode()->isTextNode() && downstreamEnd. computeContainerNode()->parentNode() == rootEditableElement(*downstreamEnd.compu teContainerNode()));
847 bool lineBreakAtEndOfSelectionToDelete = lineBreakExistsAtVisiblePosition(m_ selectionToDelete.visibleEnd()); 862 bool lineBreakAtEndOfSelectionToDelete = lineBreakExistsAtVisiblePosition(m_ selectionToDelete.visibleEnd());
848 m_needPlaceholder = !rootWillStayOpenWithoutPlaceholder 863 m_needPlaceholder = !rootWillStayOpenWithoutPlaceholder
849 && isStartOfParagraph(m_selectionToDelete.visibleStart(), CanCrossEditin gBoundary) 864 && isStartOfParagraph(m_selectionToDelete.visibleStart(), CanCrossEditin gBoundary)
850 && isEndOfParagraph(m_selectionToDelete.visibleEnd(), CanCrossEditingBou ndary) 865 && isEndOfParagraph(m_selectionToDelete.visibleEnd(), CanCrossEditingBou ndary)
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 if (editingState->isAborted()) 936 if (editingState->isAborted())
922 return; 937 return;
923 } 938 }
924 } 939 }
925 940
926 rebalanceWhitespaceAt(m_endingPosition); 941 rebalanceWhitespaceAt(m_endingPosition);
927 942
928 calculateTypingStyleAfterDelete(); 943 calculateTypingStyleAfterDelete();
929 944
930 setEndingSelection(VisibleSelection(m_endingPosition, affinity, endingSelect ion().isDirectional())); 945 setEndingSelection(VisibleSelection(m_endingPosition, affinity, endingSelect ion().isDirectional()));
946
947 // This deletion command is part or a move operation.
948 if (!m_referenceMovePosition.isNull()) {
949 // If the node for the destination has been removed as a result of the d eletion,
950 // set the destination to the ending point after the deletion.
951 // Fixes: <rdar://problem/3910425> REGRESSION (Mail): Crash in ReplaceSe lectionCommand;
952 // selection is empty, leading to null deref
953 if (!m_referenceMovePosition.isConnected())
954 m_referenceMovePosition = endingSelection().start();
955
956 // Move selection shouldn't left empty <li> block.
957 cleanupAfterDeletion(editingState, createVisiblePositionDeprecated(m_ref erenceMovePosition));
958 if (editingState->isAborted())
959 return;
960 }
961
931 clearTransientState(); 962 clearTransientState();
932 } 963 }
933 964
934 InputEvent::InputType DeleteSelectionCommand::inputType() const 965 InputEvent::InputType DeleteSelectionCommand::inputType() const
935 { 966 {
936 // |DeleteSelectionCommand| could be used with Cut, Menu Bar deletion and |T ypingCommand|. 967 // |DeleteSelectionCommand| could be used with Cut, Menu Bar deletion and |T ypingCommand|.
937 // 1. Cut and Menu Bar deletion should rely on correct |m_inputType|. 968 // 1. Cut and Menu Bar deletion should rely on correct |m_inputType|.
938 // 2. |TypingCommand| will supply the |inputType()|, so |m_inputType| could default to |InputType::None|. 969 // 2. |TypingCommand| will supply the |inputType()|, so |m_inputType| could default to |InputType::None|.
939 return m_inputType; 970 return m_inputType;
940 } 971 }
941 972
942 // Normally deletion doesn't preserve the typing style that was present before i t. For example, 973 // Normally deletion doesn't preserve the typing style that was present before i t. For example,
943 // type a character, Bold, then delete the character and start typing. The Bold typing style shouldn't 974 // type a character, Bold, then delete the character and start typing. The Bold typing style shouldn't
944 // stick around. Deletion should preserve a typing style that *it* sets, howeve r. 975 // stick around. Deletion should preserve a typing style that *it* sets, howeve r.
945 bool DeleteSelectionCommand::preservesTypingStyle() const 976 bool DeleteSelectionCommand::preservesTypingStyle() const
946 { 977 {
947 return m_typingStyle; 978 return m_typingStyle;
948 } 979 }
949 980
950 DEFINE_TRACE(DeleteSelectionCommand) 981 DEFINE_TRACE(DeleteSelectionCommand)
951 { 982 {
952 visitor->trace(m_selectionToDelete); 983 visitor->trace(m_selectionToDelete);
953 visitor->trace(m_upstreamStart); 984 visitor->trace(m_upstreamStart);
954 visitor->trace(m_downstreamStart); 985 visitor->trace(m_downstreamStart);
955 visitor->trace(m_upstreamEnd); 986 visitor->trace(m_upstreamEnd);
956 visitor->trace(m_downstreamEnd); 987 visitor->trace(m_downstreamEnd);
957 visitor->trace(m_endingPosition); 988 visitor->trace(m_endingPosition);
958 visitor->trace(m_leadingWhitespace); 989 visitor->trace(m_leadingWhitespace);
959 visitor->trace(m_trailingWhitespace); 990 visitor->trace(m_trailingWhitespace);
991 visitor->trace(m_referenceMovePosition);
960 visitor->trace(m_startBlock); 992 visitor->trace(m_startBlock);
961 visitor->trace(m_endBlock); 993 visitor->trace(m_endBlock);
962 visitor->trace(m_typingStyle); 994 visitor->trace(m_typingStyle);
963 visitor->trace(m_deleteIntoBlockquoteStyle); 995 visitor->trace(m_deleteIntoBlockquoteStyle);
964 visitor->trace(m_startRoot); 996 visitor->trace(m_startRoot);
965 visitor->trace(m_endRoot); 997 visitor->trace(m_endRoot);
966 visitor->trace(m_startTableRow); 998 visitor->trace(m_startTableRow);
967 visitor->trace(m_endTableRow); 999 visitor->trace(m_endTableRow);
968 visitor->trace(m_temporaryPlaceholder); 1000 visitor->trace(m_temporaryPlaceholder);
969 CompositeEditCommand::trace(visitor); 1001 CompositeEditCommand::trace(visitor);
970 } 1002 }
971 1003
972 } // namespace blink 1004 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698