| 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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 Element* enclosingBlockElement = enclosingBlock(pos.computeContainerNode()); | 132 Element* enclosingBlockElement = enclosingBlock(pos.computeContainerNode()); |
| 133 for (Position nextPosition = pos; nextPosition.computeContainerNode() != enc
losingBlockElement; pos = nextPosition) { | 133 for (Position nextPosition = pos; nextPosition.computeContainerNode() != enc
losingBlockElement; pos = nextPosition) { |
| 134 if (lineBreakExistsAtPosition(pos)) | 134 if (lineBreakExistsAtPosition(pos)) |
| 135 break; | 135 break; |
| 136 | 136 |
| 137 if (pos.computeContainerNode()->nonShadowBoundaryParentNode()) | 137 if (pos.computeContainerNode()->nonShadowBoundaryParentNode()) |
| 138 nextPosition = positionInParentAfterNode(*pos.computeContainerNode()
); | 138 nextPosition = positionInParentAfterNode(*pos.computeContainerNode()
); |
| 139 | 139 |
| 140 if (nextPosition == pos | 140 if (nextPosition == pos |
| 141 || enclosingBlock(nextPosition.computeContainerNode()) != enclosingB
lockElement | 141 || enclosingBlock(nextPosition.computeContainerNode()) != enclosingB
lockElement |
| 142 || VisiblePosition(pos).deepEquivalent() != VisiblePosition(nextPosi
tion).deepEquivalent()) | 142 || createVisiblePosition(pos).deepEquivalent() != createVisiblePosit
ion(nextPosition).deepEquivalent()) |
| 143 break; | 143 break; |
| 144 } | 144 } |
| 145 return pos; | 145 return pos; |
| 146 } | 146 } |
| 147 | 147 |
| 148 ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
ragment, const VisibleSelection& selection) | 148 ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
ragment, const VisibleSelection& selection) |
| 149 : m_document(document) | 149 : m_document(document) |
| 150 , m_fragment(fragment) | 150 , m_fragment(fragment) |
| 151 , m_hasInterchangeNewlineAtStart(false) | 151 , m_hasInterchangeNewlineAtStart(false) |
| 152 , m_hasInterchangeNewlineAtEnd(false) | 152 , m_hasInterchangeNewlineAtEnd(false) |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 Position inserted = endOfInsertedContent.deepEquivalent(); | 392 Position inserted = endOfInsertedContent.deepEquivalent(); |
| 393 bool isInsideMailBlockquote = enclosingNodeOfType(inserted, isMailHTMLBlockq
uoteElement, CanCrossEditingBoundary); | 393 bool isInsideMailBlockquote = enclosingNodeOfType(inserted, isMailHTMLBlockq
uoteElement, CanCrossEditingBoundary); |
| 394 return isInsideMailBlockquote && (numEnclosingMailBlockquotes(existing) == n
umEnclosingMailBlockquotes(inserted)); | 394 return isInsideMailBlockquote && (numEnclosingMailBlockquotes(existing) == n
umEnclosingMailBlockquotes(inserted)); |
| 395 } | 395 } |
| 396 | 396 |
| 397 bool ReplaceSelectionCommand::shouldMergeStart(bool selectionStartWasStartOfPara
graph, bool fragmentHasInterchangeNewlineAtStart, bool selectionStartWasInsideMa
ilBlockquote) | 397 bool ReplaceSelectionCommand::shouldMergeStart(bool selectionStartWasStartOfPara
graph, bool fragmentHasInterchangeNewlineAtStart, bool selectionStartWasInsideMa
ilBlockquote) |
| 398 { | 398 { |
| 399 if (m_movingParagraph) | 399 if (m_movingParagraph) |
| 400 return false; | 400 return false; |
| 401 | 401 |
| 402 VisiblePosition startOfInsertedContent(positionAtStartOfInsertedContent()); | 402 VisiblePosition startOfInsertedContent = positionAtStartOfInsertedContent(); |
| 403 VisiblePosition prev = previousPositionOf(startOfInsertedContent, CannotCros
sEditingBoundary); | 403 VisiblePosition prev = previousPositionOf(startOfInsertedContent, CannotCros
sEditingBoundary); |
| 404 if (prev.isNull()) | 404 if (prev.isNull()) |
| 405 return false; | 405 return false; |
| 406 | 406 |
| 407 // When we have matching quote levels, its ok to merge more frequently. | 407 // When we have matching quote levels, its ok to merge more frequently. |
| 408 // For a successful merge, we still need to make sure that the inserted cont
ent starts with the beginning of a paragraph. | 408 // For a successful merge, we still need to make sure that the inserted cont
ent starts with the beginning of a paragraph. |
| 409 // And we should only merge here if the selection start was inside a mail bl
ockquote. This prevents against removing a | 409 // And we should only merge here if the selection start was inside a mail bl
ockquote. This prevents against removing a |
| 410 // blockquote from newly pasted quoted content that was pasted into an unquo
ted position. If that unquoted position happens | 410 // blockquote from newly pasted quoted content that was pasted into an unquo
ted position. If that unquoted position happens |
| 411 // to be right after another blockquote, we don't want to merge and risk str
ipping a valid block (and newline) from the pasted content. | 411 // to be right after another blockquote, we don't want to merge and risk str
ipping a valid block (and newline) from the pasted content. |
| 412 if (isStartOfParagraph(startOfInsertedContent) && selectionStartWasInsideMai
lBlockquote && hasMatchingQuoteLevel(prev, positionAtEndOfInsertedContent())) | 412 if (isStartOfParagraph(startOfInsertedContent) && selectionStartWasInsideMai
lBlockquote && hasMatchingQuoteLevel(prev, positionAtEndOfInsertedContent())) |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 removeNodePreservingChildren(element); | 536 removeNodePreservingChildren(element); |
| 537 continue; | 537 continue; |
| 538 } | 538 } |
| 539 removeElementAttribute(element, styleAttr); | 539 removeElementAttribute(element, styleAttr); |
| 540 } else if (newInlineStyle->style()->propertyCount() != inlineStyle->prop
ertyCount()) { | 540 } else if (newInlineStyle->style()->propertyCount() != inlineStyle->prop
ertyCount()) { |
| 541 setNodeAttribute(element, styleAttr, AtomicString(newInlineStyle->st
yle()->asText())); | 541 setNodeAttribute(element, styleAttr, AtomicString(newInlineStyle->st
yle()->asText())); |
| 542 } | 542 } |
| 543 | 543 |
| 544 // FIXME: Tolerate differences in id, class, and style attributes. | 544 // FIXME: Tolerate differences in id, class, and style attributes. |
| 545 if (element->parentNode() && isNonTableCellHTMLBlockElement(element) &&
areIdenticalElements(element, element->parentNode()) | 545 if (element->parentNode() && isNonTableCellHTMLBlockElement(element) &&
areIdenticalElements(element, element->parentNode()) |
| 546 && VisiblePosition(firstPositionInNode(element->parentNode())).deepE
quivalent() == VisiblePosition(firstPositionInNode(element)).deepEquivalent() | 546 && createVisiblePosition(firstPositionInNode(element->parentNode()))
.deepEquivalent() == createVisiblePosition(firstPositionInNode(element)).deepEqu
ivalent() |
| 547 && VisiblePosition(lastPositionInNode(element->parentNode())).deepEq
uivalent() == VisiblePosition(lastPositionInNode(element)).deepEquivalent()) { | 547 && createVisiblePosition(lastPositionInNode(element->parentNode())).
deepEquivalent() == createVisiblePosition(lastPositionInNode(element)).deepEquiv
alent()) { |
| 548 insertedNodes.willRemoveNodePreservingChildren(*element); | 548 insertedNodes.willRemoveNodePreservingChildren(*element); |
| 549 removeNodePreservingChildren(element); | 549 removeNodePreservingChildren(element); |
| 550 continue; | 550 continue; |
| 551 } | 551 } |
| 552 | 552 |
| 553 if (element->parentNode() && element->parentNode()->layoutObjectIsRichly
Editable()) | 553 if (element->parentNode() && element->parentNode()->layoutObjectIsRichly
Editable()) |
| 554 removeElementAttribute(element, contenteditableAttr); | 554 removeElementAttribute(element, contenteditableAttr); |
| 555 | 555 |
| 556 // WebKit used to not add display: inline and float: none on copy. | 556 // WebKit used to not add display: inline and float: none on copy. |
| 557 // Keep this code around for backward compatibility | 557 // Keep this code around for backward compatibility |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 658 } | 658 } |
| 659 | 659 |
| 660 void ReplaceSelectionCommand::moveElementOutOfAncestor(PassRefPtrWillBeRawPtr<El
ement> prpElement, PassRefPtrWillBeRawPtr<ContainerNode> prpAncestor) | 660 void ReplaceSelectionCommand::moveElementOutOfAncestor(PassRefPtrWillBeRawPtr<El
ement> prpElement, PassRefPtrWillBeRawPtr<ContainerNode> prpAncestor) |
| 661 { | 661 { |
| 662 RefPtrWillBeRawPtr<Element> element = prpElement; | 662 RefPtrWillBeRawPtr<Element> element = prpElement; |
| 663 RefPtrWillBeRawPtr<ContainerNode> ancestor = prpAncestor; | 663 RefPtrWillBeRawPtr<ContainerNode> ancestor = prpAncestor; |
| 664 | 664 |
| 665 if (!ancestor->parentNode()->hasEditableStyle()) | 665 if (!ancestor->parentNode()->hasEditableStyle()) |
| 666 return; | 666 return; |
| 667 | 667 |
| 668 VisiblePosition positionAtEndOfNode(lastPositionInOrAfterNode(element.get())
); | 668 VisiblePosition positionAtEndOfNode = createVisiblePosition(lastPositionInOr
AfterNode(element.get())); |
| 669 VisiblePosition lastPositionInParagraph(lastPositionInNode(ancestor.get())); | 669 VisiblePosition lastPositionInParagraph = createVisiblePosition(lastPosition
InNode(ancestor.get())); |
| 670 if (positionAtEndOfNode.deepEquivalent() == lastPositionInParagraph.deepEqui
valent()) { | 670 if (positionAtEndOfNode.deepEquivalent() == lastPositionInParagraph.deepEqui
valent()) { |
| 671 removeNode(element); | 671 removeNode(element); |
| 672 if (ancestor->nextSibling()) | 672 if (ancestor->nextSibling()) |
| 673 insertNodeBefore(element, ancestor->nextSibling()); | 673 insertNodeBefore(element, ancestor->nextSibling()); |
| 674 else | 674 else |
| 675 appendNode(element, ancestor->parentNode()); | 675 appendNode(element, ancestor->parentNode()); |
| 676 } else { | 676 } else { |
| 677 RefPtrWillBeRawPtr<Node> nodeToSplitTo = splitTreeToNode(element.get(),
ancestor.get(), true); | 677 RefPtrWillBeRawPtr<Node> nodeToSplitTo = splitTreeToNode(element.get(),
ancestor.get(), true); |
| 678 removeNode(element); | 678 removeNode(element); |
| 679 insertNodeBefore(element, nodeToSplitTo); | 679 insertNodeBefore(element, nodeToSplitTo); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 705 if (firstNodeInserted && firstNodeInserted->isTextNode() && !nodeHasVisibleL
ayoutText(toText(*firstNodeInserted))) { | 705 if (firstNodeInserted && firstNodeInserted->isTextNode() && !nodeHasVisibleL
ayoutText(toText(*firstNodeInserted))) { |
| 706 insertedNodes.willRemoveNode(*firstNodeInserted); | 706 insertedNodes.willRemoveNode(*firstNodeInserted); |
| 707 removeNode(firstNodeInserted); | 707 removeNode(firstNodeInserted); |
| 708 } | 708 } |
| 709 } | 709 } |
| 710 | 710 |
| 711 VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent() const | 711 VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent() const |
| 712 { | 712 { |
| 713 // FIXME: Why is this hack here? What's special about <select> tags? | 713 // FIXME: Why is this hack here? What's special about <select> tags? |
| 714 HTMLSelectElement* enclosingSelect = toHTMLSelectElement(enclosingElementWit
hTag(m_endOfInsertedContent, selectTag)); | 714 HTMLSelectElement* enclosingSelect = toHTMLSelectElement(enclosingElementWit
hTag(m_endOfInsertedContent, selectTag)); |
| 715 return VisiblePosition(enclosingSelect ? lastPositionInOrAfterNode(enclosing
Select) : m_endOfInsertedContent); | 715 return createVisiblePosition(enclosingSelect ? lastPositionInOrAfterNode(enc
losingSelect) : m_endOfInsertedContent); |
| 716 } | 716 } |
| 717 | 717 |
| 718 VisiblePosition ReplaceSelectionCommand::positionAtStartOfInsertedContent() cons
t | 718 VisiblePosition ReplaceSelectionCommand::positionAtStartOfInsertedContent() cons
t |
| 719 { | 719 { |
| 720 return VisiblePosition(m_startOfInsertedContent); | 720 return createVisiblePosition(m_startOfInsertedContent); |
| 721 } | 721 } |
| 722 | 722 |
| 723 static void removeHeadContents(ReplacementFragment& fragment) | 723 static void removeHeadContents(ReplacementFragment& fragment) |
| 724 { | 724 { |
| 725 Node* next = nullptr; | 725 Node* next = nullptr; |
| 726 for (Node* node = fragment.firstChild(); node; node = next) { | 726 for (Node* node = fragment.firstChild(); node; node = next) { |
| 727 if (isHTMLBaseElement(*node) | 727 if (isHTMLBaseElement(*node) |
| 728 || isHTMLLinkElement(*node) | 728 || isHTMLLinkElement(*node) |
| 729 || isHTMLMetaElement(*node) | 729 || isHTMLMetaElement(*node) |
| 730 || isHTMLStyleElement(*node) | 730 || isHTMLStyleElement(*node) |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 843 bool mergeForward = !(inSameParagraph(startOfInsertedContent, endOfInsertedC
ontent) && !isStartOfParagraph(startOfInsertedContent)); | 843 bool mergeForward = !(inSameParagraph(startOfInsertedContent, endOfInsertedC
ontent) && !isStartOfParagraph(startOfInsertedContent)); |
| 844 | 844 |
| 845 VisiblePosition destination = mergeForward ? nextPositionOf(endOfInsertedCon
tent) : endOfInsertedContent; | 845 VisiblePosition destination = mergeForward ? nextPositionOf(endOfInsertedCon
tent) : endOfInsertedContent; |
| 846 VisiblePosition startOfParagraphToMove = mergeForward ? startOfParagraph(end
OfInsertedContent) : nextPositionOf(endOfInsertedContent); | 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 = createVisiblePosition(positionBeforeNode(placeholder.get()
)); |
| 854 } | 854 } |
| 855 | 855 |
| 856 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToMove)
, destination); | 856 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToMove)
, destination); |
| 857 | 857 |
| 858 // Merging forward will remove m_endOfInsertedContent from the document. | 858 // Merging forward will remove m_endOfInsertedContent from the document. |
| 859 if (mergeForward) { | 859 if (mergeForward) { |
| 860 if (m_startOfInsertedContent.isOrphan()) | 860 if (m_startOfInsertedContent.isOrphan()) |
| 861 m_startOfInsertedContent = endingSelection().visibleStart().deepEqui
valent(); | 861 m_startOfInsertedContent = endingSelection().visibleStart().deepEqui
valent(); |
| 862 m_endOfInsertedContent = endingSelection().visibleEnd().deepEquivalent()
; | 862 m_endOfInsertedContent = endingSelection().visibleEnd().deepEquivalent()
; |
| 863 // If we merged text nodes, m_endOfInsertedContent could be null. If | 863 // If we merged text nodes, m_endOfInsertedContent could be null. If |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1025 // If the downstream node has been removed there's no point in continuing. | 1025 // If the downstream node has been removed there's no point in continuing. |
| 1026 if (!mostForwardCaretPosition(insertionPos).anchorNode()) | 1026 if (!mostForwardCaretPosition(insertionPos).anchorNode()) |
| 1027 return; | 1027 return; |
| 1028 | 1028 |
| 1029 // NOTE: This would be an incorrect usage of downstream() if downstream() we
re changed to mean the last position after | 1029 // NOTE: This would be an incorrect usage of downstream() if downstream() we
re changed to mean the last position after |
| 1030 // p that maps to the same visible position as p (since in the case where a
br is at the end of a block and collapsed | 1030 // p that maps to the same visible position as p (since in the case where a
br is at the end of a block and collapsed |
| 1031 // away, there are positions after the br which map to the same visible posi
tion as [br, 0]). | 1031 // away, there are positions after the br which map to the same visible posi
tion as [br, 0]). |
| 1032 HTMLBRElement* endBR = isHTMLBRElement(*mostForwardCaretPosition(insertionPo
s).anchorNode()) ? toHTMLBRElement(mostForwardCaretPosition(insertionPos).anchor
Node()) : 0; | 1032 HTMLBRElement* endBR = isHTMLBRElement(*mostForwardCaretPosition(insertionPo
s).anchorNode()) ? toHTMLBRElement(mostForwardCaretPosition(insertionPos).anchor
Node()) : 0; |
| 1033 VisiblePosition originalVisPosBeforeEndBR; | 1033 VisiblePosition originalVisPosBeforeEndBR; |
| 1034 if (endBR) | 1034 if (endBR) |
| 1035 originalVisPosBeforeEndBR = previousPositionOf(VisiblePosition(positionB
eforeNode(endBR))); | 1035 originalVisPosBeforeEndBR = previousPositionOf(createVisiblePosition(pos
itionBeforeNode(endBR))); |
| 1036 | 1036 |
| 1037 RefPtrWillBeRawPtr<Element> enclosingBlockOfInsertionPos = enclosingBlock(in
sertionPos.anchorNode()); | 1037 RefPtrWillBeRawPtr<Element> enclosingBlockOfInsertionPos = enclosingBlock(in
sertionPos.anchorNode()); |
| 1038 | 1038 |
| 1039 // Adjust insertionPos to prevent nesting. | 1039 // Adjust insertionPos to prevent nesting. |
| 1040 // If the start was in a Mail blockquote, we will have already handled adjus
ting insertionPos above. | 1040 // If the start was in a Mail blockquote, we will have already handled adjus
ting insertionPos above. |
| 1041 if (m_preventNesting && enclosingBlockOfInsertionPos && !isTableCell(enclosi
ngBlockOfInsertionPos.get()) && !startIsInsideMailBlockquote) { | 1041 if (m_preventNesting && enclosingBlockOfInsertionPos && !isTableCell(enclosi
ngBlockOfInsertionPos.get()) && !startIsInsideMailBlockquote) { |
| 1042 ASSERT(enclosingBlockOfInsertionPos != currentRoot); | 1042 ASSERT(enclosingBlockOfInsertionPos != currentRoot); |
| 1043 VisiblePosition visibleInsertionPos(insertionPos); | 1043 VisiblePosition visibleInsertionPos = createVisiblePosition(insertionPos
); |
| 1044 if (isEndOfBlock(visibleInsertionPos) && !(isStartOfBlock(visibleInserti
onPos) && fragment.hasInterchangeNewlineAtEnd())) | 1044 if (isEndOfBlock(visibleInsertionPos) && !(isStartOfBlock(visibleInserti
onPos) && fragment.hasInterchangeNewlineAtEnd())) |
| 1045 insertionPos = positionInParentAfterNode(*enclosingBlockOfInsertionP
os); | 1045 insertionPos = positionInParentAfterNode(*enclosingBlockOfInsertionP
os); |
| 1046 else if (isStartOfBlock(visibleInsertionPos)) | 1046 else if (isStartOfBlock(visibleInsertionPos)) |
| 1047 insertionPos = positionInParentBeforeNode(*enclosingBlockOfInsertion
Pos); | 1047 insertionPos = positionInParentBeforeNode(*enclosingBlockOfInsertion
Pos); |
| 1048 } | 1048 } |
| 1049 | 1049 |
| 1050 // Paste at start or end of link goes outside of link. | 1050 // Paste at start or end of link goes outside of link. |
| 1051 insertionPos = positionAvoidingSpecialElementBoundary(insertionPos); | 1051 insertionPos = positionAvoidingSpecialElementBoundary(insertionPos); |
| 1052 | 1052 |
| 1053 // FIXME: Can this wait until after the operation has been performed? There
doesn't seem to be | 1053 // FIXME: Can this wait until after the operation has been performed? There
doesn't seem to be |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1152 | 1152 |
| 1153 // Mutation events (bug 20161) may have already removed the inserted content | 1153 // Mutation events (bug 20161) may have already removed the inserted content |
| 1154 if (!insertedNodes.firstNodeInserted() || !insertedNodes.firstNodeInserted()
->inDocument()) | 1154 if (!insertedNodes.firstNodeInserted() || !insertedNodes.firstNodeInserted()
->inDocument()) |
| 1155 return; | 1155 return; |
| 1156 | 1156 |
| 1157 // Scripts specified in javascript protocol may remove |enclosingBlockOfInse
rtionPos| | 1157 // Scripts specified in javascript protocol may remove |enclosingBlockOfInse
rtionPos| |
| 1158 // during insertion, e.g. <iframe src="javascript:..."> | 1158 // during insertion, e.g. <iframe src="javascript:..."> |
| 1159 if (enclosingBlockOfInsertionPos && !enclosingBlockOfInsertionPos->inDocumen
t()) | 1159 if (enclosingBlockOfInsertionPos && !enclosingBlockOfInsertionPos->inDocumen
t()) |
| 1160 enclosingBlockOfInsertionPos = nullptr; | 1160 enclosingBlockOfInsertionPos = nullptr; |
| 1161 | 1161 |
| 1162 VisiblePosition startOfInsertedContent(firstPositionInOrBeforeNode(insertedN
odes.firstNodeInserted())); | 1162 VisiblePosition startOfInsertedContent = createVisiblePosition(firstPosition
InOrBeforeNode(insertedNodes.firstNodeInserted())); |
| 1163 | 1163 |
| 1164 // We inserted before the enclosingBlockOfInsertionPos to prevent nesting, a
nd the content before the enclosingBlockOfInsertionPos wasn't in its own block a
nd | 1164 // We inserted before the enclosingBlockOfInsertionPos to prevent nesting, a
nd the content before the enclosingBlockOfInsertionPos wasn't in its own block a
nd |
| 1165 // didn't have a br after it, so the inserted content ended up in the same p
aragraph. | 1165 // didn't have a br after it, so the inserted content ended up in the same p
aragraph. |
| 1166 if (!startOfInsertedContent.isNull() && enclosingBlockOfInsertionPos && inse
rtionPos.anchorNode() == enclosingBlockOfInsertionPos->parentNode() && (unsigned
)insertionPos.computeEditingOffset() < enclosingBlockOfInsertionPos->nodeIndex()
&& !isStartOfParagraph(startOfInsertedContent)) | 1166 if (!startOfInsertedContent.isNull() && enclosingBlockOfInsertionPos && inse
rtionPos.anchorNode() == enclosingBlockOfInsertionPos->parentNode() && (unsigned
)insertionPos.computeEditingOffset() < enclosingBlockOfInsertionPos->nodeIndex()
&& !isStartOfParagraph(startOfInsertedContent)) |
| 1167 insertNodeAt(createBreakElement(document()).get(), startOfInsertedConten
t.deepEquivalent()); | 1167 insertNodeAt(createBreakElement(document()).get(), startOfInsertedConten
t.deepEquivalent()); |
| 1168 | 1168 |
| 1169 if (endBR && (plainTextFragment || (shouldRemoveEndBR(endBR, originalVisPosB
eforeEndBR) && !(fragment.hasInterchangeNewlineAtEnd() && selectionIsPlainText))
)) { | 1169 if (endBR && (plainTextFragment || (shouldRemoveEndBR(endBR, originalVisPosB
eforeEndBR) && !(fragment.hasInterchangeNewlineAtEnd() && selectionIsPlainText))
)) { |
| 1170 RefPtrWillBeRawPtr<ContainerNode> parent = endBR->parentNode(); | 1170 RefPtrWillBeRawPtr<ContainerNode> parent = endBR->parentNode(); |
| 1171 insertedNodes.willRemoveNode(*endBR); | 1171 insertedNodes.willRemoveNode(*endBR); |
| 1172 removeNode(endBR); | 1172 removeNode(endBR); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1229 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent(); | 1229 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent(); |
| 1230 VisiblePosition next = nextPositionOf(endOfInsertedContent, CannotCrossE
ditingBoundary); | 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(createVisiblePosition(firstPositionInNode
(newListItem.get()))); |
| 1240 } else { | 1240 } else { |
| 1241 // Use a default paragraph element (a plain div) for the emp
ty paragraph, using the last paragraph | 1241 // Use a default paragraph element (a plain div) for the emp
ty paragraph, using the last paragraph |
| 1242 // block's style seems to annoy users. | 1242 // block's style seems to annoy users. |
| 1243 insertParagraphSeparator(true, !startIsInsideMailBlockquote
&& highestEnclosingNodeOfType(endOfInsertedContent.deepEquivalent(), | 1243 insertParagraphSeparator(true, !startIsInsideMailBlockquote
&& highestEnclosingNodeOfType(endOfInsertedContent.deepEquivalent(), |
| 1244 isMailHTMLBlockquoteElement, CannotCrossEditingBoundary,
insertedNodes.firstNodeInserted()->parentNode())); | 1244 isMailHTMLBlockquoteElement, CannotCrossEditingBoundary,
insertedNodes.firstNodeInserted()->parentNode())); |
| 1245 } | 1245 } |
| 1246 | 1246 |
| 1247 // Select up to the paragraph separator that was added. | 1247 // Select up to the paragraph separator that was added. |
| 1248 lastPositionToSelect = endingSelection().visibleStart().deepEqui
valent(); | 1248 lastPositionToSelect = endingSelection().visibleStart().deepEqui
valent(); |
| 1249 updateNodesInserted(lastPositionToSelect.anchorNode()); | 1249 updateNodesInserted(lastPositionToSelect.anchorNode()); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1268 m_matchStyle = false; | 1268 m_matchStyle = false; |
| 1269 | 1269 |
| 1270 completeHTMLReplacement(lastPositionToSelect); | 1270 completeHTMLReplacement(lastPositionToSelect); |
| 1271 } | 1271 } |
| 1272 | 1272 |
| 1273 bool ReplaceSelectionCommand::shouldRemoveEndBR(HTMLBRElement* endBR, const Visi
blePosition& originalVisPosBeforeEndBR) | 1273 bool ReplaceSelectionCommand::shouldRemoveEndBR(HTMLBRElement* endBR, const Visi
blePosition& originalVisPosBeforeEndBR) |
| 1274 { | 1274 { |
| 1275 if (!endBR || !endBR->inDocument()) | 1275 if (!endBR || !endBR->inDocument()) |
| 1276 return false; | 1276 return false; |
| 1277 | 1277 |
| 1278 VisiblePosition visiblePos(positionBeforeNode(endBR)); | 1278 VisiblePosition visiblePos = createVisiblePosition(positionBeforeNode(endBR)
); |
| 1279 | 1279 |
| 1280 // Don't remove the br if nothing was inserted. | 1280 // Don't remove the br if nothing was inserted. |
| 1281 if (previousPositionOf(visiblePos).deepEquivalent() == originalVisPosBeforeE
ndBR.deepEquivalent()) | 1281 if (previousPositionOf(visiblePos).deepEquivalent() == originalVisPosBeforeE
ndBR.deepEquivalent()) |
| 1282 return false; | 1282 return false; |
| 1283 | 1283 |
| 1284 // Remove the br if it is collapsed away and so is unnecessary. | 1284 // Remove the br if it is collapsed away and so is unnecessary. |
| 1285 if (!document().inNoQuirksMode() && isEndOfBlock(visiblePos) && !isStartOfPa
ragraph(visiblePos)) | 1285 if (!document().inNoQuirksMode() && isEndOfBlock(visiblePos) && !isStartOfPa
ragraph(visiblePos)) |
| 1286 return true; | 1286 return true; |
| 1287 | 1287 |
| 1288 // A br that was originally holding a line open should be displaced by inser
ted content or turned into a line break. | 1288 // A br that was originally holding a line open should be displaced by inser
ted content or turned into a line break. |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1457 | 1457 |
| 1458 // If the user is inserting a list into an existing list, instead of nesting the
list, | 1458 // If the user is inserting a list into an existing list, instead of nesting the
list, |
| 1459 // we put the list items into the existing list. | 1459 // we put the list items into the existing list. |
| 1460 Node* ReplaceSelectionCommand::insertAsListItems(PassRefPtrWillBeRawPtr<HTMLElem
ent> prpListElement, Element* insertionBlock, const Position& insertPos, Inserte
dNodes& insertedNodes) | 1460 Node* ReplaceSelectionCommand::insertAsListItems(PassRefPtrWillBeRawPtr<HTMLElem
ent> prpListElement, Element* insertionBlock, const Position& insertPos, Inserte
dNodes& insertedNodes) |
| 1461 { | 1461 { |
| 1462 RefPtrWillBeRawPtr<HTMLElement> listElement = prpListElement; | 1462 RefPtrWillBeRawPtr<HTMLElement> listElement = prpListElement; |
| 1463 | 1463 |
| 1464 while (listElement->hasOneChild() && isHTMLListElement(listElement->firstChi
ld())) | 1464 while (listElement->hasOneChild() && isHTMLListElement(listElement->firstChi
ld())) |
| 1465 listElement = toHTMLElement(listElement->firstChild()); | 1465 listElement = toHTMLElement(listElement->firstChild()); |
| 1466 | 1466 |
| 1467 bool isStart = isStartOfParagraph(VisiblePosition(insertPos)); | 1467 bool isStart = isStartOfParagraph(createVisiblePosition(insertPos)); |
| 1468 bool isEnd = isEndOfParagraph(VisiblePosition(insertPos)); | 1468 bool isEnd = isEndOfParagraph(createVisiblePosition(insertPos)); |
| 1469 bool isMiddle = !isStart && !isEnd; | 1469 bool isMiddle = !isStart && !isEnd; |
| 1470 Node* lastNode = insertionBlock; | 1470 Node* lastNode = insertionBlock; |
| 1471 | 1471 |
| 1472 // If we're in the middle of a list item, we should split it into two separa
te | 1472 // If we're in the middle of a list item, we should split it into two separa
te |
| 1473 // list items and insert these nodes between them. | 1473 // list items and insert these nodes between them. |
| 1474 if (isMiddle) { | 1474 if (isMiddle) { |
| 1475 int textNodeOffset = insertPos.offsetInContainerNode(); | 1475 int textNodeOffset = insertPos.offsetInContainerNode(); |
| 1476 if (insertPos.anchorNode()->isTextNode() && textNodeOffset > 0) | 1476 if (insertPos.anchorNode()->isTextNode() && textNodeOffset > 0) |
| 1477 splitTextNode(toText(insertPos.anchorNode()), textNodeOffset); | 1477 splitTextNode(toText(insertPos.anchorNode()), textNodeOffset); |
| 1478 splitTreeToNode(insertPos.anchorNode(), lastNode, true); | 1478 splitTreeToNode(insertPos.anchorNode(), lastNode, true); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1529 RefPtrWillBeRawPtr<Node> nodeAfterInsertionPos = mostForwardCaretPosition(en
dingSelection().end()).anchorNode(); | 1529 RefPtrWillBeRawPtr<Node> nodeAfterInsertionPos = mostForwardCaretPosition(en
dingSelection().end()).anchorNode(); |
| 1530 Text* textNode = toText(fragment.firstChild()); | 1530 Text* textNode = toText(fragment.firstChild()); |
| 1531 // Our fragment creation code handles tabs, spaces, and newlines, so we don'
t have to worry about those here. | 1531 // Our fragment creation code handles tabs, spaces, and newlines, so we don'
t have to worry about those here. |
| 1532 | 1532 |
| 1533 Position start = endingSelection().start(); | 1533 Position start = endingSelection().start(); |
| 1534 Position end = replaceSelectedTextInNode(textNode->data()); | 1534 Position end = replaceSelectedTextInNode(textNode->data()); |
| 1535 if (end.isNull()) | 1535 if (end.isNull()) |
| 1536 return false; | 1536 return false; |
| 1537 | 1537 |
| 1538 if (nodeAfterInsertionPos && nodeAfterInsertionPos->parentNode() && isHTMLBR
Element(*nodeAfterInsertionPos) | 1538 if (nodeAfterInsertionPos && nodeAfterInsertionPos->parentNode() && isHTMLBR
Element(*nodeAfterInsertionPos) |
| 1539 && shouldRemoveEndBR(toHTMLBRElement(nodeAfterInsertionPos.get()), Visib
lePosition(positionBeforeNode(nodeAfterInsertionPos.get())))) | 1539 && shouldRemoveEndBR(toHTMLBRElement(nodeAfterInsertionPos.get()), creat
eVisiblePosition(positionBeforeNode(nodeAfterInsertionPos.get())))) |
| 1540 removeNodeAndPruneAncestors(nodeAfterInsertionPos.get()); | 1540 removeNodeAndPruneAncestors(nodeAfterInsertionPos.get()); |
| 1541 | 1541 |
| 1542 VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, en
d); | 1542 VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, en
d); |
| 1543 | 1543 |
| 1544 setEndingSelection(selectionAfterReplace); | 1544 setEndingSelection(selectionAfterReplace); |
| 1545 | 1545 |
| 1546 return true; | 1546 return true; |
| 1547 } | 1547 } |
| 1548 | 1548 |
| 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 |