| 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 13 matching lines...) Expand all Loading... |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "config.h" | 26 #include "config.h" |
| 27 #include "core/editing/BreakBlockquoteCommand.h" | 27 #include "core/editing/BreakBlockquoteCommand.h" |
| 28 | 28 |
| 29 #include "core/HTMLNames.h" | 29 #include "core/HTMLNames.h" |
| 30 #include "core/dom/NodeTraversal.h" | 30 #include "core/dom/NodeTraversal.h" |
| 31 #include "core/dom/Text.h" | 31 #include "core/dom/Text.h" |
| 32 #include "core/editing/VisiblePosition.h" | 32 #include "core/editing/VisiblePosition.h" |
| 33 #include "core/editing/htmlediting.h" | 33 #include "core/editing/htmlediting.h" |
| 34 #include "core/html/HTMLBRElement.h" |
| 34 #include "core/html/HTMLElement.h" | 35 #include "core/html/HTMLElement.h" |
| 35 #include "core/rendering/RenderListItem.h" | 36 #include "core/rendering/RenderListItem.h" |
| 36 | 37 |
| 37 namespace blink { | 38 namespace blink { |
| 38 | 39 |
| 39 using namespace HTMLNames; | 40 using namespace HTMLNames; |
| 40 | 41 |
| 41 BreakBlockquoteCommand::BreakBlockquoteCommand(Document& document) | 42 BreakBlockquoteCommand::BreakBlockquoteCommand(Document& document) |
| 42 : CompositeEditCommand(document) | 43 : CompositeEditCommand(document) |
| 43 { | 44 { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 64 | 65 |
| 65 // pos is a position equivalent to the caret. We use downstream() so that p
os will | 66 // pos is a position equivalent to the caret. We use downstream() so that p
os will |
| 66 // be in the first node that we need to move (there are a few exceptions to
this, see below). | 67 // be in the first node that we need to move (there are a few exceptions to
this, see below). |
| 67 Position pos = endingSelection().start().downstream(); | 68 Position pos = endingSelection().start().downstream(); |
| 68 | 69 |
| 69 // Find the top-most blockquote from the start. | 70 // Find the top-most blockquote from the start. |
| 70 Node* topBlockquote = highestEnclosingNodeOfType(pos, isMailBlockquote); | 71 Node* topBlockquote = highestEnclosingNodeOfType(pos, isMailBlockquote); |
| 71 if (!topBlockquote || !topBlockquote->parentNode() || !topBlockquote->isElem
entNode()) | 72 if (!topBlockquote || !topBlockquote->parentNode() || !topBlockquote->isElem
entNode()) |
| 72 return; | 73 return; |
| 73 | 74 |
| 74 RefPtrWillBeRawPtr<Element> breakNode = createBreakElement(document()); | 75 RefPtrWillBeRawPtr<HTMLBRElement> breakElement = createBreakElement(document
()); |
| 75 | 76 |
| 76 bool isLastVisPosInNode = isLastVisiblePositionInNode(visiblePos, topBlockqu
ote); | 77 bool isLastVisPosInNode = isLastVisiblePositionInNode(visiblePos, topBlockqu
ote); |
| 77 | 78 |
| 78 // If the position is at the beginning of the top quoted content, we don't n
eed to break the quote. | 79 // If the position is at the beginning of the top quoted content, we don't n
eed to break the quote. |
| 79 // Instead, insert the break before the blockquote, unless the position is a
s the end of the the quoted content. | 80 // Instead, insert the break before the blockquote, unless the position is a
s the end of the the quoted content. |
| 80 if (isFirstVisiblePositionInNode(visiblePos, topBlockquote) && !isLastVisPos
InNode) { | 81 if (isFirstVisiblePositionInNode(visiblePos, topBlockquote) && !isLastVisPos
InNode) { |
| 81 insertNodeBefore(breakNode.get(), topBlockquote); | 82 insertNodeBefore(breakElement.get(), topBlockquote); |
| 82 setEndingSelection(VisibleSelection(positionBeforeNode(breakNode.get()),
DOWNSTREAM, endingSelection().isDirectional())); | 83 setEndingSelection(VisibleSelection(positionBeforeNode(breakElement.get(
)), DOWNSTREAM, endingSelection().isDirectional())); |
| 83 rebalanceWhitespace(); | 84 rebalanceWhitespace(); |
| 84 return; | 85 return; |
| 85 } | 86 } |
| 86 | 87 |
| 87 // Insert a break after the top blockquote. | 88 // Insert a break after the top blockquote. |
| 88 insertNodeAfter(breakNode.get(), topBlockquote); | 89 insertNodeAfter(breakElement.get(), topBlockquote); |
| 89 | 90 |
| 90 // If we're inserting the break at the end of the quoted content, we don't n
eed to break the quote. | 91 // If we're inserting the break at the end of the quoted content, we don't n
eed to break the quote. |
| 91 if (isLastVisPosInNode) { | 92 if (isLastVisPosInNode) { |
| 92 setEndingSelection(VisibleSelection(positionBeforeNode(breakNode.get()),
DOWNSTREAM, endingSelection().isDirectional())); | 93 setEndingSelection(VisibleSelection(positionBeforeNode(breakElement.get(
)), DOWNSTREAM, endingSelection().isDirectional())); |
| 93 rebalanceWhitespace(); | 94 rebalanceWhitespace(); |
| 94 return; | 95 return; |
| 95 } | 96 } |
| 96 | 97 |
| 97 // Don't move a line break just after the caret. Doing so would create an e
xtra, empty paragraph | 98 // Don't move a line break just after the caret. Doing so would create an e
xtra, empty paragraph |
| 98 // in the new blockquote. | 99 // in the new blockquote. |
| 99 if (lineBreakExistsAtVisiblePosition(visiblePos)) | 100 if (lineBreakExistsAtVisiblePosition(visiblePos)) |
| 100 pos = pos.next(); | 101 pos = pos.next(); |
| 101 | 102 |
| 102 // Adjust the position so we don't split at the beginning of a quote. | 103 // Adjust the position so we don't split at the beginning of a quote. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 127 return; | 128 return; |
| 128 } | 129 } |
| 129 | 130 |
| 130 // Build up list of ancestors in between the start node and the top blockquo
te. | 131 // Build up list of ancestors in between the start node and the top blockquo
te. |
| 131 WillBeHeapVector<RefPtrWillBeMember<Element> > ancestors; | 132 WillBeHeapVector<RefPtrWillBeMember<Element> > ancestors; |
| 132 for (Element* node = startNode->parentElement(); node && node != topBlockquo
te; node = node->parentElement()) | 133 for (Element* node = startNode->parentElement(); node && node != topBlockquo
te; node = node->parentElement()) |
| 133 ancestors.append(node); | 134 ancestors.append(node); |
| 134 | 135 |
| 135 // Insert a clone of the top blockquote after the break. | 136 // Insert a clone of the top blockquote after the break. |
| 136 RefPtrWillBeRawPtr<Element> clonedBlockquote = toElement(topBlockquote)->clo
neElementWithoutChildren(); | 137 RefPtrWillBeRawPtr<Element> clonedBlockquote = toElement(topBlockquote)->clo
neElementWithoutChildren(); |
| 137 insertNodeAfter(clonedBlockquote.get(), breakNode.get()); | 138 insertNodeAfter(clonedBlockquote.get(), breakElement.get()); |
| 138 | 139 |
| 139 // Clone startNode's ancestors into the cloned blockquote. | 140 // Clone startNode's ancestors into the cloned blockquote. |
| 140 // On exiting this loop, clonedAncestor is the lowest ancestor | 141 // On exiting this loop, clonedAncestor is the lowest ancestor |
| 141 // that was cloned (i.e. the clone of either ancestors.last() | 142 // that was cloned (i.e. the clone of either ancestors.last() |
| 142 // or clonedBlockquote if ancestors is empty). | 143 // or clonedBlockquote if ancestors is empty). |
| 143 RefPtrWillBeRawPtr<Element> clonedAncestor = clonedBlockquote; | 144 RefPtrWillBeRawPtr<Element> clonedAncestor = clonedBlockquote; |
| 144 for (size_t i = ancestors.size(); i != 0; --i) { | 145 for (size_t i = ancestors.size(); i != 0; --i) { |
| 145 RefPtrWillBeRawPtr<Element> clonedChild = ancestors[i - 1]->cloneElement
WithoutChildren(); | 146 RefPtrWillBeRawPtr<Element> clonedChild = ancestors[i - 1]->cloneElement
WithoutChildren(); |
| 146 // Preserve list item numbering in cloned lists. | 147 // Preserve list item numbering in cloned lists. |
| 147 if (isHTMLOListElement(*clonedChild)) { | 148 if (isHTMLOListElement(*clonedChild)) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 175 // If the startNode's original parent is now empty, remove it | 176 // If the startNode's original parent is now empty, remove it |
| 176 Node* originalParent = ancestors.first().get(); | 177 Node* originalParent = ancestors.first().get(); |
| 177 if (!originalParent->hasChildren()) | 178 if (!originalParent->hasChildren()) |
| 178 removeNode(originalParent); | 179 removeNode(originalParent); |
| 179 } | 180 } |
| 180 | 181 |
| 181 // Make sure the cloned block quote renders. | 182 // Make sure the cloned block quote renders. |
| 182 addBlockPlaceholderIfNeeded(clonedBlockquote.get()); | 183 addBlockPlaceholderIfNeeded(clonedBlockquote.get()); |
| 183 | 184 |
| 184 // Put the selection right before the break. | 185 // Put the selection right before the break. |
| 185 setEndingSelection(VisibleSelection(positionBeforeNode(breakNode.get()), DOW
NSTREAM, endingSelection().isDirectional())); | 186 setEndingSelection(VisibleSelection(positionBeforeNode(breakElement.get()),
DOWNSTREAM, endingSelection().isDirectional())); |
| 186 rebalanceWhitespace(); | 187 rebalanceWhitespace(); |
| 187 } | 188 } |
| 188 | 189 |
| 189 } // namespace blink | 190 } // namespace blink |
| OLD | NEW |