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 |