| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2005 Apple Computer, Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 ASSERT(startNode); | 119 ASSERT(startNode); |
| 120 } | 120 } |
| 121 | 121 |
| 122 // If there's nothing inside topBlockquote to move, we're finished. | 122 // If there's nothing inside topBlockquote to move, we're finished. |
| 123 if (!startNode->isDescendantOf(topBlockquote)) { | 123 if (!startNode->isDescendantOf(topBlockquote)) { |
| 124 setEndingSelection(VisibleSelection(VisiblePosition(firstPositionInOrBef
oreNode(startNode)), endingSelection().isDirectional())); | 124 setEndingSelection(VisibleSelection(VisiblePosition(firstPositionInOrBef
oreNode(startNode)), endingSelection().isDirectional())); |
| 125 return; | 125 return; |
| 126 } | 126 } |
| 127 | 127 |
| 128 // Build up list of ancestors in between the start node and the top blockquo
te. | 128 // Build up list of ancestors in between the start node and the top blockquo
te. |
| 129 Vector<Element*> ancestors; | 129 Vector<RefPtr<Element> > ancestors; |
| 130 for (Element* node = startNode->parentElement(); node && node != topBlockquo
te; node = node->parentElement()) | 130 for (Element* node = startNode->parentElement(); node && node != topBlockquo
te; node = node->parentElement()) |
| 131 ancestors.append(node); | 131 ancestors.append(node); |
| 132 | 132 |
| 133 // Insert a clone of the top blockquote after the break. | 133 // Insert a clone of the top blockquote after the break. |
| 134 RefPtr<Element> clonedBlockquote = static_cast<Element*>(topBlockquote)->clo
neElementWithoutChildren(); | 134 RefPtr<Element> clonedBlockquote = static_cast<Element*>(topBlockquote)->clo
neElementWithoutChildren(); |
| 135 insertNodeAfter(clonedBlockquote.get(), breakNode.get()); | 135 insertNodeAfter(clonedBlockquote.get(), breakNode.get()); |
| 136 | 136 |
| 137 // Clone startNode's ancestors into the cloned blockquote. | 137 // Clone startNode's ancestors into the cloned blockquote. |
| 138 // On exiting this loop, clonedAncestor is the lowest ancestor | 138 // On exiting this loop, clonedAncestor is the lowest ancestor |
| 139 // that was cloned (i.e. the clone of either ancestors.last() | 139 // that was cloned (i.e. the clone of either ancestors.last() |
| 140 // or clonedBlockquote if ancestors is empty). | 140 // or clonedBlockquote if ancestors is empty). |
| 141 RefPtr<Element> clonedAncestor = clonedBlockquote; | 141 RefPtr<Element> clonedAncestor = clonedBlockquote; |
| 142 for (size_t i = ancestors.size(); i != 0; --i) { | 142 for (size_t i = ancestors.size(); i != 0; --i) { |
| 143 RefPtr<Element> clonedChild = ancestors[i - 1]->cloneElementWithoutChild
ren(); | 143 RefPtr<Element> clonedChild = ancestors[i - 1]->cloneElementWithoutChild
ren(); |
| 144 // Preserve list item numbering in cloned lists. | 144 // Preserve list item numbering in cloned lists. |
| 145 if (clonedChild->isElementNode() && clonedChild->hasTagName(olTag)) { | 145 if (clonedChild->isElementNode() && clonedChild->hasTagName(olTag)) { |
| 146 Node* listChildNode = i > 1 ? ancestors[i - 2] : startNode; | 146 Node* listChildNode = i > 1 ? ancestors[i - 2].get() : startNode; |
| 147 // The first child of the cloned list might not be a list item eleme
nt, | 147 // The first child of the cloned list might not be a list item eleme
nt, |
| 148 // find the first one so that we know where to start numbering. | 148 // find the first one so that we know where to start numbering. |
| 149 while (listChildNode && !listChildNode->hasTagName(liTag)) | 149 while (listChildNode && !listChildNode->hasTagName(liTag)) |
| 150 listChildNode = listChildNode->nextSibling(); | 150 listChildNode = listChildNode->nextSibling(); |
| 151 if (listChildNode && listChildNode->renderer() && listChildNode->ren
derer()->isListItem()) | 151 if (listChildNode && listChildNode->renderer() && listChildNode->ren
derer()->isListItem()) |
| 152 setNodeAttribute(static_cast<Element*>(clonedChild.get()), start
Attr, String::number(toRenderListItem(listChildNode->renderer())->value())); | 152 setNodeAttribute(static_cast<Element*>(clonedChild.get()), start
Attr, String::number(toRenderListItem(listChildNode->renderer())->value())); |
| 153 } | 153 } |
| 154 | 154 |
| 155 appendNode(clonedChild.get(), clonedAncestor.get()); | 155 appendNode(clonedChild.get(), clonedAncestor.get()); |
| 156 clonedAncestor = clonedChild; | 156 clonedAncestor = clonedChild; |
| 157 } | 157 } |
| 158 | 158 |
| 159 // Move the startNode and its siblings. | 159 moveRemainingSiblingsToNewParent(startNode, 0, clonedAncestor); |
| 160 Node *moveNode = startNode; | |
| 161 while (moveNode) { | |
| 162 Node *next = moveNode->nextSibling(); | |
| 163 removeNode(moveNode); | |
| 164 appendNode(moveNode, clonedAncestor.get()); | |
| 165 moveNode = next; | |
| 166 } | |
| 167 | 160 |
| 168 if (!ancestors.isEmpty()) { | 161 if (!ancestors.isEmpty()) { |
| 169 // Split the tree up the ancestor chain until the topBlockquote | 162 // Split the tree up the ancestor chain until the topBlockquote |
| 170 // Throughout this loop, clonedParent is the clone of ancestor's parent. | 163 // Throughout this loop, clonedParent is the clone of ancestor's parent. |
| 171 // This is so we can clone ancestor's siblings and place the clones | 164 // This is so we can clone ancestor's siblings and place the clones |
| 172 // into the clone corresponding to the ancestor's parent. | 165 // into the clone corresponding to the ancestor's parent. |
| 173 Element* ancestor; | 166 RefPtr<Element> ancestor; |
| 174 Element* clonedParent; | 167 RefPtr<Element> clonedParent; |
| 175 for (ancestor = ancestors.first(), clonedParent = clonedAncestor->parent
Element(); | 168 for (ancestor = ancestors.first(), clonedParent = clonedAncestor->parent
Element(); |
| 176 ancestor && ancestor != topBlockquote; | 169 ancestor && ancestor != topBlockquote; |
| 177 ancestor = ancestor->parentElement(), clonedParent = clonedParent->
parentElement()) { | 170 ancestor = ancestor->parentElement(), clonedParent = clonedParent->
parentElement()) |
| 178 moveNode = ancestor->nextSibling(); | 171 moveRemainingSiblingsToNewParent(ancestor->nextSibling(), 0, clonedP
arent); |
| 179 while (moveNode) { | 172 |
| 180 Node *next = moveNode->nextSibling(); | |
| 181 removeNode(moveNode); | |
| 182 appendNode(moveNode, clonedParent); | |
| 183 moveNode = next; | |
| 184 } | |
| 185 } | |
| 186 | |
| 187 // If the startNode's original parent is now empty, remove it | 173 // If the startNode's original parent is now empty, remove it |
| 188 Node* originalParent = ancestors.first(); | 174 Node* originalParent = ancestors.first().get(); |
| 189 if (!originalParent->hasChildNodes()) | 175 if (!originalParent->hasChildNodes()) |
| 190 removeNode(originalParent); | 176 removeNode(originalParent); |
| 191 } | 177 } |
| 192 | 178 |
| 193 // Make sure the cloned block quote renders. | 179 // Make sure the cloned block quote renders. |
| 194 addBlockPlaceholderIfNeeded(clonedBlockquote.get()); | 180 addBlockPlaceholderIfNeeded(clonedBlockquote.get()); |
| 195 | 181 |
| 196 // Put the selection right before the break. | 182 // Put the selection right before the break. |
| 197 setEndingSelection(VisibleSelection(positionBeforeNode(breakNode.get()), DOW
NSTREAM, endingSelection().isDirectional())); | 183 setEndingSelection(VisibleSelection(positionBeforeNode(breakNode.get()), DOW
NSTREAM, endingSelection().isDirectional())); |
| 198 rebalanceWhitespace(); | 184 rebalanceWhitespace(); |
| 199 } | 185 } |
| 200 | 186 |
| 201 } // namespace WebCore | 187 } // namespace WebCore |
| OLD | NEW |