| 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 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 return !selectionStartWasStartOfParagraph | 415 return !selectionStartWasStartOfParagraph |
| 416 && !fragmentHasInterchangeNewlineAtStart | 416 && !fragmentHasInterchangeNewlineAtStart |
| 417 && isStartOfParagraph(startOfInsertedContent) | 417 && isStartOfParagraph(startOfInsertedContent) |
| 418 && !isHTMLBRElement(*startOfInsertedContent.deepEquivalent().anchorNode(
)) | 418 && !isHTMLBRElement(*startOfInsertedContent.deepEquivalent().anchorNode(
)) |
| 419 && shouldMerge(startOfInsertedContent, prev); | 419 && shouldMerge(startOfInsertedContent, prev); |
| 420 } | 420 } |
| 421 | 421 |
| 422 bool ReplaceSelectionCommand::shouldMergeEnd(bool selectionEndWasEndOfParagraph) | 422 bool ReplaceSelectionCommand::shouldMergeEnd(bool selectionEndWasEndOfParagraph) |
| 423 { | 423 { |
| 424 VisiblePosition endOfInsertedContent(positionAtEndOfInsertedContent()); | 424 VisiblePosition endOfInsertedContent(positionAtEndOfInsertedContent()); |
| 425 VisiblePosition next = endOfInsertedContent.next(CannotCrossEditingBoundary)
; | 425 VisiblePosition next = nextPositionOf(endOfInsertedContent, CannotCrossEditi
ngBoundary); |
| 426 if (next.isNull()) | 426 if (next.isNull()) |
| 427 return false; | 427 return false; |
| 428 | 428 |
| 429 return !selectionEndWasEndOfParagraph | 429 return !selectionEndWasEndOfParagraph |
| 430 && isEndOfParagraph(endOfInsertedContent) | 430 && isEndOfParagraph(endOfInsertedContent) |
| 431 && !isHTMLBRElement(*endOfInsertedContent.deepEquivalent().anchorNode()) | 431 && !isHTMLBRElement(*endOfInsertedContent.deepEquivalent().anchorNode()) |
| 432 && shouldMerge(endOfInsertedContent, next); | 432 && shouldMerge(endOfInsertedContent, next); |
| 433 } | 433 } |
| 434 | 434 |
| 435 static bool isMailPasteAsQuotationHTMLBlockQuoteElement(const Node* node) | 435 static bool isMailPasteAsQuotationHTMLBlockQuoteElement(const Node* node) |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 835 ASSERT_NOT_REACHED(); | 835 ASSERT_NOT_REACHED(); |
| 836 return; | 836 return; |
| 837 } | 837 } |
| 838 | 838 |
| 839 // Merging two paragraphs will destroy the moved one's block styles. Always
move the end of inserted forward | 839 // Merging two paragraphs will destroy the moved one's block styles. Always
move the end of inserted forward |
| 840 // to preserve the block style of the paragraph already in the document, unl
ess the paragraph to move would | 840 // to preserve the block style of the paragraph already in the document, unl
ess the paragraph to move would |
| 841 // include the what was the start of the selection that was pasted into, so
that we preserve that paragraph's | 841 // include the what was the start of the selection that was pasted into, so
that we preserve that paragraph's |
| 842 // block styles. | 842 // block styles. |
| 843 bool mergeForward = !(inSameParagraph(startOfInsertedContent, endOfInsertedC
ontent) && !isStartOfParagraph(startOfInsertedContent)); | 843 bool mergeForward = !(inSameParagraph(startOfInsertedContent, endOfInsertedC
ontent) && !isStartOfParagraph(startOfInsertedContent)); |
| 844 | 844 |
| 845 VisiblePosition destination = mergeForward ? endOfInsertedContent.next() : e
ndOfInsertedContent; | 845 VisiblePosition destination = mergeForward ? nextPositionOf(endOfInsertedCon
tent) : endOfInsertedContent; |
| 846 VisiblePosition startOfParagraphToMove = mergeForward ? startOfParagraph(end
OfInsertedContent) : endOfInsertedContent.next(); | 846 VisiblePosition startOfParagraphToMove = mergeForward ? startOfParagraph(end
OfInsertedContent) : nextPositionOf(endOfInsertedContent); |
| 847 | 847 |
| 848 // Merging forward could result in deleting the destination anchor node. | 848 // Merging forward could result in deleting the destination anchor node. |
| 849 // To avoid this, we add a placeholder node before the start of the paragrap
h. | 849 // To avoid this, we add a placeholder node before the start of the paragrap
h. |
| 850 if (endOfParagraph(startOfParagraphToMove).deepEquivalent() == destination.d
eepEquivalent()) { | 850 if (endOfParagraph(startOfParagraphToMove).deepEquivalent() == destination.d
eepEquivalent()) { |
| 851 RefPtrWillBeRawPtr<HTMLBRElement> placeholder = createBreakElement(docum
ent()); | 851 RefPtrWillBeRawPtr<HTMLBRElement> placeholder = createBreakElement(docum
ent()); |
| 852 insertNodeBefore(placeholder, startOfParagraphToMove.deepEquivalent().an
chorNode()); | 852 insertNodeBefore(placeholder, startOfParagraphToMove.deepEquivalent().an
chorNode()); |
| 853 destination = VisiblePosition(positionBeforeNode(placeholder.get())); | 853 destination = VisiblePosition(positionBeforeNode(placeholder.get())); |
| 854 } | 854 } |
| 855 | 855 |
| 856 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToMove)
, destination); | 856 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToMove)
, destination); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 970 // Merge blocks if the start of the selection was in a Mail blockquote,
since we handle | 970 // Merge blocks if the start of the selection was in a Mail blockquote,
since we handle |
| 971 // that case specially to prevent nesting. | 971 // that case specially to prevent nesting. |
| 972 bool mergeBlocksAfterDelete = startIsInsideMailBlockquote || isEndOfPara
graph(visibleEnd) || isStartOfBlock(visibleStart); | 972 bool mergeBlocksAfterDelete = startIsInsideMailBlockquote || isEndOfPara
graph(visibleEnd) || isStartOfBlock(visibleStart); |
| 973 // FIXME: We should only expand to include fully selected special elemen
ts if we are copying a | 973 // FIXME: We should only expand to include fully selected special elemen
ts if we are copying a |
| 974 // selection and pasting it on top of itself. | 974 // selection and pasting it on top of itself. |
| 975 deleteSelection(false, mergeBlocksAfterDelete, false); | 975 deleteSelection(false, mergeBlocksAfterDelete, false); |
| 976 visibleStart = endingSelection().visibleStart(); | 976 visibleStart = endingSelection().visibleStart(); |
| 977 if (fragment.hasInterchangeNewlineAtStart()) { | 977 if (fragment.hasInterchangeNewlineAtStart()) { |
| 978 if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleSta
rt)) { | 978 if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleSta
rt)) { |
| 979 if (!isEndOfEditableOrNonEditableContent(visibleStart)) | 979 if (!isEndOfEditableOrNonEditableContent(visibleStart)) |
| 980 setEndingSelection(visibleStart.next()); | 980 setEndingSelection(nextPositionOf(visibleStart)); |
| 981 } else { | 981 } else { |
| 982 insertParagraphSeparator(); | 982 insertParagraphSeparator(); |
| 983 } | 983 } |
| 984 } | 984 } |
| 985 insertionPos = endingSelection().start(); | 985 insertionPos = endingSelection().start(); |
| 986 } else { | 986 } else { |
| 987 ASSERT(selection.isCaret()); | 987 ASSERT(selection.isCaret()); |
| 988 if (fragment.hasInterchangeNewlineAtStart()) { | 988 if (fragment.hasInterchangeNewlineAtStart()) { |
| 989 VisiblePosition next = visibleStart.next(CannotCrossEditingBoundary)
; | 989 VisiblePosition next = nextPositionOf(visibleStart, CannotCrossEditi
ngBoundary); |
| 990 if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleSta
rt) && next.isNotNull()) { | 990 if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleSta
rt) && next.isNotNull()) { |
| 991 setEndingSelection(next); | 991 setEndingSelection(next); |
| 992 } else { | 992 } else { |
| 993 insertParagraphSeparator(); | 993 insertParagraphSeparator(); |
| 994 visibleStart = endingSelection().visibleStart(); | 994 visibleStart = endingSelection().visibleStart(); |
| 995 } | 995 } |
| 996 } | 996 } |
| 997 // We split the current paragraph in two to avoid nesting the blocks fro
m the fragment inside the current block. | 997 // We split the current paragraph in two to avoid nesting the blocks fro
m the fragment inside the current block. |
| 998 // For example paste <div>foo</div><div>bar</div><div>baz</div> into <di
v>x^x</div>, where ^ is the caret. | 998 // For example paste <div>foo</div><div>bar</div><div>baz</div> into <di
v>x^x</div>, where ^ is the caret. |
| 999 // As long as the div styles are the same, visually you'd expect: <div>
xbar</div><div>bar</div><div>bazx</div>, | 999 // As long as the div styles are the same, visually you'd expect: <div>
xbar</div><div>bar</div><div>bazx</div>, |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1220 // only ever used to create positions where inserted content starts/ends
. | 1220 // only ever used to create positions where inserted content starts/ends
. |
| 1221 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToM
ove), destination); | 1221 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToM
ove), destination); |
| 1222 m_startOfInsertedContent = mostForwardCaretPosition(endingSelection().vi
sibleStart().deepEquivalent()); | 1222 m_startOfInsertedContent = mostForwardCaretPosition(endingSelection().vi
sibleStart().deepEquivalent()); |
| 1223 if (m_endOfInsertedContent.isOrphan()) | 1223 if (m_endOfInsertedContent.isOrphan()) |
| 1224 m_endOfInsertedContent = mostBackwardCaretPosition(endingSelection()
.visibleEnd().deepEquivalent()); | 1224 m_endOfInsertedContent = mostBackwardCaretPosition(endingSelection()
.visibleEnd().deepEquivalent()); |
| 1225 } | 1225 } |
| 1226 | 1226 |
| 1227 Position lastPositionToSelect; | 1227 Position lastPositionToSelect; |
| 1228 if (fragment.hasInterchangeNewlineAtEnd()) { | 1228 if (fragment.hasInterchangeNewlineAtEnd()) { |
| 1229 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent(); | 1229 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent(); |
| 1230 VisiblePosition next = endOfInsertedContent.next(CannotCrossEditingBound
ary); | 1230 VisiblePosition next = nextPositionOf(endOfInsertedContent, CannotCrossE
ditingBoundary); |
| 1231 | 1231 |
| 1232 if (selectionEndWasEndOfParagraph || !isEndOfParagraph(endOfInsertedCont
ent) || next.isNull()) { | 1232 if (selectionEndWasEndOfParagraph || !isEndOfParagraph(endOfInsertedCont
ent) || next.isNull()) { |
| 1233 if (!isStartOfParagraph(endOfInsertedContent)) { | 1233 if (!isStartOfParagraph(endOfInsertedContent)) { |
| 1234 setEndingSelection(endOfInsertedContent); | 1234 setEndingSelection(endOfInsertedContent); |
| 1235 Element* enclosingBlockElement = enclosingBlock(endOfInsertedCon
tent.deepEquivalent().anchorNode()); | 1235 Element* enclosingBlockElement = enclosingBlock(endOfInsertedCon
tent.deepEquivalent().anchorNode()); |
| 1236 if (isListItem(enclosingBlockElement)) { | 1236 if (isListItem(enclosingBlockElement)) { |
| 1237 RefPtrWillBeRawPtr<HTMLLIElement> newListItem = createListIt
emElement(document()); | 1237 RefPtrWillBeRawPtr<HTMLLIElement> newListItem = createListIt
emElement(document()); |
| 1238 insertNodeAfter(newListItem, enclosingBlockElement); | 1238 insertNodeAfter(newListItem, enclosingBlockElement); |
| 1239 setEndingSelection(VisiblePosition(firstPositionInNode(newLi
stItem.get()))); | 1239 setEndingSelection(VisiblePosition(firstPositionInNode(newLi
stItem.get()))); |
| 1240 } else { | 1240 } else { |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1549 DEFINE_TRACE(ReplaceSelectionCommand) | 1549 DEFINE_TRACE(ReplaceSelectionCommand) |
| 1550 { | 1550 { |
| 1551 visitor->trace(m_startOfInsertedContent); | 1551 visitor->trace(m_startOfInsertedContent); |
| 1552 visitor->trace(m_endOfInsertedContent); | 1552 visitor->trace(m_endOfInsertedContent); |
| 1553 visitor->trace(m_insertionStyle); | 1553 visitor->trace(m_insertionStyle); |
| 1554 visitor->trace(m_documentFragment); | 1554 visitor->trace(m_documentFragment); |
| 1555 CompositeEditCommand::trace(visitor); | 1555 CompositeEditCommand::trace(visitor); |
| 1556 } | 1556 } |
| 1557 | 1557 |
| 1558 } // namespace blink | 1558 } // namespace blink |
| OLD | NEW |