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

Unified 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, 3 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp
diff --git a/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp b/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp
index 75b424fa928737c228012284b845b1c2780ce75b..b7ef67cf9eac676da172afd3f0cd56853a371435 100644
--- a/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp
@@ -63,7 +63,7 @@ static bool isTableRowEmpty(Node* row)
return true;
}
-DeleteSelectionCommand::DeleteSelectionCommand(Document& document, bool smartDelete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool sanitizeMarkup, InputEvent::InputType inputType)
+DeleteSelectionCommand::DeleteSelectionCommand(Document& document, bool smartDelete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool sanitizeMarkup, InputEvent::InputType inputType, const Position& referenceMovePosition)
: CompositeEditCommand(document)
, m_hasSelectionToDelete(false)
, m_smartDelete(smartDelete)
@@ -74,6 +74,7 @@ DeleteSelectionCommand::DeleteSelectionCommand(Document& document, bool smartDel
, m_startsAtEmptyLine(false)
, m_sanitizeMarkup(sanitizeMarkup)
, m_inputType(inputType)
+ , m_referenceMovePosition(referenceMovePosition)
, m_startBlock(nullptr)
, m_endBlock(nullptr)
, m_typingStyle(nullptr)
@@ -805,6 +806,7 @@ void DeleteSelectionCommand::clearTransientState()
m_endingPosition = Position();
m_leadingWhitespace = Position();
m_trailingWhitespace = Position();
+ m_referenceMovePosition = Position();
}
// This method removes div elements with no attributes that have only one child or no children at all.
@@ -838,6 +840,19 @@ void DeleteSelectionCommand::doApply(EditingState* editingState)
if (!m_selectionToDelete.isNonOrphanedRange() || !m_selectionToDelete.isContentEditable())
return;
+ 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.
+ // Update the position otherwise it may become invalid after the selection is deleted.
yosin_UTC9 2016/09/28 04:19:03 Could you utilize |RelocatablePosition|?
chongz 2016/09/29 02:36:22 Done.
+ Position selectionEnd = endingSelection().end();
+ if (m_referenceMovePosition.isOffsetInAnchor() && selectionEnd.isOffsetInAnchor()
+ && selectionEnd.computeContainerNode() == m_referenceMovePosition.computeContainerNode() && selectionEnd.offsetInContainerNode() < m_referenceMovePosition.offsetInContainerNode()) {
+ m_referenceMovePosition = Position(m_referenceMovePosition.computeContainerNode(), m_referenceMovePosition.offsetInContainerNode() - selectionEnd.offsetInContainerNode());
+
+ Position selectionStart = endingSelection().start();
+ if (selectionStart.isOffsetInAnchor() && selectionStart.computeContainerNode() == m_referenceMovePosition.computeContainerNode())
+ m_referenceMovePosition = Position(m_referenceMovePosition.computeContainerNode(), m_referenceMovePosition.offsetInContainerNode() + selectionStart.offsetInContainerNode());
+ }
+ }
+
// save this to later make the selection with
TextAffinity affinity = m_selectionToDelete.affinity();
@@ -928,6 +943,22 @@ void DeleteSelectionCommand::doApply(EditingState* editingState)
calculateTypingStyleAfterDelete();
setEndingSelection(VisibleSelection(m_endingPosition, affinity, endingSelection().isDirectional()));
+
+ // This deletion command is part or a move operation.
+ if (!m_referenceMovePosition.isNull()) {
+ // If the node for the destination has been removed as a result of the deletion,
+ // set the destination to the ending point after the deletion.
+ // Fixes: <rdar://problem/3910425> REGRESSION (Mail): Crash in ReplaceSelectionCommand;
+ // selection is empty, leading to null deref
+ if (!m_referenceMovePosition.isConnected())
+ m_referenceMovePosition = endingSelection().start();
+
+ // Move selection shouldn't left empty <li> block.
+ cleanupAfterDeletion(editingState, createVisiblePositionDeprecated(m_referenceMovePosition));
+ if (editingState->isAborted())
+ return;
+ }
+
clearTransientState();
}
@@ -957,6 +988,7 @@ DEFINE_TRACE(DeleteSelectionCommand)
visitor->trace(m_endingPosition);
visitor->trace(m_leadingWhitespace);
visitor->trace(m_trailingWhitespace);
+ visitor->trace(m_referenceMovePosition);
visitor->trace(m_startBlock);
visitor->trace(m_endBlock);
visitor->trace(m_typingStyle);

Powered by Google App Engine
This is Rietveld 408576698