| 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 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 | 334 |
| 335 static Position firstEditablePositionInNode(Node* node) | 335 static Position firstEditablePositionInNode(Node* node) |
| 336 { | 336 { |
| 337 ASSERT(node); | 337 ASSERT(node); |
| 338 Node* next = node; | 338 Node* next = node; |
| 339 while (next && !next->hasEditableStyle()) | 339 while (next && !next->hasEditableStyle()) |
| 340 next = NodeTraversal::next(*next, node); | 340 next = NodeTraversal::next(*next, node); |
| 341 return next ? firstPositionInOrBeforeNode(next) : Position(); | 341 return next ? firstPositionInOrBeforeNode(next) : Position(); |
| 342 } | 342 } |
| 343 | 343 |
| 344 void DeleteSelectionCommand::removeNode(PassRefPtrWillBeRawPtr<Node> node, Editi
ngState* editingState, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIs
AlwaysEditable) | 344 void DeleteSelectionCommand::removeNode(RawPtr<Node> node, EditingState* editing
State, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable) |
| 345 { | 345 { |
| 346 if (!node) | 346 if (!node) |
| 347 return; | 347 return; |
| 348 | 348 |
| 349 if (m_startRoot != m_endRoot && !(node->isDescendantOf(m_startRoot.get()) &&
node->isDescendantOf(m_endRoot.get()))) { | 349 if (m_startRoot != m_endRoot && !(node->isDescendantOf(m_startRoot.get()) &&
node->isDescendantOf(m_endRoot.get()))) { |
| 350 // If a node is not in both the start and end editable roots, remove it
only if its inside an editable region. | 350 // If a node is not in both the start and end editable roots, remove it
only if its inside an editable region. |
| 351 if (!node->parentNode()->hasEditableStyle()) { | 351 if (!node->parentNode()->hasEditableStyle()) { |
| 352 // Don't remove non-editable atomic nodes. | 352 // Don't remove non-editable atomic nodes. |
| 353 if (!node->hasChildren()) | 353 if (!node->hasChildren()) |
| 354 return; | 354 return; |
| 355 // Search this non-editable region for editable regions to empty. | 355 // Search this non-editable region for editable regions to empty. |
| 356 RefPtrWillBeRawPtr<Node> child = node->firstChild(); | 356 RawPtr<Node> child = node->firstChild(); |
| 357 while (child) { | 357 while (child) { |
| 358 RefPtrWillBeRawPtr<Node> nextChild = child->nextSibling(); | 358 RawPtr<Node> nextChild = child->nextSibling(); |
| 359 removeNode(child.get(), editingState, shouldAssumeContentIsAlway
sEditable); | 359 removeNode(child.get(), editingState, shouldAssumeContentIsAlway
sEditable); |
| 360 if (editingState->isAborted()) | 360 if (editingState->isAborted()) |
| 361 return; | 361 return; |
| 362 // Bail if nextChild is no longer node's child. | 362 // Bail if nextChild is no longer node's child. |
| 363 if (nextChild && nextChild->parentNode() != node) | 363 if (nextChild && nextChild->parentNode() != node) |
| 364 return; | 364 return; |
| 365 child = nextChild; | 365 child = nextChild; |
| 366 } | 366 } |
| 367 | 367 |
| 368 // Don't remove editable regions that are inside non-editable ones,
just clear them. | 368 // Don't remove editable regions that are inside non-editable ones,
just clear them. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 { | 416 { |
| 417 if (!position.isOffsetInAnchor() || position.computeContainerNode() != node) | 417 if (!position.isOffsetInAnchor() || position.computeContainerNode() != node) |
| 418 return; | 418 return; |
| 419 | 419 |
| 420 if (position.offsetInContainerNode() > offset + count) | 420 if (position.offsetInContainerNode() > offset + count) |
| 421 position = Position(position.computeContainerNode(), position.offsetInCo
ntainerNode() - count); | 421 position = Position(position.computeContainerNode(), position.offsetInCo
ntainerNode() - count); |
| 422 else if (position.offsetInContainerNode() > offset) | 422 else if (position.offsetInContainerNode() > offset) |
| 423 position = Position(position.computeContainerNode(), offset); | 423 position = Position(position.computeContainerNode(), offset); |
| 424 } | 424 } |
| 425 | 425 |
| 426 void DeleteSelectionCommand::deleteTextFromNode(PassRefPtrWillBeRawPtr<Text> nod
e, unsigned offset, unsigned count) | 426 void DeleteSelectionCommand::deleteTextFromNode(RawPtr<Text> node, unsigned offs
et, unsigned count) |
| 427 { | 427 { |
| 428 // FIXME: Update the endpoints of the range being deleted. | 428 // FIXME: Update the endpoints of the range being deleted. |
| 429 updatePositionForTextRemoval(node.get(), offset, count, m_endingPosition); | 429 updatePositionForTextRemoval(node.get(), offset, count, m_endingPosition); |
| 430 updatePositionForTextRemoval(node.get(), offset, count, m_leadingWhitespace)
; | 430 updatePositionForTextRemoval(node.get(), offset, count, m_leadingWhitespace)
; |
| 431 updatePositionForTextRemoval(node.get(), offset, count, m_trailingWhitespace
); | 431 updatePositionForTextRemoval(node.get(), offset, count, m_trailingWhitespace
); |
| 432 updatePositionForTextRemoval(node.get(), offset, count, m_downstreamEnd); | 432 updatePositionForTextRemoval(node.get(), offset, count, m_downstreamEnd); |
| 433 | 433 |
| 434 CompositeEditCommand::deleteTextFromNode(node, offset, count); | 434 CompositeEditCommand::deleteTextFromNode(node, offset, count); |
| 435 } | 435 } |
| 436 | 436 |
| 437 void DeleteSelectionCommand::makeStylingElementsDirectChildrenOfEditableRootToPr
eventStyleLoss(EditingState* editingState) | 437 void DeleteSelectionCommand::makeStylingElementsDirectChildrenOfEditableRootToPr
eventStyleLoss(EditingState* editingState) |
| 438 { | 438 { |
| 439 RefPtrWillBeRawPtr<Range> range = createRange(m_selectionToDelete.toNormaliz
edEphemeralRange()); | 439 RawPtr<Range> range = createRange(m_selectionToDelete.toNormalizedEphemeralR
ange()); |
| 440 RefPtrWillBeRawPtr<Node> node = range->firstNode(); | 440 RawPtr<Node> node = range->firstNode(); |
| 441 while (node && node != range->pastLastNode()) { | 441 while (node && node != range->pastLastNode()) { |
| 442 RefPtrWillBeRawPtr<Node> nextNode = NodeTraversal::next(*node); | 442 RawPtr<Node> nextNode = NodeTraversal::next(*node); |
| 443 if (isHTMLStyleElement(*node) || isHTMLLinkElement(*node)) { | 443 if (isHTMLStyleElement(*node) || isHTMLLinkElement(*node)) { |
| 444 nextNode = NodeTraversal::nextSkippingChildren(*node); | 444 nextNode = NodeTraversal::nextSkippingChildren(*node); |
| 445 RefPtrWillBeRawPtr<Element> rootEditableElement = node->rootEditable
Element(); | 445 RawPtr<Element> rootEditableElement = node->rootEditableElement(); |
| 446 if (rootEditableElement.get()) { | 446 if (rootEditableElement.get()) { |
| 447 removeNode(node, editingState); | 447 removeNode(node, editingState); |
| 448 if (editingState->isAborted()) | 448 if (editingState->isAborted()) |
| 449 return; | 449 return; |
| 450 appendNode(node, rootEditableElement, editingState); | 450 appendNode(node, rootEditableElement, editingState); |
| 451 if (editingState->isAborted()) | 451 if (editingState->isAborted()) |
| 452 return; | 452 return; |
| 453 } | 453 } |
| 454 } | 454 } |
| 455 node = nextNode; | 455 node = nextNode; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 | 508 |
| 509 // The selection to delete is all in one node. | 509 // The selection to delete is all in one node. |
| 510 if (!startNode->layoutObject() || (!startOffset && m_downstreamEnd.atLas
tEditingPositionForNode())) { | 510 if (!startNode->layoutObject() || (!startOffset && m_downstreamEnd.atLas
tEditingPositionForNode())) { |
| 511 removeNode(startNode, editingState); | 511 removeNode(startNode, editingState); |
| 512 if (editingState->isAborted()) | 512 if (editingState->isAborted()) |
| 513 return; | 513 return; |
| 514 } | 514 } |
| 515 } else { | 515 } else { |
| 516 bool startNodeWasDescendantOfEndNode = m_upstreamStart.anchorNode()->isD
escendantOf(m_downstreamEnd.anchorNode()); | 516 bool startNodeWasDescendantOfEndNode = m_upstreamStart.anchorNode()->isD
escendantOf(m_downstreamEnd.anchorNode()); |
| 517 // The selection to delete spans more than one node. | 517 // The selection to delete spans more than one node. |
| 518 RefPtrWillBeRawPtr<Node> node(startNode); | 518 RawPtr<Node> node(startNode); |
| 519 | 519 |
| 520 if (startOffset > 0) { | 520 if (startOffset > 0) { |
| 521 if (startNode->isTextNode()) { | 521 if (startNode->isTextNode()) { |
| 522 // in a text node that needs to be trimmed | 522 // in a text node that needs to be trimmed |
| 523 Text* text = toText(node); | 523 Text* text = toText(node); |
| 524 deleteTextFromNode(text, startOffset, text->length() - startOffs
et); | 524 deleteTextFromNode(text, startOffset, text->length() - startOffs
et); |
| 525 node = NodeTraversal::next(*node); | 525 node = NodeTraversal::next(*node); |
| 526 } else { | 526 } else { |
| 527 node = NodeTraversal::childAt(*startNode, startOffset); | 527 node = NodeTraversal::childAt(*startNode, startOffset); |
| 528 } | 528 } |
| 529 } else if (startNode == m_upstreamEnd.anchorNode() && startNode->isTextN
ode()) { | 529 } else if (startNode == m_upstreamEnd.anchorNode() && startNode->isTextN
ode()) { |
| 530 Text* text = toText(m_upstreamEnd.anchorNode()); | 530 Text* text = toText(m_upstreamEnd.anchorNode()); |
| 531 deleteTextFromNode(text, 0, m_upstreamEnd.computeOffsetInContainerNo
de()); | 531 deleteTextFromNode(text, 0, m_upstreamEnd.computeOffsetInContainerNo
de()); |
| 532 } | 532 } |
| 533 | 533 |
| 534 // handle deleting all nodes that are completely selected | 534 // handle deleting all nodes that are completely selected |
| 535 while (node && node != m_downstreamEnd.anchorNode()) { | 535 while (node && node != m_downstreamEnd.anchorNode()) { |
| 536 if (comparePositions(firstPositionInOrBeforeNode(node.get()), m_down
streamEnd) >= 0) { | 536 if (comparePositions(firstPositionInOrBeforeNode(node.get()), m_down
streamEnd) >= 0) { |
| 537 // NodeTraversal::nextSkippingChildren just blew past the end po
sition, so stop deleting | 537 // NodeTraversal::nextSkippingChildren just blew past the end po
sition, so stop deleting |
| 538 node = nullptr; | 538 node = nullptr; |
| 539 } else if (!m_downstreamEnd.anchorNode()->isDescendantOf(node.get())
) { | 539 } else if (!m_downstreamEnd.anchorNode()->isDescendantOf(node.get())
) { |
| 540 RefPtrWillBeRawPtr<Node> nextNode = NodeTraversal::nextSkippingC
hildren(*node); | 540 RawPtr<Node> nextNode = NodeTraversal::nextSkippingChildren(*nod
e); |
| 541 // if we just removed a node from the end container, update end
position so the | 541 // if we just removed a node from the end container, update end
position so the |
| 542 // check above will work | 542 // check above will work |
| 543 updatePositionForNodeRemoval(m_downstreamEnd, *node); | 543 updatePositionForNodeRemoval(m_downstreamEnd, *node); |
| 544 removeNode(node.get(), editingState); | 544 removeNode(node.get(), editingState); |
| 545 if (editingState->isAborted()) | 545 if (editingState->isAborted()) |
| 546 return; | 546 return; |
| 547 node = nextNode.get(); | 547 node = nextNode.get(); |
| 548 } else { | 548 } else { |
| 549 Node& n = NodeTraversal::lastWithinOrSelf(*node); | 549 Node& n = NodeTraversal::lastWithinOrSelf(*node); |
| 550 if (m_downstreamEnd.anchorNode() == n && m_downstreamEnd.compute
EditingOffset() >= caretMaxOffset(&n)) { | 550 if (m_downstreamEnd.anchorNode() == n && m_downstreamEnd.compute
EditingOffset() >= caretMaxOffset(&n)) { |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 m_needPlaceholder = needPlaceholder; | 714 m_needPlaceholder = needPlaceholder; |
| 715 // The endingPosition was likely clobbered by the move, so recompute it (mov
eParagraph selects the moved paragraph). | 715 // The endingPosition was likely clobbered by the move, so recompute it (mov
eParagraph selects the moved paragraph). |
| 716 m_endingPosition = endingSelection().start(); | 716 m_endingPosition = endingSelection().start(); |
| 717 } | 717 } |
| 718 | 718 |
| 719 void DeleteSelectionCommand::removePreviouslySelectedEmptyTableRows(EditingState
* editingState) | 719 void DeleteSelectionCommand::removePreviouslySelectedEmptyTableRows(EditingState
* editingState) |
| 720 { | 720 { |
| 721 if (m_endTableRow && m_endTableRow->inDocument() && m_endTableRow != m_start
TableRow) { | 721 if (m_endTableRow && m_endTableRow->inDocument() && m_endTableRow != m_start
TableRow) { |
| 722 Node* row = m_endTableRow->previousSibling(); | 722 Node* row = m_endTableRow->previousSibling(); |
| 723 while (row && row != m_startTableRow) { | 723 while (row && row != m_startTableRow) { |
| 724 RefPtrWillBeRawPtr<Node> previousRow = row->previousSibling(); | 724 RawPtr<Node> previousRow = row->previousSibling(); |
| 725 if (isTableRowEmpty(row)) { | 725 if (isTableRowEmpty(row)) { |
| 726 // Use a raw removeNode, instead of DeleteSelectionCommand's, | 726 // Use a raw removeNode, instead of DeleteSelectionCommand's, |
| 727 // because that won't remove rows, it only empties them in | 727 // because that won't remove rows, it only empties them in |
| 728 // preparation for this function. | 728 // preparation for this function. |
| 729 CompositeEditCommand::removeNode(row, editingState); | 729 CompositeEditCommand::removeNode(row, editingState); |
| 730 if (editingState->isAborted()) | 730 if (editingState->isAborted()) |
| 731 return; | 731 return; |
| 732 } | 732 } |
| 733 row = previousRow.get(); | 733 row = previousRow.get(); |
| 734 } | 734 } |
| 735 } | 735 } |
| 736 | 736 |
| 737 // Remove empty rows after the start row. | 737 // Remove empty rows after the start row. |
| 738 if (m_startTableRow && m_startTableRow->inDocument() && m_startTableRow != m
_endTableRow) { | 738 if (m_startTableRow && m_startTableRow->inDocument() && m_startTableRow != m
_endTableRow) { |
| 739 Node* row = m_startTableRow->nextSibling(); | 739 Node* row = m_startTableRow->nextSibling(); |
| 740 while (row && row != m_endTableRow) { | 740 while (row && row != m_endTableRow) { |
| 741 RefPtrWillBeRawPtr<Node> nextRow = row->nextSibling(); | 741 RawPtr<Node> nextRow = row->nextSibling(); |
| 742 if (isTableRowEmpty(row)) { | 742 if (isTableRowEmpty(row)) { |
| 743 CompositeEditCommand::removeNode(row, editingState); | 743 CompositeEditCommand::removeNode(row, editingState); |
| 744 if (editingState->isAborted()) | 744 if (editingState->isAborted()) |
| 745 return; | 745 return; |
| 746 } | 746 } |
| 747 row = nextRow.get(); | 747 row = nextRow.get(); |
| 748 } | 748 } |
| 749 } | 749 } |
| 750 | 750 |
| 751 if (m_endTableRow && m_endTableRow->inDocument() && m_endTableRow != m_start
TableRow) { | 751 if (m_endTableRow && m_endTableRow->inDocument() && m_endTableRow != m_start
TableRow) { |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 if (editingState->isAborted()) | 899 if (editingState->isAborted()) |
| 900 return; | 900 return; |
| 901 | 901 |
| 902 if (!m_needPlaceholder && rootWillStayOpenWithoutPlaceholder) { | 902 if (!m_needPlaceholder && rootWillStayOpenWithoutPlaceholder) { |
| 903 VisiblePosition visualEnding = createVisiblePosition(m_endingPosition); | 903 VisiblePosition visualEnding = createVisiblePosition(m_endingPosition); |
| 904 bool hasPlaceholder = lineBreakExistsAtVisiblePosition(visualEnding) | 904 bool hasPlaceholder = lineBreakExistsAtVisiblePosition(visualEnding) |
| 905 && nextPositionOf(visualEnding, CannotCrossEditingBoundary).isNull()
; | 905 && nextPositionOf(visualEnding, CannotCrossEditingBoundary).isNull()
; |
| 906 m_needPlaceholder = hasPlaceholder && lineBreakBeforeStart && !lineBreak
AtEndOfSelectionToDelete; | 906 m_needPlaceholder = hasPlaceholder && lineBreakBeforeStart && !lineBreak
AtEndOfSelectionToDelete; |
| 907 } | 907 } |
| 908 | 908 |
| 909 RefPtrWillBeRawPtr<HTMLBRElement> placeholder = m_needPlaceholder ? HTMLBREl
ement::create(document()) : nullptr; | 909 RawPtr<HTMLBRElement> placeholder = m_needPlaceholder ? HTMLBRElement::creat
e(document()) : nullptr; |
| 910 | 910 |
| 911 if (placeholder) { | 911 if (placeholder) { |
| 912 if (m_sanitizeMarkup) { | 912 if (m_sanitizeMarkup) { |
| 913 removeRedundantBlocks(editingState); | 913 removeRedundantBlocks(editingState); |
| 914 if (editingState->isAborted()) | 914 if (editingState->isAborted()) |
| 915 return; | 915 return; |
| 916 } | 916 } |
| 917 // handleGeneralDelete cause DOM mutation events so |m_endingPosition| | 917 // handleGeneralDelete cause DOM mutation events so |m_endingPosition| |
| 918 // can be out of document. | 918 // can be out of document. |
| 919 if (m_endingPosition.inDocument()) { | 919 if (m_endingPosition.inDocument()) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 963 visitor->trace(m_deleteIntoBlockquoteStyle); | 963 visitor->trace(m_deleteIntoBlockquoteStyle); |
| 964 visitor->trace(m_startRoot); | 964 visitor->trace(m_startRoot); |
| 965 visitor->trace(m_endRoot); | 965 visitor->trace(m_endRoot); |
| 966 visitor->trace(m_startTableRow); | 966 visitor->trace(m_startTableRow); |
| 967 visitor->trace(m_endTableRow); | 967 visitor->trace(m_endTableRow); |
| 968 visitor->trace(m_temporaryPlaceholder); | 968 visitor->trace(m_temporaryPlaceholder); |
| 969 CompositeEditCommand::trace(visitor); | 969 CompositeEditCommand::trace(visitor); |
| 970 } | 970 } |
| 971 | 971 |
| 972 } // namespace blink | 972 } // namespace blink |
| OLD | NEW |