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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 Element* enclosingBlockElement = enclosingBlock(pos.computeContainerNode()); | 133 Element* enclosingBlockElement = enclosingBlock(pos.computeContainerNode()); |
134 for (Position nextPosition = pos; nextPosition.computeContainerNode() != enc
losingBlockElement; pos = nextPosition) { | 134 for (Position nextPosition = pos; nextPosition.computeContainerNode() != enc
losingBlockElement; pos = nextPosition) { |
135 if (lineBreakExistsAtPosition(pos)) | 135 if (lineBreakExistsAtPosition(pos)) |
136 break; | 136 break; |
137 | 137 |
138 if (pos.computeContainerNode()->nonShadowBoundaryParentNode()) | 138 if (pos.computeContainerNode()->nonShadowBoundaryParentNode()) |
139 nextPosition = Position::inParentAfterNode(*pos.computeContainerNode
()); | 139 nextPosition = Position::inParentAfterNode(*pos.computeContainerNode
()); |
140 | 140 |
141 if (nextPosition == pos | 141 if (nextPosition == pos |
142 || enclosingBlock(nextPosition.computeContainerNode()) != enclosingB
lockElement | 142 || enclosingBlock(nextPosition.computeContainerNode()) != enclosingB
lockElement |
143 || createVisiblePosition(pos).deepEquivalent() != createVisiblePosit
ion(nextPosition).deepEquivalent()) | 143 || createVisiblePositionDeprecated(pos).deepEquivalent() != createVi
siblePositionDeprecated(nextPosition).deepEquivalent()) |
144 break; | 144 break; |
145 } | 145 } |
146 return pos; | 146 return pos; |
147 } | 147 } |
148 | 148 |
149 ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
ragment, const VisibleSelection& selection) | 149 ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
ragment, const VisibleSelection& selection) |
150 : m_document(document) | 150 : m_document(document) |
151 , m_fragment(fragment) | 151 , m_fragment(fragment) |
152 , m_hasInterchangeNewlineAtStart(false) | 152 , m_hasInterchangeNewlineAtStart(false) |
153 , m_hasInterchangeNewlineAtEnd(false) | 153 , m_hasInterchangeNewlineAtEnd(false) |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 } | 697 } |
698 } | 698 } |
699 } | 699 } |
700 } | 700 } |
701 | 701 |
702 void ReplaceSelectionCommand::moveElementOutOfAncestor(Element* element, Element
* ancestor, EditingState* editingState) | 702 void ReplaceSelectionCommand::moveElementOutOfAncestor(Element* element, Element
* ancestor, EditingState* editingState) |
703 { | 703 { |
704 if (!hasEditableStyle(*ancestor->parentNode())) | 704 if (!hasEditableStyle(*ancestor->parentNode())) |
705 return; | 705 return; |
706 | 706 |
707 VisiblePosition positionAtEndOfNode = createVisiblePosition(lastPositionInOr
AfterNode(element)); | 707 VisiblePosition positionAtEndOfNode = createVisiblePositionDeprecated(lastPo
sitionInOrAfterNode(element)); |
708 VisiblePosition lastPositionInParagraph = VisiblePosition::lastPositionInNod
e(ancestor); | 708 VisiblePosition lastPositionInParagraph = VisiblePosition::lastPositionInNod
e(ancestor); |
709 if (positionAtEndOfNode.deepEquivalent() == lastPositionInParagraph.deepEqui
valent()) { | 709 if (positionAtEndOfNode.deepEquivalent() == lastPositionInParagraph.deepEqui
valent()) { |
710 removeNode(element, editingState); | 710 removeNode(element, editingState); |
711 if (editingState->isAborted()) | 711 if (editingState->isAborted()) |
712 return; | 712 return; |
713 if (ancestor->nextSibling()) | 713 if (ancestor->nextSibling()) |
714 insertNodeBefore(element, ancestor->nextSibling(), editingState); | 714 insertNodeBefore(element, ancestor->nextSibling(), editingState); |
715 else | 715 else |
716 appendNode(element, ancestor->parentNode(), editingState); | 716 appendNode(element, ancestor->parentNode(), editingState); |
717 if (editingState->isAborted()) | 717 if (editingState->isAborted()) |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 } | 757 } |
758 } | 758 } |
759 | 759 |
760 VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent() const | 760 VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent() const |
761 { | 761 { |
762 // TODO(yosin): We should set |m_endOfInsertedContent| not in SELECT | 762 // TODO(yosin): We should set |m_endOfInsertedContent| not in SELECT |
763 // element, since contents of SELECT elements, e.g. OPTION, OPTGROUP, are | 763 // element, since contents of SELECT elements, e.g. OPTION, OPTGROUP, are |
764 // not editable, or SELECT element is an atomic on editing. | 764 // not editable, or SELECT element is an atomic on editing. |
765 HTMLSelectElement* enclosingSelect = toHTMLSelectElement(enclosingElementWit
hTag(m_endOfInsertedContent, selectTag)); | 765 HTMLSelectElement* enclosingSelect = toHTMLSelectElement(enclosingElementWit
hTag(m_endOfInsertedContent, selectTag)); |
766 if (enclosingSelect) | 766 if (enclosingSelect) |
767 return createVisiblePosition(lastPositionInOrAfterNode(enclosingSelect))
; | 767 return createVisiblePositionDeprecated(lastPositionInOrAfterNode(enclosi
ngSelect)); |
768 if (m_endOfInsertedContent.isOrphan()) | 768 if (m_endOfInsertedContent.isOrphan()) |
769 return VisiblePosition(); | 769 return VisiblePosition(); |
770 return createVisiblePosition(m_endOfInsertedContent); | 770 return createVisiblePositionDeprecated(m_endOfInsertedContent); |
771 } | 771 } |
772 | 772 |
773 VisiblePosition ReplaceSelectionCommand::positionAtStartOfInsertedContent() cons
t | 773 VisiblePosition ReplaceSelectionCommand::positionAtStartOfInsertedContent() cons
t |
774 { | 774 { |
775 if (m_startOfInsertedContent.isOrphan()) | 775 if (m_startOfInsertedContent.isOrphan()) |
776 return VisiblePosition(); | 776 return VisiblePosition(); |
777 return createVisiblePosition(m_startOfInsertedContent); | 777 return createVisiblePositionDeprecated(m_startOfInsertedContent); |
778 } | 778 } |
779 | 779 |
780 static void removeHeadContents(ReplacementFragment& fragment) | 780 static void removeHeadContents(ReplacementFragment& fragment) |
781 { | 781 { |
782 Node* next = nullptr; | 782 Node* next = nullptr; |
783 for (Node* node = fragment.firstChild(); node; node = next) { | 783 for (Node* node = fragment.firstChild(); node; node = next) { |
784 if (isHTMLBaseElement(*node) | 784 if (isHTMLBaseElement(*node) |
785 || isHTMLLinkElement(*node) | 785 || isHTMLLinkElement(*node) |
786 || isHTMLMetaElement(*node) | 786 || isHTMLMetaElement(*node) |
787 || isHTMLTitleElement(*node)) { | 787 || isHTMLTitleElement(*node)) { |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1142 VisiblePosition originalVisPosBeforeEndBR; | 1142 VisiblePosition originalVisPosBeforeEndBR; |
1143 if (endBR) | 1143 if (endBR) |
1144 originalVisPosBeforeEndBR = previousPositionOf(VisiblePosition::beforeNo
de(endBR)); | 1144 originalVisPosBeforeEndBR = previousPositionOf(VisiblePosition::beforeNo
de(endBR)); |
1145 | 1145 |
1146 Element* enclosingBlockOfInsertionPos = enclosingBlock(insertionPos.anchorNo
de()); | 1146 Element* enclosingBlockOfInsertionPos = enclosingBlock(insertionPos.anchorNo
de()); |
1147 | 1147 |
1148 // Adjust |enclosingBlockOfInsertionPos| to prevent nesting. | 1148 // Adjust |enclosingBlockOfInsertionPos| to prevent nesting. |
1149 // If the start was in a Mail blockquote, we will have already handled | 1149 // If the start was in a Mail blockquote, we will have already handled |
1150 // adjusting |enclosingBlockOfInsertionPos| above. | 1150 // adjusting |enclosingBlockOfInsertionPos| above. |
1151 if (m_preventNesting && enclosingBlockOfInsertionPos && enclosingBlockOfInse
rtionPos != currentRoot && !isTableCell(enclosingBlockOfInsertionPos) && !startI
sInsideMailBlockquote) { | 1151 if (m_preventNesting && enclosingBlockOfInsertionPos && enclosingBlockOfInse
rtionPos != currentRoot && !isTableCell(enclosingBlockOfInsertionPos) && !startI
sInsideMailBlockquote) { |
1152 VisiblePosition visibleInsertionPos = createVisiblePosition(insertionPos
); | 1152 VisiblePosition visibleInsertionPos = createVisiblePositionDeprecated(in
sertionPos); |
1153 if (isEndOfBlock(visibleInsertionPos) && !(isStartOfBlock(visibleInserti
onPos) && fragment.hasInterchangeNewlineAtEnd())) | 1153 if (isEndOfBlock(visibleInsertionPos) && !(isStartOfBlock(visibleInserti
onPos) && fragment.hasInterchangeNewlineAtEnd())) |
1154 insertionPos = Position::inParentAfterNode(*enclosingBlockOfInsertio
nPos); | 1154 insertionPos = Position::inParentAfterNode(*enclosingBlockOfInsertio
nPos); |
1155 else if (isStartOfBlock(visibleInsertionPos)) | 1155 else if (isStartOfBlock(visibleInsertionPos)) |
1156 insertionPos = Position::inParentBeforeNode(*enclosingBlockOfInserti
onPos); | 1156 insertionPos = Position::inParentBeforeNode(*enclosingBlockOfInserti
onPos); |
1157 } | 1157 } |
1158 | 1158 |
1159 // Paste at start or end of link goes outside of link. | 1159 // Paste at start or end of link goes outside of link. |
1160 insertionPos = positionAvoidingSpecialElementBoundary(insertionPos, editingS
tate); | 1160 insertionPos = positionAvoidingSpecialElementBoundary(insertionPos, editingS
tate); |
1161 if (editingState->isAborted()) | 1161 if (editingState->isAborted()) |
1162 return; | 1162 return; |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1273 | 1273 |
1274 // Mutation events (bug 20161) may have already removed the inserted content | 1274 // Mutation events (bug 20161) may have already removed the inserted content |
1275 if (!insertedNodes.firstNodeInserted() || !insertedNodes.firstNodeInserted()
->isConnected()) | 1275 if (!insertedNodes.firstNodeInserted() || !insertedNodes.firstNodeInserted()
->isConnected()) |
1276 return; | 1276 return; |
1277 | 1277 |
1278 // Scripts specified in javascript protocol may remove |enclosingBlockOfInse
rtionPos| | 1278 // Scripts specified in javascript protocol may remove |enclosingBlockOfInse
rtionPos| |
1279 // during insertion, e.g. <iframe src="javascript:..."> | 1279 // during insertion, e.g. <iframe src="javascript:..."> |
1280 if (enclosingBlockOfInsertionPos && !enclosingBlockOfInsertionPos->isConnect
ed()) | 1280 if (enclosingBlockOfInsertionPos && !enclosingBlockOfInsertionPos->isConnect
ed()) |
1281 enclosingBlockOfInsertionPos = nullptr; | 1281 enclosingBlockOfInsertionPos = nullptr; |
1282 | 1282 |
1283 VisiblePosition startOfInsertedContent = createVisiblePosition(firstPosition
InOrBeforeNode(insertedNodes.firstNodeInserted())); | 1283 VisiblePosition startOfInsertedContent = createVisiblePositionDeprecated(fir
stPositionInOrBeforeNode(insertedNodes.firstNodeInserted())); |
1284 | 1284 |
1285 // We inserted before the enclosingBlockOfInsertionPos to prevent nesting, a
nd the content before the enclosingBlockOfInsertionPos wasn't in its own block a
nd | 1285 // We inserted before the enclosingBlockOfInsertionPos to prevent nesting, a
nd the content before the enclosingBlockOfInsertionPos wasn't in its own block a
nd |
1286 // didn't have a br after it, so the inserted content ended up in the same p
aragraph. | 1286 // didn't have a br after it, so the inserted content ended up in the same p
aragraph. |
1287 if (!startOfInsertedContent.isNull() && enclosingBlockOfInsertionPos && inse
rtionPos.anchorNode() == enclosingBlockOfInsertionPos->parentNode() && (unsigned
)insertionPos.computeEditingOffset() < enclosingBlockOfInsertionPos->nodeIndex()
&& !isStartOfParagraph(startOfInsertedContent)) { | 1287 if (!startOfInsertedContent.isNull() && enclosingBlockOfInsertionPos && inse
rtionPos.anchorNode() == enclosingBlockOfInsertionPos->parentNode() && (unsigned
)insertionPos.computeEditingOffset() < enclosingBlockOfInsertionPos->nodeIndex()
&& !isStartOfParagraph(startOfInsertedContent)) { |
1288 insertNodeAt(HTMLBRElement::create(document()), startOfInsertedContent.d
eepEquivalent(), editingState); | 1288 insertNodeAt(HTMLBRElement::create(document()), startOfInsertedContent.d
eepEquivalent(), editingState); |
1289 if (editingState->isAborted()) | 1289 if (editingState->isAborted()) |
1290 return; | 1290 return; |
1291 } | 1291 } |
1292 | 1292 |
1293 if (endBR && (plainTextFragment || (shouldRemoveEndBR(endBR, originalVisPosB
eforeEndBR) && !(fragment.hasInterchangeNewlineAtEnd() && selectionIsPlainText))
)) { | 1293 if (endBR && (plainTextFragment || (shouldRemoveEndBR(endBR, originalVisPosB
eforeEndBR) && !(fragment.hasInterchangeNewlineAtEnd() && selectionIsPlainText))
)) { |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1644 return m_inputType; | 1644 return m_inputType; |
1645 } | 1645 } |
1646 | 1646 |
1647 // If the user is inserting a list into an existing list, instead of nesting the
list, | 1647 // If the user is inserting a list into an existing list, instead of nesting the
list, |
1648 // we put the list items into the existing list. | 1648 // we put the list items into the existing list. |
1649 Node* ReplaceSelectionCommand::insertAsListItems(HTMLElement* listElement, Eleme
nt* insertionBlock, const Position& insertPos, InsertedNodes& insertedNodes, Edi
tingState* editingState) | 1649 Node* ReplaceSelectionCommand::insertAsListItems(HTMLElement* listElement, Eleme
nt* insertionBlock, const Position& insertPos, InsertedNodes& insertedNodes, Edi
tingState* editingState) |
1650 { | 1650 { |
1651 while (listElement->hasOneChild() && isHTMLListElement(listElement->firstChi
ld())) | 1651 while (listElement->hasOneChild() && isHTMLListElement(listElement->firstChi
ld())) |
1652 listElement = toHTMLElement(listElement->firstChild()); | 1652 listElement = toHTMLElement(listElement->firstChild()); |
1653 | 1653 |
1654 bool isStart = isStartOfParagraph(createVisiblePosition(insertPos)); | 1654 bool isStart = isStartOfParagraph(createVisiblePositionDeprecated(insertPos)
); |
1655 bool isEnd = isEndOfParagraph(createVisiblePosition(insertPos)); | 1655 bool isEnd = isEndOfParagraph(createVisiblePositionDeprecated(insertPos)); |
1656 bool isMiddle = !isStart && !isEnd; | 1656 bool isMiddle = !isStart && !isEnd; |
1657 Node* lastNode = insertionBlock; | 1657 Node* lastNode = insertionBlock; |
1658 | 1658 |
1659 // If we're in the middle of a list item, we should split it into two separa
te | 1659 // If we're in the middle of a list item, we should split it into two separa
te |
1660 // list items and insert these nodes between them. | 1660 // list items and insert these nodes between them. |
1661 if (isMiddle) { | 1661 if (isMiddle) { |
1662 int textNodeOffset = insertPos.offsetInContainerNode(); | 1662 int textNodeOffset = insertPos.offsetInContainerNode(); |
1663 if (insertPos.anchorNode()->isTextNode() && textNodeOffset > 0) | 1663 if (insertPos.anchorNode()->isTextNode() && textNodeOffset > 0) |
1664 splitTextNode(toText(insertPos.anchorNode()), textNodeOffset); | 1664 splitTextNode(toText(insertPos.anchorNode()), textNodeOffset); |
1665 splitTreeToNode(insertPos.anchorNode(), lastNode, true); | 1665 splitTreeToNode(insertPos.anchorNode(), lastNode, true); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1758 visitor->trace(m_startOfInsertedContent); | 1758 visitor->trace(m_startOfInsertedContent); |
1759 visitor->trace(m_endOfInsertedContent); | 1759 visitor->trace(m_endOfInsertedContent); |
1760 visitor->trace(m_insertionStyle); | 1760 visitor->trace(m_insertionStyle); |
1761 visitor->trace(m_documentFragment); | 1761 visitor->trace(m_documentFragment); |
1762 visitor->trace(m_startOfInsertedRange); | 1762 visitor->trace(m_startOfInsertedRange); |
1763 visitor->trace(m_endOfInsertedRange); | 1763 visitor->trace(m_endOfInsertedRange); |
1764 CompositeEditCommand::trace(visitor); | 1764 CompositeEditCommand::trace(visitor); |
1765 } | 1765 } |
1766 | 1766 |
1767 } // namespace blink | 1767 } // namespace blink |
OLD | NEW |