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 |