| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2009, 2010, 2011 Google Inc. All rights reserved. | 3 * Copyright (C) 2009, 2010, 2011 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 1189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1200 // FIXME: We should only expand to include fully selected special elements | 1200 // FIXME: We should only expand to include fully selected special elements |
| 1201 // if we are copying a selection and pasting it on top of itself. | 1201 // if we are copying a selection and pasting it on top of itself. |
| 1202 deleteSelection(editingState, false, mergeBlocksAfterDelete, false); | 1202 deleteSelection(editingState, false, mergeBlocksAfterDelete, false); |
| 1203 if (editingState->isAborted()) | 1203 if (editingState->isAborted()) |
| 1204 return; | 1204 return; |
| 1205 if (fragment.hasInterchangeNewlineAtStart()) { | 1205 if (fragment.hasInterchangeNewlineAtStart()) { |
| 1206 document().updateStyleAndLayoutIgnorePendingStylesheets(); | 1206 document().updateStyleAndLayoutIgnorePendingStylesheets(); |
| 1207 VisiblePosition startAfterDelete = endingSelection().visibleStart(); | 1207 VisiblePosition startAfterDelete = endingSelection().visibleStart(); |
| 1208 if (isEndOfParagraph(startAfterDelete) && | 1208 if (isEndOfParagraph(startAfterDelete) && |
| 1209 !isStartOfParagraph(startAfterDelete) && | 1209 !isStartOfParagraph(startAfterDelete) && |
| 1210 !isEndOfEditableOrNonEditableContent(startAfterDelete)) | 1210 !isEndOfEditableOrNonEditableContent(startAfterDelete)) { |
| 1211 setEndingSelection(nextPositionOf(startAfterDelete)); | 1211 setEndingSelection( |
| 1212 else | 1212 SelectionInDOMTree::Builder() |
| 1213 .collapse(nextPositionOf(startAfterDelete).deepEquivalent()) |
| 1214 .build()); |
| 1215 } else { |
| 1213 insertParagraphSeparator(editingState); | 1216 insertParagraphSeparator(editingState); |
| 1217 } |
| 1214 if (editingState->isAborted()) | 1218 if (editingState->isAborted()) |
| 1215 return; | 1219 return; |
| 1216 } | 1220 } |
| 1217 } else { | 1221 } else { |
| 1218 DCHECK(selection.isCaret()); | 1222 DCHECK(selection.isCaret()); |
| 1219 if (fragment.hasInterchangeNewlineAtStart()) { | 1223 if (fragment.hasInterchangeNewlineAtStart()) { |
| 1220 const VisiblePosition next = | 1224 const VisiblePosition next = |
| 1221 nextPositionOf(visibleStart, CannotCrossEditingBoundary); | 1225 nextPositionOf(visibleStart, CannotCrossEditingBoundary); |
| 1222 if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleStart) && | 1226 if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleStart) && |
| 1223 next.isNotNull()) { | 1227 next.isNotNull()) { |
| 1224 setEndingSelection(next); | 1228 setEndingSelection(SelectionInDOMTree::Builder() |
| 1229 .collapse(next.deepEquivalent()) |
| 1230 .build()); |
| 1225 } else { | 1231 } else { |
| 1226 insertParagraphSeparator(editingState); | 1232 insertParagraphSeparator(editingState); |
| 1227 if (editingState->isAborted()) | 1233 if (editingState->isAborted()) |
| 1228 return; | 1234 return; |
| 1229 document().updateStyleAndLayoutIgnorePendingStylesheets(); | 1235 document().updateStyleAndLayoutIgnorePendingStylesheets(); |
| 1230 } | 1236 } |
| 1231 } | 1237 } |
| 1232 // We split the current paragraph in two to avoid nesting the blocks from | 1238 // We split the current paragraph in two to avoid nesting the blocks from |
| 1233 // the fragment inside the current block. | 1239 // the fragment inside the current block. |
| 1234 // | 1240 // |
| 1235 // For example, paste | 1241 // For example, paste |
| 1236 // <div>foo</div><div>bar</div><div>baz</div> | 1242 // <div>foo</div><div>bar</div><div>baz</div> |
| 1237 // into | 1243 // into |
| 1238 // <div>x^x</div> | 1244 // <div>x^x</div> |
| 1239 // where ^ is the caret. | 1245 // where ^ is the caret. |
| 1240 // | 1246 // |
| 1241 // As long as the div styles are the same, visually you'd expect: | 1247 // As long as the div styles are the same, visually you'd expect: |
| 1242 // <div>xbar</div><div>bar</div><div>bazx</div> | 1248 // <div>xbar</div><div>bar</div><div>bazx</div> |
| 1243 // not | 1249 // not |
| 1244 // <div>xbar<div>bar</div><div>bazx</div></div> | 1250 // <div>xbar<div>bar</div><div>bazx</div></div> |
| 1245 // Don't do this if the selection started in a Mail blockquote. | 1251 // Don't do this if the selection started in a Mail blockquote. |
| 1246 if (m_preventNesting && !startIsInsideMailBlockquote && | 1252 if (m_preventNesting && !startIsInsideMailBlockquote && |
| 1247 !isEndOfParagraph(endingSelection().visibleStart()) && | 1253 !isEndOfParagraph(endingSelection().visibleStart()) && |
| 1248 !isStartOfParagraph(endingSelection().visibleStart())) { | 1254 !isStartOfParagraph(endingSelection().visibleStart())) { |
| 1249 insertParagraphSeparator(editingState); | 1255 insertParagraphSeparator(editingState); |
| 1250 if (editingState->isAborted()) | 1256 if (editingState->isAborted()) |
| 1251 return; | 1257 return; |
| 1252 document().updateStyleAndLayoutIgnorePendingStylesheets(); | 1258 document().updateStyleAndLayoutIgnorePendingStylesheets(); |
| 1253 setEndingSelection(previousPositionOf(endingSelection().visibleStart())); | 1259 setEndingSelection( |
| 1260 SelectionInDOMTree::Builder() |
| 1261 .collapse(previousPositionOf(endingSelection().visibleStart()) |
| 1262 .deepEquivalent()) |
| 1263 .build()); |
| 1254 } | 1264 } |
| 1255 } | 1265 } |
| 1256 | 1266 |
| 1257 Position insertionPos = endingSelection().start(); | 1267 Position insertionPos = endingSelection().start(); |
| 1258 // We don't want any of the pasted content to end up nested in a Mail | 1268 // We don't want any of the pasted content to end up nested in a Mail |
| 1259 // blockquote, so first break out of any surrounding Mail blockquotes. Unless | 1269 // blockquote, so first break out of any surrounding Mail blockquotes. Unless |
| 1260 // we're inserting in a table, in which case breaking the blockquote will | 1270 // we're inserting in a table, in which case breaking the blockquote will |
| 1261 // prevent the content from actually being inserted in the table. | 1271 // prevent the content from actually being inserted in the table. |
| 1262 if (enclosingNodeOfType(insertionPos, isMailHTMLBlockquoteElement, | 1272 if (enclosingNodeOfType(insertionPos, isMailHTMLBlockquoteElement, |
| 1263 CanCrossEditingBoundary) && | 1273 CanCrossEditingBoundary) && |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1620 if (selectionEndWasEndOfParagraph || | 1630 if (selectionEndWasEndOfParagraph || |
| 1621 !isEndOfParagraph(endOfInsertedContent) || next.isNull()) { | 1631 !isEndOfParagraph(endOfInsertedContent) || next.isNull()) { |
| 1622 if (HTMLTextFormControlElement* textControl = | 1632 if (HTMLTextFormControlElement* textControl = |
| 1623 enclosingTextFormControl(currentRoot)) { | 1633 enclosingTextFormControl(currentRoot)) { |
| 1624 if (!insertedNodes.lastLeafInserted()->nextSibling()) { | 1634 if (!insertedNodes.lastLeafInserted()->nextSibling()) { |
| 1625 insertNodeAfter(textControl->createPlaceholderBreakElement(), | 1635 insertNodeAfter(textControl->createPlaceholderBreakElement(), |
| 1626 insertedNodes.lastLeafInserted(), editingState); | 1636 insertedNodes.lastLeafInserted(), editingState); |
| 1627 if (editingState->isAborted()) | 1637 if (editingState->isAborted()) |
| 1628 return; | 1638 return; |
| 1629 } | 1639 } |
| 1630 document().updateStyleAndLayoutIgnorePendingStylesheets(); | |
| 1631 setEndingSelection( | 1640 setEndingSelection( |
| 1632 VisiblePosition::afterNode(insertedNodes.lastLeafInserted())); | 1641 SelectionInDOMTree::Builder() |
| 1642 .collapse(Position::afterNode(insertedNodes.lastLeafInserted())) |
| 1643 .build()); |
| 1633 // Select up to the paragraph separator that was added. | 1644 // Select up to the paragraph separator that was added. |
| 1634 lastPositionToSelect = | 1645 lastPositionToSelect = |
| 1635 endingSelection().visibleStart().deepEquivalent(); | 1646 endingSelection().visibleStart().deepEquivalent(); |
| 1636 } else if (!isStartOfParagraph(endOfInsertedContent)) { | 1647 } else if (!isStartOfParagraph(endOfInsertedContent)) { |
| 1637 setEndingSelection(endOfInsertedContent); | 1648 setEndingSelection(SelectionInDOMTree::Builder() |
| 1649 .collapse(endOfInsertedContent.deepEquivalent()) |
| 1650 .build()); |
| 1638 Element* enclosingBlockElement = | 1651 Element* enclosingBlockElement = |
| 1639 enclosingBlock(endOfInsertedContent.deepEquivalent().anchorNode()); | 1652 enclosingBlock(endOfInsertedContent.deepEquivalent().anchorNode()); |
| 1640 if (isListItem(enclosingBlockElement)) { | 1653 if (isListItem(enclosingBlockElement)) { |
| 1641 HTMLLIElement* newListItem = HTMLLIElement::create(document()); | 1654 HTMLLIElement* newListItem = HTMLLIElement::create(document()); |
| 1642 insertNodeAfter(newListItem, enclosingBlockElement, editingState); | 1655 insertNodeAfter(newListItem, enclosingBlockElement, editingState); |
| 1643 if (editingState->isAborted()) | 1656 if (editingState->isAborted()) |
| 1644 return; | 1657 return; |
| 1645 document().updateStyleAndLayoutIgnorePendingStylesheets(); | 1658 setEndingSelection( |
| 1646 setEndingSelection(VisiblePosition::firstPositionInNode(newListItem)); | 1659 SelectionInDOMTree::Builder() |
| 1660 .collapse(Position::firstPositionInNode(newListItem)) |
| 1661 .build()); |
| 1647 } else { | 1662 } else { |
| 1648 // Use a default paragraph element (a plain div) for the empty | 1663 // Use a default paragraph element (a plain div) for the empty |
| 1649 // paragraph, using the last paragraph block's style seems to annoy | 1664 // paragraph, using the last paragraph block's style seems to annoy |
| 1650 // users. | 1665 // users. |
| 1651 insertParagraphSeparator( | 1666 insertParagraphSeparator( |
| 1652 editingState, true, | 1667 editingState, true, |
| 1653 !startIsInsideMailBlockquote && | 1668 !startIsInsideMailBlockquote && |
| 1654 highestEnclosingNodeOfType( | 1669 highestEnclosingNodeOfType( |
| 1655 endOfInsertedContent.deepEquivalent(), | 1670 endOfInsertedContent.deepEquivalent(), |
| 1656 isMailHTMLBlockquoteElement, CannotCrossEditingBoundary, | 1671 isMailHTMLBlockquoteElement, CannotCrossEditingBoundary, |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2102 visitor->trace(m_startOfInsertedContent); | 2117 visitor->trace(m_startOfInsertedContent); |
| 2103 visitor->trace(m_endOfInsertedContent); | 2118 visitor->trace(m_endOfInsertedContent); |
| 2104 visitor->trace(m_insertionStyle); | 2119 visitor->trace(m_insertionStyle); |
| 2105 visitor->trace(m_documentFragment); | 2120 visitor->trace(m_documentFragment); |
| 2106 visitor->trace(m_startOfInsertedRange); | 2121 visitor->trace(m_startOfInsertedRange); |
| 2107 visitor->trace(m_endOfInsertedRange); | 2122 visitor->trace(m_endOfInsertedRange); |
| 2108 CompositeEditCommand::trace(visitor); | 2123 CompositeEditCommand::trace(visitor); |
| 2109 } | 2124 } |
| 2110 | 2125 |
| 2111 } // namespace blink | 2126 } // namespace blink |
| OLD | NEW |