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 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
523 // DeleteFromTextNodeCommand is never aborted. | 523 // DeleteFromTextNodeCommand is never aborted. |
524 applyCommandToComposite( | 524 applyCommandToComposite( |
525 DeleteFromTextNodeCommand::create(node, offset, count), | 525 DeleteFromTextNodeCommand::create(node, offset, count), |
526 ASSERT_NO_EDITING_ABORT); | 526 ASSERT_NO_EDITING_ABORT); |
527 } | 527 } |
528 | 528 |
529 void CompositeEditCommand::replaceTextInNode(Text* node, | 529 void CompositeEditCommand::replaceTextInNode(Text* node, |
530 unsigned offset, | 530 unsigned offset, |
531 unsigned count, | 531 unsigned count, |
532 const String& replacementText) { | 532 const String& replacementText) { |
533 // Notify listeners that a replacement has occurred rather than two separate | |
534 // insert + delete operations | |
535 SynchronousMutationNotifier::ScopedNotificationSuppressor suppressor( | |
536 &document()); | |
537 | |
533 // DeleteFromTextNodeCommand and InsertIntoTextNodeCommand are never | 538 // DeleteFromTextNodeCommand and InsertIntoTextNodeCommand are never |
534 // aborted. | 539 // aborted. |
535 applyCommandToComposite( | 540 applyCommandToComposite( |
536 DeleteFromTextNodeCommand::create(node, offset, count), | 541 DeleteFromTextNodeCommand::create(node, offset, count), |
537 ASSERT_NO_EDITING_ABORT); | 542 ASSERT_NO_EDITING_ABORT); |
538 if (!replacementText.isEmpty()) | 543 if (!replacementText.isEmpty()) |
539 applyCommandToComposite( | 544 applyCommandToComposite( |
540 InsertIntoTextNodeCommand::create(node, offset, replacementText), | 545 InsertIntoTextNodeCommand::create(node, offset, replacementText), |
541 ASSERT_NO_EDITING_ABORT); | 546 ASSERT_NO_EDITING_ABORT); |
542 } | 547 } |
543 | 548 |
544 Position CompositeEditCommand::replaceSelectedTextInNode(const String& text) { | 549 Position CompositeEditCommand::replaceSelectedTextInNode(const String& text) { |
545 Position start = endingSelection().start(); | 550 Position start = endingSelection().start(); |
546 Position end = endingSelection().end(); | 551 Position end = endingSelection().end(); |
547 if (start.computeContainerNode() != end.computeContainerNode() || | 552 if (start.computeContainerNode() != end.computeContainerNode() || |
548 !start.computeContainerNode()->isTextNode() || | 553 !start.computeContainerNode()->isTextNode() || |
549 isTabHTMLSpanElementTextNode(start.computeContainerNode())) | 554 isTabHTMLSpanElementTextNode(start.computeContainerNode())) |
550 return Position(); | 555 return Position(); |
551 | 556 |
552 Text* textNode = toText(start.computeContainerNode()); | 557 Text* textNode = toText(start.computeContainerNode()); |
553 replaceTextInNode(textNode, start.offsetInContainerNode(), | 558 replaceTextInNode(textNode, start.offsetInContainerNode(), |
554 end.offsetInContainerNode() - start.offsetInContainerNode(), | 559 end.offsetInContainerNode() - start.offsetInContainerNode(), |
555 text); | 560 text); |
556 | 561 |
557 return Position(textNode, start.offsetInContainerNode() + text.length()); | 562 return Position(textNode, start.offsetInContainerNode() + text.length()); |
558 } | 563 } |
559 | 564 |
560 static void copyMarkerTypesAndDescriptions( | |
561 const DocumentMarkerVector& markerPointers, | |
562 Vector<DocumentMarker::MarkerType>& types, | |
563 Vector<String>& descriptions) { | |
564 size_t arraySize = markerPointers.size(); | |
565 types.reserveCapacity(arraySize); | |
566 descriptions.reserveCapacity(arraySize); | |
567 for (const auto& markerPointer : markerPointers) { | |
568 types.push_back(markerPointer->type()); | |
569 descriptions.push_back(markerPointer->description()); | |
570 } | |
571 } | |
572 | |
573 void CompositeEditCommand::replaceTextInNodePreservingMarkers( | |
574 Text* node, | |
575 unsigned offset, | |
576 unsigned count, | |
577 const String& replacementText) { | |
578 DocumentMarkerController& markerController = document().markers(); | |
579 Vector<DocumentMarker::MarkerType> types; | |
580 Vector<String> descriptions; | |
581 copyMarkerTypesAndDescriptions( | |
582 markerController.markersInRange( | |
583 EphemeralRange(Position(node, offset), | |
584 Position(node, offset + count)), | |
585 DocumentMarker::AllMarkers()), | |
586 types, descriptions); | |
587 | |
588 replaceTextInNode(node, offset, count, replacementText); | |
589 | |
590 // Re-adding markers requires a clean tree. | |
591 document().updateStyleAndLayout(); | |
592 | |
593 DocumentLifecycle::DisallowTransitionScope disallowTransition( | |
594 document().lifecycle()); | |
595 Position startPosition(node, offset); | |
596 Position endPosition(node, offset + replacementText.length()); | |
597 DCHECK_EQ(types.size(), descriptions.size()); | |
598 | |
599 for (size_t i = 0; i < types.size(); ++i) | |
600 markerController.addMarker(startPosition, endPosition, types[i], | |
601 descriptions[i]); | |
602 } | |
603 | |
604 Position CompositeEditCommand::positionOutsideTabSpan(const Position& pos) { | 565 Position CompositeEditCommand::positionOutsideTabSpan(const Position& pos) { |
605 if (!isTabHTMLSpanElementTextNode(pos.anchorNode())) | 566 if (!isTabHTMLSpanElementTextNode(pos.anchorNode())) |
606 return pos; | 567 return pos; |
607 | 568 |
608 switch (pos.anchorType()) { | 569 switch (pos.anchorType()) { |
609 case PositionAnchorType::BeforeChildren: | 570 case PositionAnchorType::BeforeChildren: |
610 case PositionAnchorType::AfterChildren: | 571 case PositionAnchorType::AfterChildren: |
611 NOTREACHED(); | 572 NOTREACHED(); |
612 return pos; | 573 return pos; |
613 case PositionAnchorType::OffsetInAnchor: | 574 case PositionAnchorType::OffsetInAnchor: |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
766 !isWhitespace(toText(textNode->nextSibling())->data()[0]); | 727 !isWhitespace(toText(textNode->nextSibling())->data()[0]); |
767 const bool shouldEmitNBSPbeforeEnd = | 728 const bool shouldEmitNBSPbeforeEnd = |
768 (isEndOfParagraph(visibleDownstreamPos) || | 729 (isEndOfParagraph(visibleDownstreamPos) || |
769 (unsigned)downstream == text.length()) && | 730 (unsigned)downstream == text.length()) && |
770 !nextSiblingIsTextNode; | 731 !nextSiblingIsTextNode; |
771 String rebalancedString = stringWithRebalancedWhitespace( | 732 String rebalancedString = stringWithRebalancedWhitespace( |
772 string, isStartOfParagraph(visibleUpstreamPos) || !upstream, | 733 string, isStartOfParagraph(visibleUpstreamPos) || !upstream, |
773 shouldEmitNBSPbeforeEnd); | 734 shouldEmitNBSPbeforeEnd); |
774 | 735 |
775 if (string != rebalancedString) | 736 if (string != rebalancedString) |
776 replaceTextInNodePreservingMarkers(textNode, upstream, length, | 737 replaceTextInNode(textNode, upstream, length, rebalancedString); |
yosin_UTC9
2017/02/15 02:23:25
Let's make |replaceTextInNode()| to use |Character
| |
777 rebalancedString); | |
778 } | 738 } |
779 | 739 |
780 void CompositeEditCommand::prepareWhitespaceAtPositionForSplit( | 740 void CompositeEditCommand::prepareWhitespaceAtPositionForSplit( |
781 Position& position) { | 741 Position& position) { |
782 if (!isRichlyEditablePosition(position)) | 742 if (!isRichlyEditablePosition(position)) |
783 return; | 743 return; |
784 Node* node = position.anchorNode(); | 744 Node* node = position.anchorNode(); |
785 if (!node || !node->isTextNode()) | 745 if (!node || !node->isTextNode()) |
786 return; | 746 return; |
787 Text* textNode = toText(node); | 747 Text* textNode = toText(node); |
(...skipping 20 matching lines...) Expand all Loading... | |
808 } | 768 } |
809 | 769 |
810 void CompositeEditCommand:: | 770 void CompositeEditCommand:: |
811 replaceCollapsibleWhitespaceWithNonBreakingSpaceIfNeeded( | 771 replaceCollapsibleWhitespaceWithNonBreakingSpaceIfNeeded( |
812 const VisiblePosition& visiblePosition) { | 772 const VisiblePosition& visiblePosition) { |
813 if (!isCollapsibleWhitespace(characterAfter(visiblePosition))) | 773 if (!isCollapsibleWhitespace(characterAfter(visiblePosition))) |
814 return; | 774 return; |
815 Position pos = mostForwardCaretPosition(visiblePosition.deepEquivalent()); | 775 Position pos = mostForwardCaretPosition(visiblePosition.deepEquivalent()); |
816 if (!pos.computeContainerNode() || !pos.computeContainerNode()->isTextNode()) | 776 if (!pos.computeContainerNode() || !pos.computeContainerNode()->isTextNode()) |
817 return; | 777 return; |
818 replaceTextInNodePreservingMarkers(toText(pos.computeContainerNode()), | 778 replaceTextInNode(toText(pos.computeContainerNode()), |
819 pos.offsetInContainerNode(), 1, | 779 pos.offsetInContainerNode(), 1, nonBreakingSpaceString()); |
820 nonBreakingSpaceString()); | |
821 } | 780 } |
822 | 781 |
823 void CompositeEditCommand::rebalanceWhitespace() { | 782 void CompositeEditCommand::rebalanceWhitespace() { |
824 VisibleSelection selection = endingSelection(); | 783 VisibleSelection selection = endingSelection(); |
825 if (selection.isNone()) | 784 if (selection.isNone()) |
826 return; | 785 return; |
827 | 786 |
828 rebalanceWhitespaceAt(selection.start()); | 787 rebalanceWhitespaceAt(selection.start()); |
829 if (selection.isRange()) | 788 if (selection.isRange()) |
830 rebalanceWhitespaceAt(selection.end()); | 789 rebalanceWhitespaceAt(selection.end()); |
(...skipping 1140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1971 | 1930 |
1972 DEFINE_TRACE(CompositeEditCommand) { | 1931 DEFINE_TRACE(CompositeEditCommand) { |
1973 visitor->trace(m_commands); | 1932 visitor->trace(m_commands); |
1974 visitor->trace(m_startingSelection); | 1933 visitor->trace(m_startingSelection); |
1975 visitor->trace(m_endingSelection); | 1934 visitor->trace(m_endingSelection); |
1976 visitor->trace(m_undoStep); | 1935 visitor->trace(m_undoStep); |
1977 EditCommand::trace(visitor); | 1936 EditCommand::trace(visitor); |
1978 } | 1937 } |
1979 | 1938 |
1980 } // namespace blink | 1939 } // namespace blink |
OLD | NEW |