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

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

Issue 2399793002: Prune deprecated functions from DeleteSelectionCommand (Closed)
Patch Set: Rebased 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 m_sanitizeMarkup(sanitizeMarkup), 105 m_sanitizeMarkup(sanitizeMarkup),
106 m_inputType(inputType), 106 m_inputType(inputType),
107 m_selectionToDelete(selection), 107 m_selectionToDelete(selection),
108 m_startBlock(nullptr), 108 m_startBlock(nullptr),
109 m_endBlock(nullptr), 109 m_endBlock(nullptr),
110 m_typingStyle(nullptr), 110 m_typingStyle(nullptr),
111 m_deleteIntoBlockquoteStyle(nullptr) {} 111 m_deleteIntoBlockquoteStyle(nullptr) {}
112 112
113 void DeleteSelectionCommand::initializeStartEnd(Position& start, 113 void DeleteSelectionCommand::initializeStartEnd(Position& start,
114 Position& end) { 114 Position& end) {
115 DCHECK(!document().needsLayoutTreeUpdate());
116 DocumentLifecycle::DisallowTransitionScope disallowTransition(
117 document().lifecycle());
118
115 HTMLElement* startSpecialContainer = nullptr; 119 HTMLElement* startSpecialContainer = nullptr;
116 HTMLElement* endSpecialContainer = nullptr; 120 HTMLElement* endSpecialContainer = nullptr;
117 121
118 start = m_selectionToDelete.start(); 122 start = m_selectionToDelete.start();
119 end = m_selectionToDelete.end(); 123 end = m_selectionToDelete.end();
120 124
121 // For HRs, we'll get a position at (HR,1) when hitting delete from the 125 // For HRs, we'll get a position at (HR,1) when hitting delete from the
122 // beginning of the previous line, or (HR,0) when forward deleting, but in 126 // beginning of the previous line, or (HR,0) when forward deleting, but in
123 // these cases, we want to delete it, so manually expand the selection 127 // these cases, we want to delete it, so manually expand the selection
124 if (isHTMLHRElement(*start.anchorNode())) 128 if (isHTMLHRElement(*start.anchorNode()))
(...skipping 11 matching lines...) Expand all
136 endSpecialContainer = 0; 140 endSpecialContainer = 0;
137 141
138 Position s = 142 Position s =
139 positionBeforeContainingSpecialElement(start, &startSpecialContainer); 143 positionBeforeContainingSpecialElement(start, &startSpecialContainer);
140 Position e = 144 Position e =
141 positionAfterContainingSpecialElement(end, &endSpecialContainer); 145 positionAfterContainingSpecialElement(end, &endSpecialContainer);
142 146
143 if (!startSpecialContainer && !endSpecialContainer) 147 if (!startSpecialContainer && !endSpecialContainer)
144 break; 148 break;
145 149
146 if (createVisiblePositionDeprecated(start).deepEquivalent() != 150 if (createVisiblePosition(start).deepEquivalent() !=
147 m_selectionToDelete.visibleStartDeprecated().deepEquivalent() || 151 m_selectionToDelete.visibleStart().deepEquivalent() ||
148 createVisiblePositionDeprecated(end).deepEquivalent() != 152 createVisiblePosition(end).deepEquivalent() !=
149 m_selectionToDelete.visibleEndDeprecated().deepEquivalent()) 153 m_selectionToDelete.visibleEnd().deepEquivalent())
150 break; 154 break;
151 155
152 // If we're going to expand to include the startSpecialContainer, it must be 156 // If we're going to expand to include the startSpecialContainer, it must be
153 // fully selected. 157 // fully selected.
154 if (startSpecialContainer && !endSpecialContainer && 158 if (startSpecialContainer && !endSpecialContainer &&
155 comparePositions(Position::inParentAfterNode(*startSpecialContainer), 159 comparePositions(Position::inParentAfterNode(*startSpecialContainer),
156 end) > -1) 160 end) > -1)
157 break; 161 break;
158 162
159 // If we're going to expand to include the endSpecialContainer, it must be 163 // If we're going to expand to include the endSpecialContainer, it must be
(...skipping 18 matching lines...) Expand all
178 } else { 182 } else {
179 start = s; 183 start = s;
180 end = e; 184 end = e;
181 } 185 }
182 } 186 }
183 } 187 }
184 188
185 void DeleteSelectionCommand::setStartingSelectionOnSmartDelete( 189 void DeleteSelectionCommand::setStartingSelectionOnSmartDelete(
186 const Position& start, 190 const Position& start,
187 const Position& end) { 191 const Position& end) {
192 DCHECK(!document().needsLayoutTreeUpdate());
193 DocumentLifecycle::DisallowTransitionScope disallowTransition(
194 document().lifecycle());
195
188 bool isBaseFirst = startingSelection().isBaseFirst(); 196 bool isBaseFirst = startingSelection().isBaseFirst();
189 VisiblePosition newBase = 197 VisiblePosition newBase = createVisiblePosition(isBaseFirst ? start : end);
190 createVisiblePositionDeprecated(isBaseFirst ? start : end); 198 VisiblePosition newExtent = createVisiblePosition(isBaseFirst ? end : start);
191 VisiblePosition newExtent = 199 setStartingSelection(createVisibleSelection(
192 createVisiblePositionDeprecated(isBaseFirst ? end : start);
193 setStartingSelection(createVisibleSelectionDeprecated(
194 newBase, newExtent, startingSelection().isDirectional())); 200 newBase, newExtent, startingSelection().isDirectional()));
195 } 201 }
196 202
197 void DeleteSelectionCommand::initializePositionData( 203 void DeleteSelectionCommand::initializePositionData(
198 EditingState* editingState) { 204 EditingState* editingState) {
205 DCHECK(!document().needsLayoutTreeUpdate());
206 DocumentLifecycle::DisallowTransitionScope disallowTransition(
207 document().lifecycle());
208
199 Position start, end; 209 Position start, end;
200 initializeStartEnd(start, end); 210 initializeStartEnd(start, end);
201 DCHECK(start.isNotNull()); 211 DCHECK(start.isNotNull());
202 DCHECK(end.isNotNull()); 212 DCHECK(end.isNotNull());
203 if (!isEditablePosition(start)) { 213 if (!isEditablePosition(start)) {
204 editingState->abort(); 214 editingState->abort();
205 return; 215 return;
206 } 216 }
207 if (!isEditablePosition(end)) { 217 if (!isEditablePosition(end)) {
208 Node* highestRoot = highestEditableRoot(start); 218 Node* highestRoot = highestEditableRoot(start);
(...skipping 24 matching lines...) Expand all
233 CanCrossEditingBoundary); 243 CanCrossEditingBoundary);
234 // FIXME: This isn't right. A borderless table with two rows and a single 244 // FIXME: This isn't right. A borderless table with two rows and a single
235 // column would appear as two paragraphs. 245 // column would appear as two paragraphs.
236 if (endCell && endCell != startCell) 246 if (endCell && endCell != startCell)
237 m_mergeBlocksAfterDelete = false; 247 m_mergeBlocksAfterDelete = false;
238 248
239 // Usually the start and the end of the selection to delete are pulled 249 // Usually the start and the end of the selection to delete are pulled
240 // together as a result of the deletion. Sometimes they aren't (like when no 250 // together as a result of the deletion. Sometimes they aren't (like when no
241 // merge is requested), so we must choose one position to hold the caret 251 // merge is requested), so we must choose one position to hold the caret
242 // and receive the placeholder after deletion. 252 // and receive the placeholder after deletion.
243 VisiblePosition visibleEnd = createVisiblePositionDeprecated(m_downstreamEnd); 253 VisiblePosition visibleEnd = createVisiblePosition(m_downstreamEnd);
244 if (m_mergeBlocksAfterDelete && !isEndOfParagraphDeprecated(visibleEnd)) 254 if (m_mergeBlocksAfterDelete && !isEndOfParagraph(visibleEnd))
245 m_endingPosition = m_downstreamEnd; 255 m_endingPosition = m_downstreamEnd;
246 else 256 else
247 m_endingPosition = m_downstreamStart; 257 m_endingPosition = m_downstreamStart;
248 258
249 // We don't want to merge into a block if it will mean changing the quote 259 // We don't want to merge into a block if it will mean changing the quote
250 // level of content after deleting selections that contain a whole number 260 // level of content after deleting selections that contain a whole number
251 // paragraphs plus a line break, since it is unclear to most users that such a 261 // paragraphs plus a line break, since it is unclear to most users that such a
252 // selection actually ends at the start of the next paragraph. This matches 262 // selection actually ends at the start of the next paragraph. This matches
253 // TextEdit behavior for indented paragraphs. 263 // TextEdit behavior for indented paragraphs.
254 // Only apply this rule if the endingSelection is a range selection. If it is 264 // Only apply this rule if the endingSelection is a range selection. If it is
255 // a caret, then other operations have created the selection we're deleting 265 // a caret, then other operations have created the selection we're deleting
256 // (like the process of creating a selection to delete during a backspace), 266 // (like the process of creating a selection to delete during a backspace),
257 // and the user isn't in the situation described above. 267 // and the user isn't in the situation described above.
258 if (numEnclosingMailBlockquotes(start) != numEnclosingMailBlockquotes(end) && 268 if (numEnclosingMailBlockquotes(start) != numEnclosingMailBlockquotes(end) &&
259 isStartOfParagraphDeprecated(visibleEnd) && 269 isStartOfParagraph(visibleEnd) &&
260 isStartOfParagraph(createVisiblePositionDeprecated(start)) && 270 isStartOfParagraph(createVisiblePosition(start)) &&
261 endingSelection().isRange()) { 271 endingSelection().isRange()) {
262 m_mergeBlocksAfterDelete = false; 272 m_mergeBlocksAfterDelete = false;
263 m_pruneStartBlockIfNecessary = true; 273 m_pruneStartBlockIfNecessary = true;
264 } 274 }
265 275
266 // Handle leading and trailing whitespace, as well as smart delete adjustments 276 // Handle leading and trailing whitespace, as well as smart delete adjustments
267 // to the selection 277 // to the selection
268 m_leadingWhitespace = leadingWhitespacePosition( 278 m_leadingWhitespace = leadingWhitespacePosition(
269 m_upstreamStart, m_selectionToDelete.affinity()); 279 m_upstreamStart, m_selectionToDelete.affinity());
270 m_trailingWhitespace = 280 m_trailingWhitespace =
271 trailingWhitespacePosition(m_downstreamEnd, VP_DEFAULT_AFFINITY); 281 trailingWhitespacePosition(m_downstreamEnd, VP_DEFAULT_AFFINITY);
272 282
273 if (m_smartDelete) { 283 if (m_smartDelete) {
274 // skip smart delete if the selection to delete already starts or ends with 284 // skip smart delete if the selection to delete already starts or ends with
275 // whitespace 285 // whitespace
276 Position pos = createVisiblePositionDeprecated( 286 Position pos =
277 m_upstreamStart, m_selectionToDelete.affinity()) 287 createVisiblePosition(m_upstreamStart, m_selectionToDelete.affinity())
278 .deepEquivalent(); 288 .deepEquivalent();
279 bool skipSmartDelete = 289 bool skipSmartDelete =
280 trailingWhitespacePosition(pos, VP_DEFAULT_AFFINITY, 290 trailingWhitespacePosition(pos, VP_DEFAULT_AFFINITY,
281 ConsiderNonCollapsibleWhitespace) 291 ConsiderNonCollapsibleWhitespace)
282 .isNotNull(); 292 .isNotNull();
283 if (!skipSmartDelete) 293 if (!skipSmartDelete)
284 skipSmartDelete = 294 skipSmartDelete =
285 leadingWhitespacePosition(m_downstreamEnd, VP_DEFAULT_AFFINITY, 295 leadingWhitespacePosition(m_downstreamEnd, VP_DEFAULT_AFFINITY,
286 ConsiderNonCollapsibleWhitespace) 296 ConsiderNonCollapsibleWhitespace)
287 .isNotNull(); 297 .isNotNull();
288 298
289 // extend selection upstream if there is whitespace there 299 // extend selection upstream if there is whitespace there
290 bool hasLeadingWhitespaceBeforeAdjustment = 300 bool hasLeadingWhitespaceBeforeAdjustment =
291 leadingWhitespacePosition(m_upstreamStart, 301 leadingWhitespacePosition(m_upstreamStart,
292 m_selectionToDelete.affinity(), 302 m_selectionToDelete.affinity(),
293 ConsiderNonCollapsibleWhitespace) 303 ConsiderNonCollapsibleWhitespace)
294 .isNotNull(); 304 .isNotNull();
295 if (!skipSmartDelete && hasLeadingWhitespaceBeforeAdjustment) { 305 if (!skipSmartDelete && hasLeadingWhitespaceBeforeAdjustment) {
296 VisiblePosition visiblePos = 306 VisiblePosition visiblePos = previousPositionOf(
297 previousPositionOf(createVisiblePositionDeprecated( 307 createVisiblePosition(m_upstreamStart, VP_DEFAULT_AFFINITY));
298 m_upstreamStart, VP_DEFAULT_AFFINITY));
299 pos = visiblePos.deepEquivalent(); 308 pos = visiblePos.deepEquivalent();
300 // Expand out one character upstream for smart delete and recalculate 309 // Expand out one character upstream for smart delete and recalculate
301 // positions based on this change. 310 // positions based on this change.
302 m_upstreamStart = mostBackwardCaretPosition(pos); 311 m_upstreamStart = mostBackwardCaretPosition(pos);
303 m_downstreamStart = mostForwardCaretPosition(pos); 312 m_downstreamStart = mostForwardCaretPosition(pos);
304 m_leadingWhitespace = 313 m_leadingWhitespace =
305 leadingWhitespacePosition(m_upstreamStart, visiblePos.affinity()); 314 leadingWhitespacePosition(m_upstreamStart, visiblePos.affinity());
306 315
307 setStartingSelectionOnSmartDelete(m_upstreamStart, m_upstreamEnd); 316 setStartingSelectionOnSmartDelete(m_upstreamStart, m_upstreamEnd);
308 } 317 }
309 318
310 // trailing whitespace is only considered for smart delete if there is no 319 // trailing whitespace is only considered for smart delete if there is no
311 // leading whitespace, as in the case where you double-click the first word 320 // leading whitespace, as in the case where you double-click the first word
312 // of a paragraph. 321 // of a paragraph.
313 if (!skipSmartDelete && !hasLeadingWhitespaceBeforeAdjustment && 322 if (!skipSmartDelete && !hasLeadingWhitespaceBeforeAdjustment &&
314 trailingWhitespacePosition(m_downstreamEnd, VP_DEFAULT_AFFINITY, 323 trailingWhitespacePosition(m_downstreamEnd, VP_DEFAULT_AFFINITY,
315 ConsiderNonCollapsibleWhitespace) 324 ConsiderNonCollapsibleWhitespace)
316 .isNotNull()) { 325 .isNotNull()) {
317 // Expand out one character downstream for smart delete and recalculate 326 // Expand out one character downstream for smart delete and recalculate
318 // positions based on this change. 327 // positions based on this change.
319 pos = nextPositionOf(createVisiblePositionDeprecated(m_downstreamEnd, 328 pos = nextPositionOf(
320 VP_DEFAULT_AFFINITY)) 329 createVisiblePosition(m_downstreamEnd, VP_DEFAULT_AFFINITY))
321 .deepEquivalent(); 330 .deepEquivalent();
322 m_upstreamEnd = mostBackwardCaretPosition(pos); 331 m_upstreamEnd = mostBackwardCaretPosition(pos);
323 m_downstreamEnd = mostForwardCaretPosition(pos); 332 m_downstreamEnd = mostForwardCaretPosition(pos);
324 m_trailingWhitespace = 333 m_trailingWhitespace =
325 trailingWhitespacePosition(m_downstreamEnd, VP_DEFAULT_AFFINITY); 334 trailingWhitespacePosition(m_downstreamEnd, VP_DEFAULT_AFFINITY);
326 335
327 setStartingSelectionOnSmartDelete(m_downstreamStart, m_downstreamEnd); 336 setStartingSelectionOnSmartDelete(m_downstreamStart, m_downstreamEnd);
328 } 337 }
329 } 338 }
330 339
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 return; 781 return;
773 782
774 // FIXME: The deletion algorithm shouldn't let this happen. 783 // FIXME: The deletion algorithm shouldn't let this happen.
775 if (comparePositions(m_upstreamStart, m_downstreamEnd) > 0) 784 if (comparePositions(m_upstreamStart, m_downstreamEnd) > 0)
776 return; 785 return;
777 786
778 // There's nothing to merge. 787 // There's nothing to merge.
779 if (m_upstreamStart == m_downstreamEnd) 788 if (m_upstreamStart == m_downstreamEnd)
780 return; 789 return;
781 790
791 document().updateStyleAndLayoutIgnorePendingStylesheets();
792
782 VisiblePosition startOfParagraphToMove = 793 VisiblePosition startOfParagraphToMove =
783 createVisiblePositionDeprecated(m_downstreamEnd); 794 createVisiblePosition(m_downstreamEnd);
784 VisiblePosition mergeDestination = 795 VisiblePosition mergeDestination = createVisiblePosition(m_upstreamStart);
785 createVisiblePositionDeprecated(m_upstreamStart);
786 796
787 // m_downstreamEnd's block has been emptied out by deletion. There is no 797 // m_downstreamEnd's block has been emptied out by deletion. There is no
788 // content inside of it to move, so just remove it. 798 // content inside of it to move, so just remove it.
789 Element* endBlock = enclosingBlock(m_downstreamEnd.anchorNode()); 799 Element* endBlock = enclosingBlock(m_downstreamEnd.anchorNode());
790 if (!endBlock || 800 if (!endBlock ||
791 !endBlock->contains( 801 !endBlock->contains(
792 startOfParagraphToMove.deepEquivalent().anchorNode()) || 802 startOfParagraphToMove.deepEquivalent().anchorNode()) ||
793 !startOfParagraphToMove.deepEquivalent().anchorNode()) { 803 !startOfParagraphToMove.deepEquivalent().anchorNode()) {
794 removeNode(enclosingBlock(m_downstreamEnd.anchorNode()), editingState); 804 removeNode(enclosingBlock(m_downstreamEnd.anchorNode()), editingState);
795 return; 805 return;
(...skipping 18 matching lines...) Expand all
814 document().updateStyleAndLayoutIgnorePendingStylesheets(); 824 document().updateStyleAndLayoutIgnorePendingStylesheets();
815 mergeDestination = createVisiblePosition(m_upstreamStart); 825 mergeDestination = createVisiblePosition(m_upstreamStart);
816 startOfParagraphToMove = 826 startOfParagraphToMove =
817 createVisiblePosition(storedStartOfParagraphToMove); 827 createVisiblePosition(storedStartOfParagraphToMove);
818 } 828 }
819 829
820 if (mergeDestination.deepEquivalent() == 830 if (mergeDestination.deepEquivalent() ==
821 startOfParagraphToMove.deepEquivalent()) 831 startOfParagraphToMove.deepEquivalent())
822 return; 832 return;
823 833
824 VisiblePosition endOfParagraphToMove = endOfParagraphDeprecated( 834 VisiblePosition endOfParagraphToMove =
825 startOfParagraphToMove, CanSkipOverEditingBoundary); 835 endOfParagraph(startOfParagraphToMove, CanSkipOverEditingBoundary);
826 836
827 if (mergeDestination.deepEquivalent() == 837 if (mergeDestination.deepEquivalent() ==
828 endOfParagraphToMove.deepEquivalent()) 838 endOfParagraphToMove.deepEquivalent())
829 return; 839 return;
830 840
831 // If the merge destination and source to be moved are both list items of 841 // If the merge destination and source to be moved are both list items of
832 // different lists, merge them into single list. 842 // different lists, merge them into single list.
833 Node* listItemInFirstParagraph = 843 Node* listItemInFirstParagraph =
834 enclosingNodeOfType(m_upstreamStart, isListItem); 844 enclosingNodeOfType(m_upstreamStart, isListItem);
835 Node* listItemInSecondParagraph = 845 Node* listItemInSecondParagraph =
836 enclosingNodeOfType(m_downstreamEnd, isListItem); 846 enclosingNodeOfType(m_downstreamEnd, isListItem);
837 if (listItemInFirstParagraph && listItemInSecondParagraph && 847 if (listItemInFirstParagraph && listItemInSecondParagraph &&
838 listItemInFirstParagraph->parentElement() != 848 listItemInFirstParagraph->parentElement() !=
839 listItemInSecondParagraph->parentElement() && 849 listItemInSecondParagraph->parentElement() &&
840 canMergeLists(listItemInFirstParagraph->parentElement(), 850 canMergeLists(listItemInFirstParagraph->parentElement(),
841 listItemInSecondParagraph->parentElement())) { 851 listItemInSecondParagraph->parentElement())) {
842 mergeIdenticalElements(listItemInFirstParagraph->parentElement(), 852 mergeIdenticalElements(listItemInFirstParagraph->parentElement(),
843 listItemInSecondParagraph->parentElement(), 853 listItemInSecondParagraph->parentElement(),
844 editingState); 854 editingState);
845 if (editingState->isAborted()) 855 if (editingState->isAborted())
846 return; 856 return;
847 m_endingPosition = mergeDestination.deepEquivalent(); 857 m_endingPosition = mergeDestination.deepEquivalent();
848 return; 858 return;
849 } 859 }
850 860
851 // The rule for merging into an empty block is: only do so if its farther to 861 // The rule for merging into an empty block is: only do so if its farther to
852 // the right. 862 // the right.
853 // FIXME: Consider RTL. 863 // FIXME: Consider RTL.
854 if (!m_startsAtEmptyLine && isStartOfParagraphDeprecated(mergeDestination) && 864 if (!m_startsAtEmptyLine && isStartOfParagraph(mergeDestination) &&
855 absoluteCaretBoundsOf(startOfParagraphToMove).x() > 865 absoluteCaretBoundsOf(startOfParagraphToMove).x() >
856 absoluteCaretBoundsOf(mergeDestination).x()) { 866 absoluteCaretBoundsOf(mergeDestination).x()) {
857 if (isHTMLBRElement( 867 if (isHTMLBRElement(
858 *mostForwardCaretPosition(mergeDestination.deepEquivalent()) 868 *mostForwardCaretPosition(mergeDestination.deepEquivalent())
859 .anchorNode())) { 869 .anchorNode())) {
860 removeNodeAndPruneAncestors( 870 removeNodeAndPruneAncestors(
861 mostForwardCaretPosition(mergeDestination.deepEquivalent()) 871 mostForwardCaretPosition(mergeDestination.deepEquivalent())
862 .anchorNode(), 872 .anchorNode(),
863 editingState); 873 editingState);
864 if (editingState->isAborted()) 874 if (editingState->isAborted())
865 return; 875 return;
866 m_endingPosition = startOfParagraphToMove.deepEquivalent(); 876 m_endingPosition = startOfParagraphToMove.deepEquivalent();
867 return; 877 return;
868 } 878 }
869 } 879 }
870 880
871 // Block images, tables and horizontal rules cannot be made inline with 881 // Block images, tables and horizontal rules cannot be made inline with
872 // content at mergeDestination. If there is any 882 // content at mergeDestination. If there is any
873 // (!isStartOfParagraphDeprecated(mergeDestination)), don't merge, just move 883 // (!isStartOfParagraphDeprecated(mergeDestination)), don't merge, just move
874 // the caret to just before the selection we deleted. See 884 // the caret to just before the selection we deleted. See
875 // https://bugs.webkit.org/show_bug.cgi?id=25439 885 // https://bugs.webkit.org/show_bug.cgi?id=25439
876 if (isRenderedAsNonInlineTableImageOrHR( 886 if (isRenderedAsNonInlineTableImageOrHR(
877 startOfParagraphToMove.deepEquivalent().anchorNode()) && 887 startOfParagraphToMove.deepEquivalent().anchorNode()) &&
878 !isStartOfParagraphDeprecated(mergeDestination)) { 888 !isStartOfParagraph(mergeDestination)) {
879 m_endingPosition = m_upstreamStart; 889 m_endingPosition = m_upstreamStart;
880 return; 890 return;
881 } 891 }
882 892
883 // moveParagraphs will insert placeholders if it removes blocks that would 893 // moveParagraphs will insert placeholders if it removes blocks that would
884 // require their use, don't let block removals that it does cause the 894 // require their use, don't let block removals that it does cause the
885 // insertion of *another* placeholder. 895 // insertion of *another* placeholder.
886 bool needPlaceholder = m_needPlaceholder; 896 bool needPlaceholder = m_needPlaceholder;
887 bool paragraphToMergeIsEmpty = startOfParagraphToMove.deepEquivalent() == 897 bool paragraphToMergeIsEmpty = startOfParagraphToMove.deepEquivalent() ==
888 endOfParagraphToMove.deepEquivalent(); 898 endOfParagraphToMove.deepEquivalent();
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1022 1032
1023 if (!m_selectionToDelete.isNonOrphanedRange() || 1033 if (!m_selectionToDelete.isNonOrphanedRange() ||
1024 !m_selectionToDelete.isContentEditable()) 1034 !m_selectionToDelete.isContentEditable())
1025 return; 1035 return;
1026 1036
1027 RelocatablePosition relocatableReferencePosition(m_referenceMovePosition); 1037 RelocatablePosition relocatableReferencePosition(m_referenceMovePosition);
1028 1038
1029 // save this to later make the selection with 1039 // save this to later make the selection with
1030 TextAffinity affinity = m_selectionToDelete.affinity(); 1040 TextAffinity affinity = m_selectionToDelete.affinity();
1031 1041
1042 document().updateStyleAndLayoutIgnorePendingStylesheets();
1043
1032 Position downstreamEnd = mostForwardCaretPosition(m_selectionToDelete.end()); 1044 Position downstreamEnd = mostForwardCaretPosition(m_selectionToDelete.end());
1033 bool rootWillStayOpenWithoutPlaceholder = 1045 bool rootWillStayOpenWithoutPlaceholder =
1034 downstreamEnd.computeContainerNode() == 1046 downstreamEnd.computeContainerNode() ==
1035 rootEditableElement(*downstreamEnd.computeContainerNode()) || 1047 rootEditableElement(*downstreamEnd.computeContainerNode()) ||
1036 (downstreamEnd.computeContainerNode()->isTextNode() && 1048 (downstreamEnd.computeContainerNode()->isTextNode() &&
1037 downstreamEnd.computeContainerNode()->parentNode() == 1049 downstreamEnd.computeContainerNode()->parentNode() ==
1038 rootEditableElement(*downstreamEnd.computeContainerNode())); 1050 rootEditableElement(*downstreamEnd.computeContainerNode()));
1039 bool lineBreakAtEndOfSelectionToDelete = lineBreakExistsAtVisiblePosition( 1051 bool lineBreakAtEndOfSelectionToDelete =
1040 m_selectionToDelete.visibleEndDeprecated()); 1052 lineBreakExistsAtVisiblePosition(m_selectionToDelete.visibleEnd());
1041 m_needPlaceholder = 1053 m_needPlaceholder = !rootWillStayOpenWithoutPlaceholder &&
1042 !rootWillStayOpenWithoutPlaceholder && 1054 isStartOfParagraph(m_selectionToDelete.visibleStart(),
1043 isStartOfParagraphDeprecated(m_selectionToDelete.visibleStartDeprecated(), 1055 CanCrossEditingBoundary) &&
1044 CanCrossEditingBoundary) && 1056 isEndOfParagraph(m_selectionToDelete.visibleEnd(),
1045 isEndOfParagraphDeprecated(m_selectionToDelete.visibleEndDeprecated(), 1057 CanCrossEditingBoundary) &&
1046 CanCrossEditingBoundary) && 1058 !lineBreakAtEndOfSelectionToDelete;
1047 !lineBreakAtEndOfSelectionToDelete;
1048 if (m_needPlaceholder) { 1059 if (m_needPlaceholder) {
1049 // Don't need a placeholder when deleting a selection that starts just 1060 // Don't need a placeholder when deleting a selection that starts just
1050 // before a table and ends inside it (we do need placeholders to hold 1061 // before a table and ends inside it (we do need placeholders to hold
1051 // open empty cells, but that's handled elsewhere). 1062 // open empty cells, but that's handled elsewhere).
1052 if (Element* table = tableElementJustAfter( 1063 if (Element* table =
1053 m_selectionToDelete.visibleStartDeprecated())) { 1064 tableElementJustAfter(m_selectionToDelete.visibleStart())) {
1054 if (m_selectionToDelete.end().anchorNode()->isDescendantOf(table)) 1065 if (m_selectionToDelete.end().anchorNode()->isDescendantOf(table))
1055 m_needPlaceholder = false; 1066 m_needPlaceholder = false;
1056 } 1067 }
1057 } 1068 }
1058 1069
1059 // set up our state 1070 // set up our state
1060 initializePositionData(editingState); 1071 initializePositionData(editingState);
1061 if (editingState->isAborted()) 1072 if (editingState->isAborted())
1062 return; 1073 return;
1063 1074
1064 bool lineBreakBeforeStart = lineBreakExistsAtVisiblePosition( 1075 bool lineBreakBeforeStart = lineBreakExistsAtVisiblePosition(
1065 previousPositionOf(createVisiblePositionDeprecated(m_upstreamStart))); 1076 previousPositionOf(createVisiblePosition(m_upstreamStart)));
1066 1077
1067 // Delete any text that may hinder our ability to fixup whitespace after the 1078 // Delete any text that may hinder our ability to fixup whitespace after the
1068 // delete 1079 // delete
1069 deleteInsignificantTextDownstream(m_trailingWhitespace); 1080 deleteInsignificantTextDownstream(m_trailingWhitespace);
1070 1081
1071 saveTypingStyleState(); 1082 saveTypingStyleState();
1072 1083
1073 // deleting just a BR is handled specially, at least because we do not 1084 // deleting just a BR is handled specially, at least because we do not
1074 // want to replace it with a placeholder BR! 1085 // want to replace it with a placeholder BR!
1075 bool brResult = handleSpecialCaseBRDelete(editingState); 1086 bool brResult = handleSpecialCaseBRDelete(editingState);
1076 if (editingState->isAborted()) 1087 if (editingState->isAborted())
1077 return; 1088 return;
1078 if (brResult) { 1089 if (brResult) {
1079 calculateTypingStyleAfterDelete(); 1090 calculateTypingStyleAfterDelete();
1080 setEndingSelection(createVisibleSelectionDeprecated( 1091 document().updateStyleAndLayoutIgnorePendingStylesheets();
1092 setEndingSelection(createVisibleSelection(
1081 m_endingPosition, affinity, endingSelection().isDirectional())); 1093 m_endingPosition, affinity, endingSelection().isDirectional()));
1082 clearTransientState(); 1094 clearTransientState();
1083 rebalanceWhitespace(); 1095 rebalanceWhitespace();
1084 return; 1096 return;
1085 } 1097 }
1086 1098
1087 handleGeneralDelete(editingState); 1099 handleGeneralDelete(editingState);
1088 if (editingState->isAborted()) 1100 if (editingState->isAborted())
1089 return; 1101 return;
1090 1102
1091 fixupWhitespace(); 1103 fixupWhitespace();
1092 1104
1093 mergeParagraphs(editingState); 1105 mergeParagraphs(editingState);
1094 if (editingState->isAborted()) 1106 if (editingState->isAborted())
1095 return; 1107 return;
1096 1108
1097 removePreviouslySelectedEmptyTableRows(editingState); 1109 removePreviouslySelectedEmptyTableRows(editingState);
1098 if (editingState->isAborted()) 1110 if (editingState->isAborted())
1099 return; 1111 return;
1100 1112
1101 if (!m_needPlaceholder && rootWillStayOpenWithoutPlaceholder) { 1113 if (!m_needPlaceholder && rootWillStayOpenWithoutPlaceholder) {
1102 VisiblePosition visualEnding = 1114 document().updateStyleAndLayoutIgnorePendingStylesheets();
1103 createVisiblePositionDeprecated(m_endingPosition); 1115 VisiblePosition visualEnding = createVisiblePosition(m_endingPosition);
1104 bool hasPlaceholder = 1116 bool hasPlaceholder =
1105 lineBreakExistsAtVisiblePosition(visualEnding) && 1117 lineBreakExistsAtVisiblePosition(visualEnding) &&
1106 nextPositionOf(visualEnding, CannotCrossEditingBoundary).isNull(); 1118 nextPositionOf(visualEnding, CannotCrossEditingBoundary).isNull();
1107 m_needPlaceholder = hasPlaceholder && lineBreakBeforeStart && 1119 m_needPlaceholder = hasPlaceholder && lineBreakBeforeStart &&
1108 !lineBreakAtEndOfSelectionToDelete; 1120 !lineBreakAtEndOfSelectionToDelete;
1109 } 1121 }
1110 1122
1111 HTMLBRElement* placeholder = 1123 HTMLBRElement* placeholder =
1112 m_needPlaceholder ? HTMLBRElement::create(document()) : nullptr; 1124 m_needPlaceholder ? HTMLBRElement::create(document()) : nullptr;
1113 1125
1114 if (placeholder) { 1126 if (placeholder) {
1115 if (m_sanitizeMarkup) { 1127 if (m_sanitizeMarkup) {
1116 removeRedundantBlocks(editingState); 1128 removeRedundantBlocks(editingState);
1117 if (editingState->isAborted()) 1129 if (editingState->isAborted())
1118 return; 1130 return;
1119 } 1131 }
1120 // handleGeneralDelete cause DOM mutation events so |m_endingPosition| 1132 // handleGeneralDelete cause DOM mutation events so |m_endingPosition|
1121 // can be out of document. 1133 // can be out of document.
1122 if (m_endingPosition.isConnected()) { 1134 if (m_endingPosition.isConnected()) {
1123 insertNodeAt(placeholder, m_endingPosition, editingState); 1135 insertNodeAt(placeholder, m_endingPosition, editingState);
1124 if (editingState->isAborted()) 1136 if (editingState->isAborted())
1125 return; 1137 return;
1126 } 1138 }
1127 } 1139 }
1128 1140
1129 rebalanceWhitespaceAt(m_endingPosition); 1141 rebalanceWhitespaceAt(m_endingPosition);
1130 1142
1131 calculateTypingStyleAfterDelete(); 1143 calculateTypingStyleAfterDelete();
1132 1144
1133 setEndingSelection(createVisibleSelectionDeprecated( 1145 document().updateStyleAndLayoutIgnorePendingStylesheets();
1134 m_endingPosition, affinity, endingSelection().isDirectional())); 1146
1147 setEndingSelection(createVisibleSelection(m_endingPosition, affinity,
1148 endingSelection().isDirectional()));
1135 1149
1136 if (relocatableReferencePosition.position().isNull()) { 1150 if (relocatableReferencePosition.position().isNull()) {
1137 clearTransientState(); 1151 clearTransientState();
1138 return; 1152 return;
1139 } 1153 }
1140 1154
1141 // This deletion command is part of a move operation, we need to cleanup after 1155 // This deletion command is part of a move operation, we need to cleanup after
1142 // deletion. 1156 // deletion.
1143 m_referenceMovePosition = relocatableReferencePosition.position(); 1157 m_referenceMovePosition = relocatableReferencePosition.position();
1144 // If the node for the destination has been removed as a result of the 1158 // If the node for the destination has been removed as a result of the
1145 // deletion, set the destination to the ending point after the deletion. 1159 // deletion, set the destination to the ending point after the deletion.
1146 // Fixes: <rdar://problem/3910425> REGRESSION (Mail): Crash in 1160 // Fixes: <rdar://problem/3910425> REGRESSION (Mail): Crash in
1147 // ReplaceSelectionCommand; selection is empty, leading to null deref 1161 // ReplaceSelectionCommand; selection is empty, leading to null deref
1148 if (!m_referenceMovePosition.isConnected()) 1162 if (!m_referenceMovePosition.isConnected())
1149 m_referenceMovePosition = endingSelection().start(); 1163 m_referenceMovePosition = endingSelection().start();
1150 1164
1151 // Move selection shouldn't left empty <li> block. 1165 // Move selection shouldn't left empty <li> block.
1152 cleanupAfterDeletion( 1166 cleanupAfterDeletion(editingState,
1153 editingState, createVisiblePositionDeprecated(m_referenceMovePosition)); 1167 createVisiblePosition(m_referenceMovePosition));
1154 if (editingState->isAborted()) 1168 if (editingState->isAborted())
1155 return; 1169 return;
1156 1170
1157 clearTransientState(); 1171 clearTransientState();
1158 } 1172 }
1159 1173
1160 InputEvent::InputType DeleteSelectionCommand::inputType() const { 1174 InputEvent::InputType DeleteSelectionCommand::inputType() const {
1161 // |DeleteSelectionCommand| could be used with Cut, Menu Bar deletion and 1175 // |DeleteSelectionCommand| could be used with Cut, Menu Bar deletion and
1162 // |TypingCommand|. 1176 // |TypingCommand|.
1163 // 1. Cut and Menu Bar deletion should rely on correct |m_inputType|. 1177 // 1. Cut and Menu Bar deletion should rely on correct |m_inputType|.
(...skipping 26 matching lines...) Expand all
1190 visitor->trace(m_deleteIntoBlockquoteStyle); 1204 visitor->trace(m_deleteIntoBlockquoteStyle);
1191 visitor->trace(m_startRoot); 1205 visitor->trace(m_startRoot);
1192 visitor->trace(m_endRoot); 1206 visitor->trace(m_endRoot);
1193 visitor->trace(m_startTableRow); 1207 visitor->trace(m_startTableRow);
1194 visitor->trace(m_endTableRow); 1208 visitor->trace(m_endTableRow);
1195 visitor->trace(m_temporaryPlaceholder); 1209 visitor->trace(m_temporaryPlaceholder);
1196 CompositeEditCommand::trace(visitor); 1210 CompositeEditCommand::trace(visitor);
1197 } 1211 }
1198 1212
1199 } // namespace blink 1213 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698