| 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 | 93 |
| 94 // pos is a position equivalent to the caret. We use downstream() so that p
os will | 94 // pos is a position equivalent to the caret. We use downstream() so that p
os will |
| 95 // be in the first node that we need to move (there are a few exceptions to
this, see below). | 95 // be in the first node that we need to move (there are a few exceptions to
this, see below). |
| 96 Position pos = mostForwardCaretPosition(endingSelection().start()); | 96 Position pos = mostForwardCaretPosition(endingSelection().start()); |
| 97 | 97 |
| 98 // Find the top-most blockquote from the start. | 98 // Find the top-most blockquote from the start. |
| 99 HTMLQuoteElement* topBlockquote = toHTMLQuoteElement(highestEnclosingNodeOfT
ype(pos, isMailHTMLBlockquoteElement)); | 99 HTMLQuoteElement* topBlockquote = toHTMLQuoteElement(highestEnclosingNodeOfT
ype(pos, isMailHTMLBlockquoteElement)); |
| 100 if (!topBlockquote || !topBlockquote->parentNode()) | 100 if (!topBlockquote || !topBlockquote->parentNode()) |
| 101 return; | 101 return; |
| 102 | 102 |
| 103 RefPtrWillBeRawPtr<HTMLBRElement> breakElement = HTMLBRElement::create(docum
ent()); | 103 RawPtr<HTMLBRElement> breakElement = HTMLBRElement::create(document()); |
| 104 | 104 |
| 105 bool isLastVisPosInNode = isLastVisiblePositionInNode(visiblePos, topBlockqu
ote); | 105 bool isLastVisPosInNode = isLastVisiblePositionInNode(visiblePos, topBlockqu
ote); |
| 106 | 106 |
| 107 // If the position is at the beginning of the top quoted content, we don't n
eed to break the quote. | 107 // If the position is at the beginning of the top quoted content, we don't n
eed to break the quote. |
| 108 // Instead, insert the break before the blockquote, unless the position is a
s the end of the the quoted content. | 108 // Instead, insert the break before the blockquote, unless the position is a
s the end of the the quoted content. |
| 109 if (isFirstVisiblePositionInNode(visiblePos, topBlockquote) && !isLastVisPos
InNode) { | 109 if (isFirstVisiblePositionInNode(visiblePos, topBlockquote) && !isLastVisPos
InNode) { |
| 110 insertNodeBefore(breakElement.get(), topBlockquote); | 110 insertNodeBefore(breakElement.get(), topBlockquote); |
| 111 setEndingSelection(VisibleSelection(positionBeforeNode(breakElement.get(
)), TextAffinity::Downstream, endingSelection().isDirectional())); | 111 setEndingSelection(VisibleSelection(positionBeforeNode(breakElement.get(
)), TextAffinity::Downstream, endingSelection().isDirectional())); |
| 112 rebalanceWhitespace(); | 112 rebalanceWhitespace(); |
| 113 return; | 113 return; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 ASSERT(startNode); | 158 ASSERT(startNode); |
| 159 } | 159 } |
| 160 | 160 |
| 161 // If there's nothing inside topBlockquote to move, we're finished. | 161 // If there's nothing inside topBlockquote to move, we're finished. |
| 162 if (!startNode->isDescendantOf(topBlockquote)) { | 162 if (!startNode->isDescendantOf(topBlockquote)) { |
| 163 setEndingSelection(VisibleSelection(createVisiblePosition(firstPositionI
nOrBeforeNode(startNode)), endingSelection().isDirectional())); | 163 setEndingSelection(VisibleSelection(createVisiblePosition(firstPositionI
nOrBeforeNode(startNode)), endingSelection().isDirectional())); |
| 164 return; | 164 return; |
| 165 } | 165 } |
| 166 | 166 |
| 167 // Build up list of ancestors in between the start node and the top blockquo
te. | 167 // Build up list of ancestors in between the start node and the top blockquo
te. |
| 168 WillBeHeapVector<RefPtrWillBeMember<Element>> ancestors; | 168 HeapVector<Member<Element>> ancestors; |
| 169 for (Element* node = startNode->parentElement(); node && node != topBlockquo
te; node = node->parentElement()) | 169 for (Element* node = startNode->parentElement(); node && node != topBlockquo
te; node = node->parentElement()) |
| 170 ancestors.append(node); | 170 ancestors.append(node); |
| 171 | 171 |
| 172 // Insert a clone of the top blockquote after the break. | 172 // Insert a clone of the top blockquote after the break. |
| 173 RefPtrWillBeRawPtr<Element> clonedBlockquote = topBlockquote->cloneElementWi
thoutChildren(); | 173 RawPtr<Element> clonedBlockquote = topBlockquote->cloneElementWithoutChildre
n(); |
| 174 insertNodeAfter(clonedBlockquote.get(), breakElement.get()); | 174 insertNodeAfter(clonedBlockquote.get(), breakElement.get()); |
| 175 | 175 |
| 176 // Clone startNode's ancestors into the cloned blockquote. | 176 // Clone startNode's ancestors into the cloned blockquote. |
| 177 // On exiting this loop, clonedAncestor is the lowest ancestor | 177 // On exiting this loop, clonedAncestor is the lowest ancestor |
| 178 // that was cloned (i.e. the clone of either ancestors.last() | 178 // that was cloned (i.e. the clone of either ancestors.last() |
| 179 // or clonedBlockquote if ancestors is empty). | 179 // or clonedBlockquote if ancestors is empty). |
| 180 RefPtrWillBeRawPtr<Element> clonedAncestor = clonedBlockquote; | 180 RawPtr<Element> clonedAncestor = clonedBlockquote; |
| 181 for (size_t i = ancestors.size(); i != 0; --i) { | 181 for (size_t i = ancestors.size(); i != 0; --i) { |
| 182 RefPtrWillBeRawPtr<Element> clonedChild = ancestors[i - 1]->cloneElement
WithoutChildren(); | 182 RawPtr<Element> clonedChild = ancestors[i - 1]->cloneElementWithoutChild
ren(); |
| 183 // Preserve list item numbering in cloned lists. | 183 // Preserve list item numbering in cloned lists. |
| 184 if (isHTMLOListElement(*clonedChild)) { | 184 if (isHTMLOListElement(*clonedChild)) { |
| 185 Node* listChildNode = i > 1 ? ancestors[i - 2].get() : startNode; | 185 Node* listChildNode = i > 1 ? ancestors[i - 2].get() : startNode; |
| 186 // The first child of the cloned list might not be a list item eleme
nt, | 186 // The first child of the cloned list might not be a list item eleme
nt, |
| 187 // find the first one so that we know where to start numbering. | 187 // find the first one so that we know where to start numbering. |
| 188 while (listChildNode && !isHTMLLIElement(*listChildNode)) | 188 while (listChildNode && !isHTMLLIElement(*listChildNode)) |
| 189 listChildNode = listChildNode->nextSibling(); | 189 listChildNode = listChildNode->nextSibling(); |
| 190 if (isListItem(listChildNode)) | 190 if (isListItem(listChildNode)) |
| 191 setNodeAttribute(clonedChild, startAttr, AtomicString::number(to
LayoutListItem(listChildNode->layoutObject())->value())); | 191 setNodeAttribute(clonedChild, startAttr, AtomicString::number(to
LayoutListItem(listChildNode->layoutObject())->value())); |
| 192 } | 192 } |
| 193 | 193 |
| 194 appendNode(clonedChild.get(), clonedAncestor.get()); | 194 appendNode(clonedChild.get(), clonedAncestor.get()); |
| 195 clonedAncestor = clonedChild; | 195 clonedAncestor = clonedChild; |
| 196 } | 196 } |
| 197 | 197 |
| 198 moveRemainingSiblingsToNewParent(startNode, 0, clonedAncestor); | 198 moveRemainingSiblingsToNewParent(startNode, 0, clonedAncestor); |
| 199 | 199 |
| 200 if (!ancestors.isEmpty()) { | 200 if (!ancestors.isEmpty()) { |
| 201 // Split the tree up the ancestor chain until the topBlockquote | 201 // Split the tree up the ancestor chain until the topBlockquote |
| 202 // Throughout this loop, clonedParent is the clone of ancestor's parent. | 202 // Throughout this loop, clonedParent is the clone of ancestor's parent. |
| 203 // This is so we can clone ancestor's siblings and place the clones | 203 // This is so we can clone ancestor's siblings and place the clones |
| 204 // into the clone corresponding to the ancestor's parent. | 204 // into the clone corresponding to the ancestor's parent. |
| 205 RefPtrWillBeRawPtr<Element> ancestor = nullptr; | 205 RawPtr<Element> ancestor = nullptr; |
| 206 RefPtrWillBeRawPtr<Element> clonedParent = nullptr; | 206 RawPtr<Element> clonedParent = nullptr; |
| 207 for (ancestor = ancestors.first(), clonedParent = clonedAncestor->parent
Element(); | 207 for (ancestor = ancestors.first(), clonedParent = clonedAncestor->parent
Element(); |
| 208 ancestor && ancestor != topBlockquote; | 208 ancestor && ancestor != topBlockquote; |
| 209 ancestor = ancestor->parentElement(), clonedParent = clonedParent->p
arentElement()) | 209 ancestor = ancestor->parentElement(), clonedParent = clonedParent->p
arentElement()) |
| 210 moveRemainingSiblingsToNewParent(ancestor->nextSibling(), 0, clonedP
arent); | 210 moveRemainingSiblingsToNewParent(ancestor->nextSibling(), 0, clonedP
arent); |
| 211 | 211 |
| 212 // If the startNode's original parent is now empty, remove it | 212 // If the startNode's original parent is now empty, remove it |
| 213 Element* originalParent = ancestors.first().get(); | 213 Element* originalParent = ancestors.first().get(); |
| 214 if (!originalParent->hasChildren()) | 214 if (!originalParent->hasChildren()) |
| 215 removeNode(originalParent); | 215 removeNode(originalParent); |
| 216 } | 216 } |
| 217 | 217 |
| 218 // Make sure the cloned block quote renders. | 218 // Make sure the cloned block quote renders. |
| 219 addBlockPlaceholderIfNeeded(clonedBlockquote.get()); | 219 addBlockPlaceholderIfNeeded(clonedBlockquote.get()); |
| 220 | 220 |
| 221 // Put the selection right before the break. | 221 // Put the selection right before the break. |
| 222 setEndingSelection(VisibleSelection(positionBeforeNode(breakElement.get()),
TextAffinity::Downstream, endingSelection().isDirectional())); | 222 setEndingSelection(VisibleSelection(positionBeforeNode(breakElement.get()),
TextAffinity::Downstream, endingSelection().isDirectional())); |
| 223 rebalanceWhitespace(); | 223 rebalanceWhitespace(); |
| 224 } | 224 } |
| 225 | 225 |
| 226 } // namespace blink | 226 } // namespace blink |
| OLD | NEW |