Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(825)

Side by Side Diff: third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp

Issue 2692093003: Rewrite DocumentMarkerController to use SynchronousMutationObserver (Closed)
Patch Set: Don't try to use -1 as default value for unsigned int Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698