| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2005 Apple Computer, 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 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 | 165 |
| 166 void DeleteSelectionCommand::initializePositionData() | 166 void DeleteSelectionCommand::initializePositionData() |
| 167 { | 167 { |
| 168 Position start, end; | 168 Position start, end; |
| 169 initializeStartEnd(start, end); | 169 initializeStartEnd(start, end); |
| 170 | 170 |
| 171 ASSERT(isEditablePosition(start, ContentIsEditable, DoNotUpdateStyle)); | 171 ASSERT(isEditablePosition(start, ContentIsEditable, DoNotUpdateStyle)); |
| 172 if (!isEditablePosition(end, ContentIsEditable, DoNotUpdateStyle)) | 172 if (!isEditablePosition(end, ContentIsEditable, DoNotUpdateStyle)) |
| 173 end = lastEditablePositionBeforePositionInRoot(end, highestEditableRoot(
start)); | 173 end = lastEditablePositionBeforePositionInRoot(end, highestEditableRoot(
start)); |
| 174 | 174 |
| 175 m_upstreamStart = start.upstream(); | 175 m_upstreamStart = mostBackwardCaretPosition(start); |
| 176 m_downstreamStart = start.downstream(); | 176 m_downstreamStart = mostForwardCaretPosition(start); |
| 177 m_upstreamEnd = end.upstream(); | 177 m_upstreamEnd = mostBackwardCaretPosition(end); |
| 178 m_downstreamEnd = end.downstream(); | 178 m_downstreamEnd = mostForwardCaretPosition(end); |
| 179 | 179 |
| 180 m_startRoot = editableRootForPosition(start); | 180 m_startRoot = editableRootForPosition(start); |
| 181 m_endRoot = editableRootForPosition(end); | 181 m_endRoot = editableRootForPosition(end); |
| 182 | 182 |
| 183 m_startTableRow = toHTMLTableRowElement(enclosingNodeOfType(start, &isHTMLTa
bleRowElement)); | 183 m_startTableRow = toHTMLTableRowElement(enclosingNodeOfType(start, &isHTMLTa
bleRowElement)); |
| 184 m_endTableRow = toHTMLTableRowElement(enclosingNodeOfType(end, &isHTMLTableR
owElement)); | 184 m_endTableRow = toHTMLTableRowElement(enclosingNodeOfType(end, &isHTMLTableR
owElement)); |
| 185 | 185 |
| 186 // Don't move content out of a table cell. | 186 // Don't move content out of a table cell. |
| 187 // If the cell is non-editable, enclosingNodeOfType won't return it by defau
lt, so | 187 // If the cell is non-editable, enclosingNodeOfType won't return it by defau
lt, so |
| 188 // tell that function that we don't care if it returns non-editable nodes. | 188 // tell that function that we don't care if it returns non-editable nodes. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 if (!skipSmartDelete) | 226 if (!skipSmartDelete) |
| 227 skipSmartDelete = leadingWhitespacePosition(m_downstreamEnd, VP_DEFA
ULT_AFFINITY, ConsiderNonCollapsibleWhitespace).isNotNull(); | 227 skipSmartDelete = leadingWhitespacePosition(m_downstreamEnd, VP_DEFA
ULT_AFFINITY, ConsiderNonCollapsibleWhitespace).isNotNull(); |
| 228 | 228 |
| 229 // extend selection upstream if there is whitespace there | 229 // extend selection upstream if there is whitespace there |
| 230 bool hasLeadingWhitespaceBeforeAdjustment = leadingWhitespacePosition(m_
upstreamStart, m_selectionToDelete.affinity(), ConsiderNonCollapsibleWhitespace)
.isNotNull(); | 230 bool hasLeadingWhitespaceBeforeAdjustment = leadingWhitespacePosition(m_
upstreamStart, m_selectionToDelete.affinity(), ConsiderNonCollapsibleWhitespace)
.isNotNull(); |
| 231 if (!skipSmartDelete && hasLeadingWhitespaceBeforeAdjustment) { | 231 if (!skipSmartDelete && hasLeadingWhitespaceBeforeAdjustment) { |
| 232 VisiblePosition visiblePos = VisiblePosition(m_upstreamStart, VP_DEF
AULT_AFFINITY).previous(); | 232 VisiblePosition visiblePos = VisiblePosition(m_upstreamStart, VP_DEF
AULT_AFFINITY).previous(); |
| 233 pos = visiblePos.deepEquivalent(); | 233 pos = visiblePos.deepEquivalent(); |
| 234 // Expand out one character upstream for smart delete and recalculat
e | 234 // Expand out one character upstream for smart delete and recalculat
e |
| 235 // positions based on this change. | 235 // positions based on this change. |
| 236 m_upstreamStart = pos.upstream(); | 236 m_upstreamStart = mostBackwardCaretPosition(pos); |
| 237 m_downstreamStart = pos.downstream(); | 237 m_downstreamStart = mostForwardCaretPosition(pos); |
| 238 m_leadingWhitespace = leadingWhitespacePosition(m_upstreamStart, vis
iblePos.affinity()); | 238 m_leadingWhitespace = leadingWhitespacePosition(m_upstreamStart, vis
iblePos.affinity()); |
| 239 | 239 |
| 240 setStartingSelectionOnSmartDelete(m_upstreamStart, m_upstreamEnd); | 240 setStartingSelectionOnSmartDelete(m_upstreamStart, m_upstreamEnd); |
| 241 } | 241 } |
| 242 | 242 |
| 243 // trailing whitespace is only considered for smart delete if there is n
o leading | 243 // trailing whitespace is only considered for smart delete if there is n
o leading |
| 244 // whitespace, as in the case where you double-click the first word of a
paragraph. | 244 // whitespace, as in the case where you double-click the first word of a
paragraph. |
| 245 if (!skipSmartDelete && !hasLeadingWhitespaceBeforeAdjustment && trailin
gWhitespacePosition(m_downstreamEnd, VP_DEFAULT_AFFINITY, ConsiderNonCollapsible
Whitespace).isNotNull()) { | 245 if (!skipSmartDelete && !hasLeadingWhitespaceBeforeAdjustment && trailin
gWhitespacePosition(m_downstreamEnd, VP_DEFAULT_AFFINITY, ConsiderNonCollapsible
Whitespace).isNotNull()) { |
| 246 // Expand out one character downstream for smart delete and recalcul
ate | 246 // Expand out one character downstream for smart delete and recalcul
ate |
| 247 // positions based on this change. | 247 // positions based on this change. |
| 248 pos = VisiblePosition(m_downstreamEnd, VP_DEFAULT_AFFINITY).next().d
eepEquivalent(); | 248 pos = VisiblePosition(m_downstreamEnd, VP_DEFAULT_AFFINITY).next().d
eepEquivalent(); |
| 249 m_upstreamEnd = pos.upstream(); | 249 m_upstreamEnd = mostBackwardCaretPosition(pos); |
| 250 m_downstreamEnd = pos.downstream(); | 250 m_downstreamEnd = mostForwardCaretPosition(pos); |
| 251 m_trailingWhitespace = trailingWhitespacePosition(m_downstreamEnd, V
P_DEFAULT_AFFINITY); | 251 m_trailingWhitespace = trailingWhitespacePosition(m_downstreamEnd, V
P_DEFAULT_AFFINITY); |
| 252 | 252 |
| 253 setStartingSelectionOnSmartDelete(m_downstreamStart, m_downstreamEnd
); | 253 setStartingSelectionOnSmartDelete(m_downstreamStart, m_downstreamEnd
); |
| 254 } | 254 } |
| 255 } | 255 } |
| 256 | 256 |
| 257 // We must pass call parentAnchoredEquivalent on the positions since some ed
iting positions | 257 // We must pass call parentAnchoredEquivalent on the positions since some ed
iting positions |
| 258 // that appear inside their nodes aren't really inside them. [hr, 0] is one
example. | 258 // that appear inside their nodes aren't really inside them. [hr, 0] is one
example. |
| 259 // FIXME: parentAnchoredEquivalent should eventually be moved into enclosing
element getters | 259 // FIXME: parentAnchoredEquivalent should eventually be moved into enclosing
element getters |
| 260 // like the one below, since editing functions should obviously accept editi
ng positions. | 260 // like the one below, since editing functions should obviously accept editi
ng positions. |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 && listItemInFirstParagraph->parentElement() != listItemInSecondParagrap
h->parentElement() | 647 && listItemInFirstParagraph->parentElement() != listItemInSecondParagrap
h->parentElement() |
| 648 && canMergeLists(listItemInFirstParagraph->parentElement(), listItemInSe
condParagraph->parentElement())) { | 648 && canMergeLists(listItemInFirstParagraph->parentElement(), listItemInSe
condParagraph->parentElement())) { |
| 649 mergeIdenticalElements(listItemInFirstParagraph->parentElement(), listIt
emInSecondParagraph->parentElement()); | 649 mergeIdenticalElements(listItemInFirstParagraph->parentElement(), listIt
emInSecondParagraph->parentElement()); |
| 650 m_endingPosition = mergeDestination.deepEquivalent(); | 650 m_endingPosition = mergeDestination.deepEquivalent(); |
| 651 return; | 651 return; |
| 652 } | 652 } |
| 653 | 653 |
| 654 // The rule for merging into an empty block is: only do so if its farther to
the right. | 654 // The rule for merging into an empty block is: only do so if its farther to
the right. |
| 655 // FIXME: Consider RTL. | 655 // FIXME: Consider RTL. |
| 656 if (!m_startsAtEmptyLine && isStartOfParagraph(mergeDestination) && startOfP
aragraphToMove.absoluteCaretBounds().x() > mergeDestination.absoluteCaretBounds(
).x()) { | 656 if (!m_startsAtEmptyLine && isStartOfParagraph(mergeDestination) && startOfP
aragraphToMove.absoluteCaretBounds().x() > mergeDestination.absoluteCaretBounds(
).x()) { |
| 657 if (isHTMLBRElement(*mergeDestination.deepEquivalent().downstream().anch
orNode())) { | 657 if (isHTMLBRElement(*mostForwardCaretPosition(mergeDestination.deepEquiv
alent()).anchorNode())) { |
| 658 removeNodeAndPruneAncestors(mergeDestination.deepEquivalent().downst
ream().anchorNode()); | 658 removeNodeAndPruneAncestors(mostForwardCaretPosition(mergeDestinatio
n.deepEquivalent()).anchorNode()); |
| 659 m_endingPosition = startOfParagraphToMove.deepEquivalent(); | 659 m_endingPosition = startOfParagraphToMove.deepEquivalent(); |
| 660 return; | 660 return; |
| 661 } | 661 } |
| 662 } | 662 } |
| 663 | 663 |
| 664 // Block images, tables and horizontal rules cannot be made inline with cont
ent at mergeDestination. If there is | 664 // Block images, tables and horizontal rules cannot be made inline with cont
ent at mergeDestination. If there is |
| 665 // any (!isStartOfParagraph(mergeDestination)), don't merge, just move the c
aret to just before the selection we deleted. | 665 // any (!isStartOfParagraph(mergeDestination)), don't merge, just move the c
aret to just before the selection we deleted. |
| 666 // See https://bugs.webkit.org/show_bug.cgi?id=25439 | 666 // See https://bugs.webkit.org/show_bug.cgi?id=25439 |
| 667 if (isRenderedAsNonInlineTableImageOrHR(startOfParagraphToMove.deepEquivalen
t().anchorNode()) && !isStartOfParagraph(mergeDestination)) { | 667 if (isRenderedAsNonInlineTableImageOrHR(startOfParagraphToMove.deepEquivalen
t().anchorNode()) && !isStartOfParagraph(mergeDestination)) { |
| 668 m_endingPosition = m_upstreamStart; | 668 m_endingPosition = m_upstreamStart; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 787 // use the current ending selection. | 787 // use the current ending selection. |
| 788 if (!m_hasSelectionToDelete) | 788 if (!m_hasSelectionToDelete) |
| 789 m_selectionToDelete = endingSelection(); | 789 m_selectionToDelete = endingSelection(); |
| 790 | 790 |
| 791 if (!m_selectionToDelete.isNonOrphanedRange() || !m_selectionToDelete.isCont
entEditable()) | 791 if (!m_selectionToDelete.isNonOrphanedRange() || !m_selectionToDelete.isCont
entEditable()) |
| 792 return; | 792 return; |
| 793 | 793 |
| 794 // save this to later make the selection with | 794 // save this to later make the selection with |
| 795 TextAffinity affinity = m_selectionToDelete.affinity(); | 795 TextAffinity affinity = m_selectionToDelete.affinity(); |
| 796 | 796 |
| 797 Position downstreamEnd = m_selectionToDelete.end().downstream(); | 797 Position downstreamEnd = mostForwardCaretPosition(m_selectionToDelete.end())
; |
| 798 bool rootWillStayOpenWithoutPlaceholder = downstreamEnd.computeContainerNode
() == downstreamEnd.computeContainerNode()->rootEditableElement() | 798 bool rootWillStayOpenWithoutPlaceholder = downstreamEnd.computeContainerNode
() == downstreamEnd.computeContainerNode()->rootEditableElement() |
| 799 || (downstreamEnd.computeContainerNode()->isTextNode() && downstreamEnd.
computeContainerNode()->parentNode() == downstreamEnd.computeContainerNode()->ro
otEditableElement()); | 799 || (downstreamEnd.computeContainerNode()->isTextNode() && downstreamEnd.
computeContainerNode()->parentNode() == downstreamEnd.computeContainerNode()->ro
otEditableElement()); |
| 800 bool lineBreakAtEndOfSelectionToDelete = lineBreakExistsAtVisiblePosition(m_
selectionToDelete.visibleEnd()); | 800 bool lineBreakAtEndOfSelectionToDelete = lineBreakExistsAtVisiblePosition(m_
selectionToDelete.visibleEnd()); |
| 801 m_needPlaceholder = !rootWillStayOpenWithoutPlaceholder | 801 m_needPlaceholder = !rootWillStayOpenWithoutPlaceholder |
| 802 && isStartOfParagraph(m_selectionToDelete.visibleStart(), CanCrossEditin
gBoundary) | 802 && isStartOfParagraph(m_selectionToDelete.visibleStart(), CanCrossEditin
gBoundary) |
| 803 && isEndOfParagraph(m_selectionToDelete.visibleEnd(), CanCrossEditingBou
ndary) | 803 && isEndOfParagraph(m_selectionToDelete.visibleEnd(), CanCrossEditingBou
ndary) |
| 804 && !lineBreakAtEndOfSelectionToDelete; | 804 && !lineBreakAtEndOfSelectionToDelete; |
| 805 if (m_needPlaceholder) { | 805 if (m_needPlaceholder) { |
| 806 // Don't need a placeholder when deleting a selection that starts just | 806 // Don't need a placeholder when deleting a selection that starts just |
| 807 // before a table and ends inside it (we do need placeholders to hold | 807 // before a table and ends inside it (we do need placeholders to hold |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 visitor->trace(m_deleteIntoBlockquoteStyle); | 899 visitor->trace(m_deleteIntoBlockquoteStyle); |
| 900 visitor->trace(m_startRoot); | 900 visitor->trace(m_startRoot); |
| 901 visitor->trace(m_endRoot); | 901 visitor->trace(m_endRoot); |
| 902 visitor->trace(m_startTableRow); | 902 visitor->trace(m_startTableRow); |
| 903 visitor->trace(m_endTableRow); | 903 visitor->trace(m_endTableRow); |
| 904 visitor->trace(m_temporaryPlaceholder); | 904 visitor->trace(m_temporaryPlaceholder); |
| 905 CompositeEditCommand::trace(visitor); | 905 CompositeEditCommand::trace(visitor); |
| 906 } | 906 } |
| 907 | 907 |
| 908 } // namespace blink | 908 } // namespace blink |
| OLD | NEW |