// For the moment, this is SPI and the only client (Mail.app) is satisfied.
// Here are two things to re-evaluate when making into API.
// 1. Currently, InheritedListType uses clones whereas OrderedList and
// UnorderedList create a new list node of the specified type.  That is
// inconsistent wrt style.  If that is not OK, here are some alternatives:
//  - new nodes always inherit style (probably the best choice)
//  - new nodes have always have no style
//  - new nodes of the same type inherit style
// 2. Currently, the node we return may be either a pre-existing one or
// a new one. Is it confusing to return the pre-existing one without
// somehow indicating that it is not new?  If so, here are some alternatives:
//  - only return the list node if we created it
//  - indicate whether the list node is new or pre-existing
//  - (silly) client specifies whether to return pre-existing list nodes
void IncreaseSelectionListLevelCommand::doApply()
{
    Node* startListChild;
    Node* endListChild;
    if (!canIncreaseListLevel(endingSelection(), startListChild, endListChild))
        return;

    Node* previousItem = startListChild->renderer()->previousSibling()->node();
    if (isListHTMLElement(previousItem)) {
        // move nodes up into preceding list
        appendSiblingNodeRange(startListChild, endListChild, downcast<Element>(previousItem));
        m_listElement = previousItem;
    } else {
        // create a sublist for the preceding element and move nodes there
        RefPtr<Element> newParent;
        switch (m_listType) {
            case InheritedListType:
                newParent = startListChild->parentElement();
                if (newParent)
                    newParent = newParent->cloneElementWithoutChildren(document());
                break;
            case OrderedList:
                newParent = HTMLOListElement::create(document());
                break;
            case UnorderedList:
                newParent = HTMLUListElement::create(document());
                break;
        }
        insertNodeBefore(newParent, startListChild);
        appendSiblingNodeRange(startListChild, endListChild, newParent.get());
        m_listElement = WTFMove(newParent);
    }
}
// For the moment, this is SPI and the only client (Mail.app) is satisfied.
// Here are two things to re-evaluate when making into API.
// 1. Currently, InheritedListType uses clones whereas OrderedList and
// UnorderedList create a new list node of the specified type.  That is
// inconsistent wrt style.  If that is not OK, here are some alternatives:
//  - new nodes always inherit style (probably the best choice)
//  - new nodes have always have no style
//  - new nodes of the same type inherit style
// 2. Currently, the node we return may be either a pre-existing one or
// a new one. Is it confusing to return the pre-existing one without
// somehow indicating that it is not new?  If so, here are some alternatives:
//  - only return the list node if we created it
//  - indicate whether the list node is new or pre-existing
//  - (silly) client specifies whether to return pre-existing list nodes
void IncreaseSelectionListLevelCommand::doApply()
{
    Node* startListChild;
    Node* endListChild;
    if (!canIncreaseListLevel(endingSelection(), startListChild, endListChild))
        return;

    Node* previousItem = startListChild->renderer()->previousSibling()->element();
    if (isListElement(previousItem)) {
        // move nodes up into preceding list
        appendSiblingNodeRange(startListChild, endListChild, previousItem);
        m_listElement = previousItem;
    } else {
        // create a sublist for the preceding element and move nodes there
        RefPtr<Node> newParent;
        switch (m_listType) {
            case InheritedListType:
                newParent = startListChild->parentNode()->cloneNode(false);
                break;
            case OrderedList:
                newParent = createOrderedListElement(document());
                break;
            case UnorderedList:
                newParent = createUnorderedListElement(document());
                break;
        }
        insertNodeBefore(newParent.get(), startListChild);
        appendSiblingNodeRange(startListChild, endListChild, newParent.get());
        m_listElement = newParent.get();
    }
}