diff options
Diffstat (limited to 'WebCore/editing/ModifySelectionListLevel.cpp')
-rw-r--r-- | WebCore/editing/ModifySelectionListLevel.cpp | 293 |
1 files changed, 0 insertions, 293 deletions
diff --git a/WebCore/editing/ModifySelectionListLevel.cpp b/WebCore/editing/ModifySelectionListLevel.cpp deleted file mode 100644 index 0b1123b..0000000 --- a/WebCore/editing/ModifySelectionListLevel.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ModifySelectionListLevel.h" - -#include "Document.h" -#include "Element.h" -#include "Frame.h" -#include "RenderObject.h" -#include "SelectionController.h" -#include "htmlediting.h" - -namespace WebCore { - -ModifySelectionListLevelCommand::ModifySelectionListLevelCommand(Document* document) - : CompositeEditCommand(document) -{ -} - -bool ModifySelectionListLevelCommand::preservesTypingStyle() const -{ - return true; -} - -// This needs to be static so it can be called by canIncreaseSelectionListLevel and canDecreaseSelectionListLevel -static bool getStartEndListChildren(const Selection& selection, Node*& start, Node*& end) -{ - if (selection.isNone()) - return false; - - // start must be in a list child - Node* startListChild = enclosingListChild(selection.start().node()); - if (!startListChild) - return false; - - // end must be in a list child - Node* endListChild = selection.isRange() ? enclosingListChild(selection.end().node()) : startListChild; - if (!endListChild) - return false; - - // For a range selection we want the following behavior: - // - the start and end must be within the same overall list - // - the start must be at or above the level of the rest of the range - // - if the end is anywhere in a sublist lower than start, the whole sublist gets moved - // In terms of this function, this means: - // - endListChild must start out being be a sibling of startListChild, or be in a - // sublist of startListChild or a sibling - // - if endListChild is in a sublist of startListChild or a sibling, it must be adjusted - // to be the ancestor that is startListChild or its sibling - while (startListChild->parentNode() != endListChild->parentNode()) { - endListChild = endListChild->parentNode(); - if (!endListChild) - return false; - } - - // if the selection ends on a list item with a sublist, include the entire sublist - if (endListChild->renderer()->isListItem()) { - RenderObject* r = endListChild->renderer()->nextSibling(); - if (r && isListElement(r->element())) - endListChild = r->element(); - } - - start = startListChild; - end = endListChild; - return true; -} - -void ModifySelectionListLevelCommand::insertSiblingNodeRangeBefore(Node* startNode, Node* endNode, Node* refNode) -{ - Node* node = startNode; - while (1) { - Node* next = node->nextSibling(); - removeNode(node); - insertNodeBefore(node, refNode); - - if (node == endNode) - break; - - node = next; - } -} - -void ModifySelectionListLevelCommand::insertSiblingNodeRangeAfter(Node* startNode, Node* endNode, Node* refNode) -{ - Node* node = startNode; - while (1) { - Node* next = node->nextSibling(); - removeNode(node); - insertNodeAfter(node, refNode); - - if (node == endNode) - break; - - refNode = node; - node = next; - } -} - -void ModifySelectionListLevelCommand::appendSiblingNodeRange(Node* startNode, Node* endNode, Node* newParent) -{ - Node* node = startNode; - while (1) { - Node* next = node->nextSibling(); - removeNode(node); - appendNode(node, newParent); - - if (node == endNode) - break; - - node = next; - } -} - -IncreaseSelectionListLevelCommand::IncreaseSelectionListLevelCommand(Document* document, Type listType) - : ModifySelectionListLevelCommand(document) - , m_listType(listType) -{ -} - -// This needs to be static so it can be called by canIncreaseSelectionListLevel -static bool canIncreaseListLevel(const Selection& selection, Node*& start, Node*& end) -{ - if (!getStartEndListChildren(selection, start, end)) - return false; - - // start must not be the first child (because you need a prior one - // to increase relative to) - if (!start->renderer()->previousSibling()) - return false; - - return true; -} - -// 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(); - } -} - -bool IncreaseSelectionListLevelCommand::canIncreaseSelectionListLevel(Document* document) -{ - Node* startListChild; - Node* endListChild; - return canIncreaseListLevel(document->frame()->selection()->selection(), startListChild, endListChild); -} - -PassRefPtr<Node> IncreaseSelectionListLevelCommand::increaseSelectionListLevelWithType(Document* document, Type listType) -{ - ASSERT(document); - ASSERT(document->frame()); - RefPtr<IncreaseSelectionListLevelCommand> modCommand = new IncreaseSelectionListLevelCommand(document, listType); - modCommand->apply(); - return modCommand->m_listElement; -} - -PassRefPtr<Node> IncreaseSelectionListLevelCommand::increaseSelectionListLevel(Document* document) -{ - return increaseSelectionListLevelWithType(document, InheritedListType); -} - -PassRefPtr<Node> IncreaseSelectionListLevelCommand::increaseSelectionListLevelOrdered(Document* document) -{ - return increaseSelectionListLevelWithType(document, OrderedList); -} - -PassRefPtr<Node> IncreaseSelectionListLevelCommand::increaseSelectionListLevelUnordered(Document* document) -{ - return increaseSelectionListLevelWithType(document, UnorderedList); -} - -DecreaseSelectionListLevelCommand::DecreaseSelectionListLevelCommand(Document* document) - : ModifySelectionListLevelCommand(document) -{ -} - -// This needs to be static so it can be called by canDecreaseSelectionListLevel -static bool canDecreaseListLevel(const Selection& selection, Node*& start, Node*& end) -{ - if (!getStartEndListChildren(selection, start, end)) - return false; - - // there must be a destination list to move the items to - if (!isListElement(start->parentNode()->parentNode())) - return false; - - return true; -} - -void DecreaseSelectionListLevelCommand::doApply() -{ - Node* startListChild; - Node* endListChild; - if (!canDecreaseListLevel(endingSelection(), startListChild, endListChild)) - return; - - Node* previousItem = startListChild->renderer()->previousSibling() ? startListChild->renderer()->previousSibling()->element() : 0; - Node* nextItem = endListChild->renderer()->nextSibling() ? endListChild->renderer()->nextSibling()->element() : 0; - Node* listNode = startListChild->parentNode(); - - if (!previousItem) { - // at start of sublist, move the child(ren) to before the sublist - insertSiblingNodeRangeBefore(startListChild, endListChild, listNode); - // if that was the whole sublist we moved, remove the sublist node - if (!nextItem) - removeNode(listNode); - } else if (!nextItem) { - // at end of list, move the child(ren) to after the sublist - insertSiblingNodeRangeAfter(startListChild, endListChild, listNode); - } else { - // in the middle of list, split the list and move the children to the divide - splitElement(static_cast<Element*>(listNode), startListChild); - insertSiblingNodeRangeBefore(startListChild, endListChild, listNode); - } -} - -bool DecreaseSelectionListLevelCommand::canDecreaseSelectionListLevel(Document* document) -{ - Node* startListChild; - Node* endListChild; - return canDecreaseListLevel(document->frame()->selection()->selection(), startListChild, endListChild); -} - -void DecreaseSelectionListLevelCommand::decreaseSelectionListLevel(Document* document) -{ - ASSERT(document); - ASSERT(document->frame()); - applyCommand(new DecreaseSelectionListLevelCommand(document)); -} - -} |