Пример #1
0
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));
}