| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 if (pos.offsetInContainerNode() <= caretMinOffset(pos.computeContainerNode()
)) | 592 if (pos.offsetInContainerNode() <= caretMinOffset(pos.computeContainerNode()
)) |
| 593 return positionInParentBeforeNode(*tabSpan); | 593 return positionInParentBeforeNode(*tabSpan); |
| 594 | 594 |
| 595 if (pos.offsetInContainerNode() >= caretMaxOffset(pos.computeContainerNode()
)) | 595 if (pos.offsetInContainerNode() >= caretMaxOffset(pos.computeContainerNode()
)) |
| 596 return positionInParentAfterNode(*tabSpan); | 596 return positionInParentAfterNode(*tabSpan); |
| 597 | 597 |
| 598 splitTextNodeContainingElement(toText(pos.computeContainerNode()), pos.offse
tInContainerNode()); | 598 splitTextNodeContainingElement(toText(pos.computeContainerNode()), pos.offse
tInContainerNode()); |
| 599 return positionInParentBeforeNode(*tabSpan); | 599 return positionInParentBeforeNode(*tabSpan); |
| 600 } | 600 } |
| 601 | 601 |
| 602 void CompositeEditCommand::insertNodeAtTabSpanPosition(PassRefPtrWillBeRawPtr<No
de> node, const Position& pos) | 602 void CompositeEditCommand::insertNodeAtTabSpanPosition(PassRefPtrWillBeRawPtr<No
de> node, const Position& pos, EditingState* editingState) |
| 603 { | 603 { |
| 604 // insert node before, after, or at split of tab span | 604 // insert node before, after, or at split of tab span |
| 605 insertNodeAt(node, positionOutsideTabSpan(pos)); | 605 insertNodeAt(node, positionOutsideTabSpan(pos), editingState); |
| 606 } | 606 } |
| 607 | 607 |
| 608 void CompositeEditCommand::deleteSelection(EditingState* editingState, bool smar
tDelete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool saniti
zeMarkup) | 608 void CompositeEditCommand::deleteSelection(EditingState* editingState, bool smar
tDelete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool saniti
zeMarkup) |
| 609 { | 609 { |
| 610 if (endingSelection().isRange()) | 610 if (endingSelection().isRange()) |
| 611 applyCommandToComposite(DeleteSelectionCommand::create(document(), smart
Delete, mergeBlocksAfterDelete, expandForSpecialElements, sanitizeMarkup), editi
ngState); | 611 applyCommandToComposite(DeleteSelectionCommand::create(document(), smart
Delete, mergeBlocksAfterDelete, expandForSpecialElements, sanitizeMarkup), editi
ngState); |
| 612 } | 612 } |
| 613 | 613 |
| 614 void CompositeEditCommand::deleteSelection(const VisibleSelection &selection, Ed
itingState* editingState, bool smartDelete, bool mergeBlocksAfterDelete, bool ex
pandForSpecialElements, bool sanitizeMarkup) | 614 void CompositeEditCommand::deleteSelection(const VisibleSelection &selection, Ed
itingState* editingState, bool smartDelete, bool mergeBlocksAfterDelete, bool ex
pandForSpecialElements, bool sanitizeMarkup) |
| 615 { | 615 { |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 886 // Should assert isLayoutBlockFlow || isInlineFlow when deletion improves. S
ee 4244964. | 886 // Should assert isLayoutBlockFlow || isInlineFlow when deletion improves. S
ee 4244964. |
| 887 ASSERT(container->layoutObject()); | 887 ASSERT(container->layoutObject()); |
| 888 | 888 |
| 889 RefPtrWillBeRawPtr<HTMLBRElement> placeholder = HTMLBRElement::create(docume
nt()); | 889 RefPtrWillBeRawPtr<HTMLBRElement> placeholder = HTMLBRElement::create(docume
nt()); |
| 890 appendNode(placeholder, container, editingState); | 890 appendNode(placeholder, container, editingState); |
| 891 if (editingState->isAborted()) | 891 if (editingState->isAborted()) |
| 892 return nullptr; | 892 return nullptr; |
| 893 return placeholder.release(); | 893 return placeholder.release(); |
| 894 } | 894 } |
| 895 | 895 |
| 896 PassRefPtrWillBeRawPtr<HTMLBRElement> CompositeEditCommand::insertBlockPlacehold
er(const Position& pos) | 896 PassRefPtrWillBeRawPtr<HTMLBRElement> CompositeEditCommand::insertBlockPlacehold
er(const Position& pos, EditingState* editingState) |
| 897 { | 897 { |
| 898 if (pos.isNull()) | 898 if (pos.isNull()) |
| 899 return nullptr; | 899 return nullptr; |
| 900 | 900 |
| 901 // Should assert isLayoutBlockFlow || isInlineFlow when deletion improves. S
ee 4244964. | 901 // Should assert isLayoutBlockFlow || isInlineFlow when deletion improves. S
ee 4244964. |
| 902 ASSERT(pos.anchorNode()->layoutObject()); | 902 ASSERT(pos.anchorNode()->layoutObject()); |
| 903 | 903 |
| 904 RefPtrWillBeRawPtr<HTMLBRElement> placeholder = HTMLBRElement::create(docume
nt()); | 904 RefPtrWillBeRawPtr<HTMLBRElement> placeholder = HTMLBRElement::create(docume
nt()); |
| 905 insertNodeAt(placeholder, pos); | 905 insertNodeAt(placeholder, pos, editingState); |
| 906 if (editingState->isAborted()) |
| 907 return nullptr; |
| 906 return placeholder.release(); | 908 return placeholder.release(); |
| 907 } | 909 } |
| 908 | 910 |
| 909 PassRefPtrWillBeRawPtr<HTMLBRElement> CompositeEditCommand::addBlockPlaceholderI
fNeeded(Element* container, EditingState* editingState) | 911 PassRefPtrWillBeRawPtr<HTMLBRElement> CompositeEditCommand::addBlockPlaceholderI
fNeeded(Element* container, EditingState* editingState) |
| 910 { | 912 { |
| 911 if (!container) | 913 if (!container) |
| 912 return nullptr; | 914 return nullptr; |
| 913 | 915 |
| 914 document().updateLayoutIgnorePendingStylesheets(); | 916 document().updateLayoutIgnorePendingStylesheets(); |
| 915 | 917 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 934 // We are certain that the position is at a line break, but it may be a br o
r a preserved newline. | 936 // We are certain that the position is at a line break, but it may be a br o
r a preserved newline. |
| 935 if (isHTMLBRElement(*p.anchorNode())) { | 937 if (isHTMLBRElement(*p.anchorNode())) { |
| 936 // Removing a BR element won't dispatch synchronous events. | 938 // Removing a BR element won't dispatch synchronous events. |
| 937 removeNode(p.anchorNode(), ASSERT_NO_EDITING_ABORT); | 939 removeNode(p.anchorNode(), ASSERT_NO_EDITING_ABORT); |
| 938 return; | 940 return; |
| 939 } | 941 } |
| 940 | 942 |
| 941 deleteTextFromNode(toText(p.anchorNode()), p.offsetInContainerNode(), 1); | 943 deleteTextFromNode(toText(p.anchorNode()), p.offsetInContainerNode(), 1); |
| 942 } | 944 } |
| 943 | 945 |
| 944 PassRefPtrWillBeRawPtr<HTMLElement> CompositeEditCommand::insertNewDefaultParagr
aphElementAt(const Position& position) | 946 PassRefPtrWillBeRawPtr<HTMLElement> CompositeEditCommand::insertNewDefaultParagr
aphElementAt(const Position& position, EditingState* editingState) |
| 945 { | 947 { |
| 946 RefPtrWillBeRawPtr<HTMLElement> paragraphElement = createDefaultParagraphEle
ment(document()); | 948 RefPtrWillBeRawPtr<HTMLElement> paragraphElement = createDefaultParagraphEle
ment(document()); |
| 947 paragraphElement->appendChild(HTMLBRElement::create(document())); | 949 paragraphElement->appendChild(HTMLBRElement::create(document())); |
| 948 insertNodeAt(paragraphElement, position); | 950 insertNodeAt(paragraphElement, position, editingState); |
| 951 if (editingState->isAborted()) |
| 952 return nullptr; |
| 949 return paragraphElement.release(); | 953 return paragraphElement.release(); |
| 950 } | 954 } |
| 951 | 955 |
| 952 // If the paragraph is not entirely within it's own block, create one and move t
he paragraph into | 956 // If the paragraph is not entirely within it's own block, create one and move t
he paragraph into |
| 953 // it, and return that block. Otherwise return 0. | 957 // it, and return that block. Otherwise return 0. |
| 954 PassRefPtrWillBeRawPtr<HTMLElement> CompositeEditCommand::moveParagraphContentsT
oNewBlockIfNecessary(const Position& pos, EditingState* editingState) | 958 PassRefPtrWillBeRawPtr<HTMLElement> CompositeEditCommand::moveParagraphContentsT
oNewBlockIfNecessary(const Position& pos, EditingState* editingState) |
| 955 { | 959 { |
| 956 ASSERT(isEditablePosition(pos, ContentIsEditable, DoNotUpdateStyle)); | 960 ASSERT(isEditablePosition(pos, ContentIsEditable, DoNotUpdateStyle)); |
| 957 | 961 |
| 958 // It's strange that this function is responsible for verifying that pos has
not been invalidated | 962 // It's strange that this function is responsible for verifying that pos has
not been invalidated |
| (...skipping 13 matching lines...) Expand all Loading... |
| 972 return nullptr; | 976 return nullptr; |
| 973 | 977 |
| 974 // Perform some checks to see if we need to perform work in this function. | 978 // Perform some checks to see if we need to perform work in this function. |
| 975 if (isEnclosingBlock(upstreamStart.anchorNode())) { | 979 if (isEnclosingBlock(upstreamStart.anchorNode())) { |
| 976 // If the block is the root editable element, always move content to a n
ew block, | 980 // If the block is the root editable element, always move content to a n
ew block, |
| 977 // since it is illegal to modify attributes on the root editable element
for editing. | 981 // since it is illegal to modify attributes on the root editable element
for editing. |
| 978 if (upstreamStart.anchorNode() == rootEditableElementOf(upstreamStart))
{ | 982 if (upstreamStart.anchorNode() == rootEditableElementOf(upstreamStart))
{ |
| 979 // If the block is the root editable element and it contains no visi
ble content, create a new | 983 // If the block is the root editable element and it contains no visi
ble content, create a new |
| 980 // block but don't try and move content into it, since there's nothi
ng for moveParagraphs to move. | 984 // block but don't try and move content into it, since there's nothi
ng for moveParagraphs to move. |
| 981 if (!hasRenderedNonAnonymousDescendantsWithHeight(upstreamStart.anch
orNode()->layoutObject())) | 985 if (!hasRenderedNonAnonymousDescendantsWithHeight(upstreamStart.anch
orNode()->layoutObject())) |
| 982 return insertNewDefaultParagraphElementAt(upstreamStart); | 986 return insertNewDefaultParagraphElementAt(upstreamStart, editing
State); |
| 983 } else if (isEnclosingBlock(upstreamEnd.anchorNode())) { | 987 } else if (isEnclosingBlock(upstreamEnd.anchorNode())) { |
| 984 if (!upstreamEnd.anchorNode()->isDescendantOf(upstreamStart.anchorNo
de())) { | 988 if (!upstreamEnd.anchorNode()->isDescendantOf(upstreamStart.anchorNo
de())) { |
| 985 // If the paragraph end is a descendant of paragraph start, then
we need to run | 989 // If the paragraph end is a descendant of paragraph start, then
we need to run |
| 986 // the rest of this function. If not, we can bail here. | 990 // the rest of this function. If not, we can bail here. |
| 987 return nullptr; | 991 return nullptr; |
| 988 } | 992 } |
| 989 } else if (enclosingBlock(upstreamEnd.anchorNode()) != upstreamStart.anc
horNode()) { | 993 } else if (enclosingBlock(upstreamEnd.anchorNode()) != upstreamStart.anc
horNode()) { |
| 990 // It should be an ancestor of the paragraph start. | 994 // It should be an ancestor of the paragraph start. |
| 991 // We can bail as we have a full block to work with. | 995 // We can bail as we have a full block to work with. |
| 992 return nullptr; | 996 return nullptr; |
| 993 } else if (isEndOfEditableOrNonEditableContent(visibleEnd)) { | 997 } else if (isEndOfEditableOrNonEditableContent(visibleEnd)) { |
| 994 // At the end of the editable region. We can bail here as well. | 998 // At the end of the editable region. We can bail here as well. |
| 995 return nullptr; | 999 return nullptr; |
| 996 } | 1000 } |
| 997 } | 1001 } |
| 998 | 1002 |
| 999 if (visibleParagraphEnd.isNull()) | 1003 if (visibleParagraphEnd.isNull()) |
| 1000 return nullptr; | 1004 return nullptr; |
| 1001 | 1005 |
| 1002 RefPtrWillBeRawPtr<HTMLElement> newBlock = insertNewDefaultParagraphElementA
t(upstreamStart); | 1006 RefPtrWillBeRawPtr<HTMLElement> newBlock = insertNewDefaultParagraphElementA
t(upstreamStart, editingState); |
| 1007 if (editingState->isAborted()) |
| 1008 return nullptr; |
| 1003 | 1009 |
| 1004 bool endWasBr = isHTMLBRElement(*visibleParagraphEnd.deepEquivalent().anchor
Node()); | 1010 bool endWasBr = isHTMLBRElement(*visibleParagraphEnd.deepEquivalent().anchor
Node()); |
| 1005 | 1011 |
| 1006 // Inserting default paragraph element can change visible position. We | 1012 // Inserting default paragraph element can change visible position. We |
| 1007 // should update visible positions before use them. | 1013 // should update visible positions before use them. |
| 1008 visiblePos = createVisiblePosition(pos, VP_DEFAULT_AFFINITY); | 1014 visiblePos = createVisiblePosition(pos, VP_DEFAULT_AFFINITY); |
| 1009 visibleParagraphStart = startOfParagraph(visiblePos); | 1015 visibleParagraphStart = startOfParagraph(visiblePos); |
| 1010 visibleParagraphEnd = endOfParagraph(visiblePos); | 1016 visibleParagraphEnd = endOfParagraph(visiblePos); |
| 1011 moveParagraphs(visibleParagraphStart, visibleParagraphEnd, createVisiblePosi
tion(firstPositionInNode(newBlock.get())), editingState); | 1017 moveParagraphs(visibleParagraphStart, visibleParagraphEnd, createVisiblePosi
tion(firstPositionInNode(newBlock.get())), editingState); |
| 1012 if (editingState->isAborted()) | 1018 if (editingState->isAborted()) |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1211 // baz | 1217 // baz |
| 1212 // Imagine moving 'bar' to ^. 'bar' will be deleted and its div pruned. Th
at would | 1218 // Imagine moving 'bar' to ^. 'bar' will be deleted and its div pruned. Th
at would |
| 1213 // cause 'baz' to collapse onto the line with 'foobar' unless we insert a br
. | 1219 // cause 'baz' to collapse onto the line with 'foobar' unless we insert a br
. |
| 1214 // Must recononicalize these two VisiblePositions after the pruning above. | 1220 // Must recononicalize these two VisiblePositions after the pruning above. |
| 1215 beforeParagraph = createVisiblePosition(beforeParagraph.deepEquivalent()); | 1221 beforeParagraph = createVisiblePosition(beforeParagraph.deepEquivalent()); |
| 1216 afterParagraph = createVisiblePosition(afterParagraph.deepEquivalent()); | 1222 afterParagraph = createVisiblePosition(afterParagraph.deepEquivalent()); |
| 1217 | 1223 |
| 1218 if (beforeParagraph.isNotNull() && !isDisplayInsideTable(beforeParagraph.dee
pEquivalent().anchorNode()) | 1224 if (beforeParagraph.isNotNull() && !isDisplayInsideTable(beforeParagraph.dee
pEquivalent().anchorNode()) |
| 1219 && ((!isEndOfParagraph(beforeParagraph) && !isStartOfParagraph(beforePar
agraph)) || beforeParagraph.deepEquivalent() == afterParagraph.deepEquivalent())
) { | 1225 && ((!isEndOfParagraph(beforeParagraph) && !isStartOfParagraph(beforePar
agraph)) || beforeParagraph.deepEquivalent() == afterParagraph.deepEquivalent())
) { |
| 1220 // FIXME: Trim text between beforeParagraph and afterParagraph if they a
ren't equal. | 1226 // FIXME: Trim text between beforeParagraph and afterParagraph if they a
ren't equal. |
| 1221 insertNodeAt(HTMLBRElement::create(document()), beforeParagraph.deepEqui
valent()); | 1227 insertNodeAt(HTMLBRElement::create(document()), beforeParagraph.deepEqui
valent(), editingState); |
| 1222 } | 1228 } |
| 1223 } | 1229 } |
| 1224 | 1230 |
| 1225 void CompositeEditCommand::moveParagraph(const VisiblePosition& startOfParagraph
ToMove, const VisiblePosition& endOfParagraphToMove, const VisiblePosition& dest
ination, EditingState* editingState, bool preserveSelection, bool preserveStyle,
Node* constrainingAncestor) | 1231 void CompositeEditCommand::moveParagraph(const VisiblePosition& startOfParagraph
ToMove, const VisiblePosition& endOfParagraphToMove, const VisiblePosition& dest
ination, EditingState* editingState, bool preserveSelection, bool preserveStyle,
Node* constrainingAncestor) |
| 1226 { | 1232 { |
| 1227 ASSERT(isStartOfParagraph(startOfParagraphToMove)); | 1233 ASSERT(isStartOfParagraph(startOfParagraphToMove)); |
| 1228 ASSERT(isEndOfParagraph(endOfParagraphToMove)); | 1234 ASSERT(isEndOfParagraph(endOfParagraphToMove)); |
| 1229 moveParagraphs(startOfParagraphToMove, endOfParagraphToMove, destination, ed
itingState, preserveSelection, preserveStyle, constrainingAncestor); | 1235 moveParagraphs(startOfParagraphToMove, endOfParagraphToMove, destination, ed
itingState, preserveSelection, preserveStyle, constrainingAncestor); |
| 1230 } | 1236 } |
| 1231 | 1237 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1301 // foo^ | 1307 // foo^ |
| 1302 // <div>bar</div> | 1308 // <div>bar</div> |
| 1303 // baz | 1309 // baz |
| 1304 // Imagine moving 'bar' to ^. 'bar' will be deleted and its div pruned. That
would | 1310 // Imagine moving 'bar' to ^. 'bar' will be deleted and its div pruned. That
would |
| 1305 // cause 'baz' to collapse onto the line with 'foobar' unless we insert a br
. | 1311 // cause 'baz' to collapse onto the line with 'foobar' unless we insert a br
. |
| 1306 // Must recononicalize these two VisiblePositions after the pruning above. | 1312 // Must recononicalize these two VisiblePositions after the pruning above. |
| 1307 beforeParagraph = createVisiblePosition(beforeParagraph.deepEquivalent()); | 1313 beforeParagraph = createVisiblePosition(beforeParagraph.deepEquivalent()); |
| 1308 afterParagraph = createVisiblePosition(afterParagraph.deepEquivalent()); | 1314 afterParagraph = createVisiblePosition(afterParagraph.deepEquivalent()); |
| 1309 if (beforeParagraph.isNotNull() && (!isEndOfParagraph(beforeParagraph) || be
foreParagraph.deepEquivalent() == afterParagraph.deepEquivalent())) { | 1315 if (beforeParagraph.isNotNull() && (!isEndOfParagraph(beforeParagraph) || be
foreParagraph.deepEquivalent() == afterParagraph.deepEquivalent())) { |
| 1310 // FIXME: Trim text between beforeParagraph and afterParagraph if they a
ren't equal. | 1316 // FIXME: Trim text between beforeParagraph and afterParagraph if they a
ren't equal. |
| 1311 insertNodeAt(HTMLBRElement::create(document()), beforeParagraph.deepEqui
valent()); | 1317 insertNodeAt(HTMLBRElement::create(document()), beforeParagraph.deepEqui
valent(), editingState); |
| 1318 if (editingState->isAborted()) |
| 1319 return; |
| 1312 // Need an updateLayout here in case inserting the br has split a text n
ode. | 1320 // Need an updateLayout here in case inserting the br has split a text n
ode. |
| 1313 document().updateLayoutIgnorePendingStylesheets(); | 1321 document().updateLayoutIgnorePendingStylesheets(); |
| 1314 } | 1322 } |
| 1315 | 1323 |
| 1316 destinationIndex = TextIterator::rangeLength(firstPositionInNode(document().
documentElement()), destination.toParentAnchoredPosition(), true); | 1324 destinationIndex = TextIterator::rangeLength(firstPositionInNode(document().
documentElement()), destination.toParentAnchoredPosition(), true); |
| 1317 | 1325 |
| 1318 setEndingSelection(VisibleSelection(destination, originalIsDirectional)); | 1326 setEndingSelection(VisibleSelection(destination, originalIsDirectional)); |
| 1319 ASSERT(endingSelection().isCaretOrRange()); | 1327 ASSERT(endingSelection().isCaretOrRange()); |
| 1320 ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::S
electReplacement | ReplaceSelectionCommand::MovingParagraph; | 1328 ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::S
electReplacement | ReplaceSelectionCommand::MovingParagraph; |
| 1321 if (!preserveStyle) | 1329 if (!preserveStyle) |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1593 } | 1601 } |
| 1594 | 1602 |
| 1595 DEFINE_TRACE(CompositeEditCommand) | 1603 DEFINE_TRACE(CompositeEditCommand) |
| 1596 { | 1604 { |
| 1597 visitor->trace(m_commands); | 1605 visitor->trace(m_commands); |
| 1598 visitor->trace(m_composition); | 1606 visitor->trace(m_composition); |
| 1599 EditCommand::trace(visitor); | 1607 EditCommand::trace(visitor); |
| 1600 } | 1608 } |
| 1601 | 1609 |
| 1602 } // namespace blink | 1610 } // namespace blink |
| OLD | NEW |