void MoveSelectionCommand::doApply() { ASSERT(endingSelection().isNonOrphanedRange()); Position pos = m_position; if (pos.isNull()) return; // Update the position otherwise it may become invalid after the selection is deleted. Position selectionEnd = endingSelection().end(); if (pos.anchorType() == Position::PositionIsOffsetInAnchor && selectionEnd.anchorType() == Position::PositionIsOffsetInAnchor && selectionEnd.containerNode() == pos.containerNode() && selectionEnd.offsetInContainerNode() < pos.offsetInContainerNode()) { pos.moveToOffset(pos.offsetInContainerNode() - selectionEnd.offsetInContainerNode()); Position selectionStart = endingSelection().start(); if (selectionStart.anchorType() == Position::PositionIsOffsetInAnchor && selectionStart.containerNode() == pos.containerNode()) pos.moveToOffset(pos.offsetInContainerNode() + selectionStart.offsetInContainerNode()); } { auto deleteSelection = DeleteSelectionCommand::create(document(), m_smartDelete, true, false, true, true, EditActionDeleteByDrag); deleteSelection->setParent(this); deleteSelection->apply(); m_commands.append(WTFMove(deleteSelection)); } // 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 (!pos.anchorNode()->inDocument()) pos = endingSelection().start(); cleanupAfterDeletion(pos); setEndingSelection(VisibleSelection(pos, endingSelection().affinity(), endingSelection().isDirectional())); setStartingSelection(endingSelection()); if (!pos.anchorNode()->inDocument()) { // Document was modified out from under us. return; } ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::PreventNesting; if (m_smartInsert) options |= ReplaceSelectionCommand::SmartReplace; { auto replaceSelection = ReplaceSelectionCommand::create(document(), WTFMove(m_fragment), options, EditActionInsertFromDrop); replaceSelection->setParent(this); replaceSelection->apply(); m_commands.append(WTFMove(replaceSelection)); } }
void MoveSelectionCommand::doApply() { ASSERT(endingSelection().isNonOrphanedRange()); Position pos = m_position; if (pos.isNull()) return; // Update the position otherwise it may become invalid after the selection is deleted. Position selectionEnd = endingSelection().end(); if (pos.isOffsetInAnchor() && selectionEnd.isOffsetInAnchor() && selectionEnd.computeContainerNode() == pos.computeContainerNode() && selectionEnd.offsetInContainerNode() < pos.offsetInContainerNode()) { pos = Position(pos.computeContainerNode(), pos.offsetInContainerNode() - selectionEnd.offsetInContainerNode()); Position selectionStart = endingSelection().start(); if (selectionStart.isOffsetInAnchor() && selectionStart.computeContainerNode() == pos.computeContainerNode()) pos = Position(pos.computeContainerNode(), pos.offsetInContainerNode() + selectionStart.offsetInContainerNode()); } deleteSelection(m_smartDelete); // 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 (!pos.inDocument()) pos = endingSelection().start(); cleanupAfterDeletion(VisiblePosition(pos)); setEndingSelection(VisibleSelection(pos, endingSelection().affinity(), endingSelection().isDirectional())); if (!pos.inDocument()) { // Document was modified out from under us. return; } ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::PreventNesting; if (m_smartInsert) options |= ReplaceSelectionCommand::SmartReplace; applyCommandToComposite(ReplaceSelectionCommand::create(document(), m_fragment, options)); }