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

Side by Side Diff: Source/core/editing/CompositeEditCommand.cpp

Issue 424493003: Use tighter typing in editing: CompositeEditCommand (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 #include "core/editing/SplitElementCommand.h" 56 #include "core/editing/SplitElementCommand.h"
57 #include "core/editing/SplitTextNodeCommand.h" 57 #include "core/editing/SplitTextNodeCommand.h"
58 #include "core/editing/SplitTextNodeContainingElementCommand.h" 58 #include "core/editing/SplitTextNodeContainingElementCommand.h"
59 #include "core/editing/TextIterator.h" 59 #include "core/editing/TextIterator.h"
60 #include "core/editing/VisibleUnits.h" 60 #include "core/editing/VisibleUnits.h"
61 #include "core/editing/WrapContentsInDummySpanCommand.h" 61 #include "core/editing/WrapContentsInDummySpanCommand.h"
62 #include "core/editing/htmlediting.h" 62 #include "core/editing/htmlediting.h"
63 #include "core/editing/markup.h" 63 #include "core/editing/markup.h"
64 #include "core/events/ScopedEventQueue.h" 64 #include "core/events/ScopedEventQueue.h"
65 #include "core/frame/LocalFrame.h" 65 #include "core/frame/LocalFrame.h"
66 #include "core/html/HTMLBRElement.h"
66 #include "core/html/HTMLElement.h" 67 #include "core/html/HTMLElement.h"
67 #include "core/html/HTMLSpanElement.h" 68 #include "core/html/HTMLSpanElement.h"
68 #include "core/rendering/InlineTextBox.h" 69 #include "core/rendering/InlineTextBox.h"
69 #include "core/rendering/RenderBlock.h" 70 #include "core/rendering/RenderBlock.h"
70 #include "core/rendering/RenderListItem.h" 71 #include "core/rendering/RenderListItem.h"
71 #include "core/rendering/RenderText.h" 72 #include "core/rendering/RenderText.h"
72 73
73 namespace blink { 74 namespace blink {
74 75
75 using namespace HTMLNames; 76 using namespace HTMLNames;
(...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 deleteInsignificantText(textNode, startOffset, endOffset); 821 deleteInsignificantText(textNode, startOffset, endOffset);
821 } 822 }
822 } 823 }
823 824
824 void CompositeEditCommand::deleteInsignificantTextDownstream(const Position& pos ) 825 void CompositeEditCommand::deleteInsignificantTextDownstream(const Position& pos )
825 { 826 {
826 Position end = VisiblePosition(pos, VP_DEFAULT_AFFINITY).next().deepEquivale nt().downstream(); 827 Position end = VisiblePosition(pos, VP_DEFAULT_AFFINITY).next().deepEquivale nt().downstream();
827 deleteInsignificantText(pos, end); 828 deleteInsignificantText(pos, end);
828 } 829 }
829 830
830 PassRefPtrWillBeRawPtr<Node> CompositeEditCommand::appendBlockPlaceholder(PassRe fPtrWillBeRawPtr<Element> container) 831 PassRefPtrWillBeRawPtr<HTMLBRElement> CompositeEditCommand::appendBlockPlacehold er(PassRefPtrWillBeRawPtr<Element> container)
831 { 832 {
832 if (!container) 833 if (!container)
833 return nullptr; 834 return nullptr;
834 835
835 document().updateLayoutIgnorePendingStylesheets(); 836 document().updateLayoutIgnorePendingStylesheets();
836 837
837 // Should assert isRenderBlockFlow || isInlineFlow when deletion improves. S ee 4244964. 838 // Should assert isRenderBlockFlow || isInlineFlow when deletion improves. S ee 4244964.
838 ASSERT(container->renderer()); 839 ASSERT(container->renderer());
839 840
840 RefPtrWillBeRawPtr<Node> placeholder = createBlockPlaceholderElement(documen t()); 841 RefPtrWillBeRawPtr<HTMLBRElement> placeholder = createBlockPlaceholderElemen t(document());
841 appendNode(placeholder, container); 842 appendNode(placeholder, container);
842 return placeholder.release(); 843 return placeholder.release();
843 } 844 }
844 845
845 PassRefPtrWillBeRawPtr<Node> CompositeEditCommand::insertBlockPlaceholder(const Position& pos) 846 PassRefPtrWillBeRawPtr<HTMLBRElement> CompositeEditCommand::insertBlockPlacehold er(const Position& pos)
846 { 847 {
847 if (pos.isNull()) 848 if (pos.isNull())
848 return nullptr; 849 return nullptr;
849 850
850 // Should assert isRenderBlockFlow || isInlineFlow when deletion improves. S ee 4244964. 851 // Should assert isRenderBlockFlow || isInlineFlow when deletion improves. S ee 4244964.
851 ASSERT(pos.deprecatedNode()->renderer()); 852 ASSERT(pos.deprecatedNode()->renderer());
852 853
853 RefPtrWillBeRawPtr<Node> placeholder = createBlockPlaceholderElement(documen t()); 854 RefPtrWillBeRawPtr<HTMLBRElement> placeholder = createBlockPlaceholderElemen t(document());
854 insertNodeAt(placeholder, pos); 855 insertNodeAt(placeholder, pos);
855 return placeholder.release(); 856 return placeholder.release();
856 } 857 }
857 858
858 PassRefPtrWillBeRawPtr<Node> CompositeEditCommand::addBlockPlaceholderIfNeeded(E lement* container) 859 PassRefPtrWillBeRawPtr<HTMLBRElement> CompositeEditCommand::addBlockPlaceholderI fNeeded(Element* container)
859 { 860 {
860 if (!container) 861 if (!container)
861 return nullptr; 862 return nullptr;
862 863
863 document().updateLayoutIgnorePendingStylesheets(); 864 document().updateLayoutIgnorePendingStylesheets();
864 865
865 RenderObject* renderer = container->renderer(); 866 RenderObject* renderer = container->renderer();
866 if (!renderer || !renderer->isRenderBlockFlow()) 867 if (!renderer || !renderer->isRenderBlockFlow())
867 return nullptr; 868 return nullptr;
868 869
869 // append the placeholder to make sure it follows 870 // append the placeholder to make sure it follows
870 // any unrendered blocks 871 // any unrendered blocks
871 RenderBlock* block = toRenderBlock(renderer); 872 RenderBlockFlow* block = toRenderBlockFlow(renderer);
872 if (block->height() == 0 || (block->isListItem() && toRenderListItem(block)- >isEmpty())) 873 if (block->height() == 0 || (block->isListItem() && toRenderListItem(block)- >isEmpty()))
873 return appendBlockPlaceholder(container); 874 return appendBlockPlaceholder(container);
874 875
875 return nullptr; 876 return nullptr;
876 } 877 }
877 878
878 // Assumes that the position is at a placeholder and does the removal without mu ch checking. 879 // Assumes that the position is at a placeholder and does the removal without mu ch checking.
879 void CompositeEditCommand::removePlaceholderAt(const Position& p) 880 void CompositeEditCommand::removePlaceholderAt(const Position& p)
880 { 881 {
881 ASSERT(lineBreakExistsAtPosition(p)); 882 ASSERT(lineBreakExistsAtPosition(p));
882 883
883 // We are certain that the position is at a line break, but it may be a br o r a preserved newline. 884 // We are certain that the position is at a line break, but it may be a br o r a preserved newline.
884 if (isHTMLBRElement(*p.anchorNode())) { 885 if (isHTMLBRElement(*p.anchorNode())) {
885 removeNode(p.anchorNode()); 886 removeNode(p.anchorNode());
886 return; 887 return;
887 } 888 }
888 889
889 deleteTextFromNode(toText(p.anchorNode()), p.offsetInContainerNode(), 1); 890 deleteTextFromNode(toText(p.anchorNode()), p.offsetInContainerNode(), 1);
890 } 891 }
891 892
892 PassRefPtrWillBeRawPtr<Element> CompositeEditCommand::insertNewDefaultParagraphE lementAt(const Position& position) 893 PassRefPtrWillBeRawPtr<HTMLElement> CompositeEditCommand::insertNewDefaultParagr aphElementAt(const Position& position)
893 { 894 {
894 RefPtrWillBeRawPtr<Element> paragraphElement = createDefaultParagraphElement (document()); 895 RefPtrWillBeRawPtr<HTMLElement> paragraphElement = createDefaultParagraphEle ment(document());
895 paragraphElement->appendChild(createBreakElement(document())); 896 paragraphElement->appendChild(createBreakElement(document()));
896 insertNodeAt(paragraphElement, position); 897 insertNodeAt(paragraphElement, position);
897 return paragraphElement.release(); 898 return paragraphElement.release();
898 } 899 }
899 900
900 // If the paragraph is not entirely within it's own block, create one and move t he paragraph into 901 // If the paragraph is not entirely within it's own block, create one and move t he paragraph into
901 // it, and return that block. Otherwise return 0. 902 // it, and return that block. Otherwise return 0.
902 PassRefPtrWillBeRawPtr<Element> CompositeEditCommand::moveParagraphContentsToNew BlockIfNecessary(const Position& pos) 903 PassRefPtrWillBeRawPtr<HTMLElement> CompositeEditCommand::moveParagraphContentsT oNewBlockIfNecessary(const Position& pos)
903 { 904 {
904 ASSERT(isEditablePosition(pos, ContentIsEditable, DoNotUpdateStyle)); 905 ASSERT(isEditablePosition(pos, ContentIsEditable, DoNotUpdateStyle));
905 906
906 // It's strange that this function is responsible for verifying that pos has not been invalidated 907 // It's strange that this function is responsible for verifying that pos has not been invalidated
907 // by an earlier call to this function. The caller, applyBlockStyle, should do this. 908 // by an earlier call to this function. The caller, applyBlockStyle, should do this.
908 VisiblePosition visiblePos(pos, VP_DEFAULT_AFFINITY); 909 VisiblePosition visiblePos(pos, VP_DEFAULT_AFFINITY);
909 VisiblePosition visibleParagraphStart(startOfParagraph(visiblePos)); 910 VisiblePosition visibleParagraphStart(startOfParagraph(visiblePos));
910 VisiblePosition visibleParagraphEnd = endOfParagraph(visiblePos); 911 VisiblePosition visibleParagraphEnd = endOfParagraph(visiblePos);
911 VisiblePosition next = visibleParagraphEnd.next(); 912 VisiblePosition next = visibleParagraphEnd.next();
912 VisiblePosition visibleEnd = next.isNotNull() ? next : visibleParagraphEnd; 913 VisiblePosition visibleEnd = next.isNotNull() ? next : visibleParagraphEnd;
(...skipping 27 matching lines...) Expand all
940 return nullptr; 941 return nullptr;
941 } else if (isEndOfEditableOrNonEditableContent(visibleEnd)) { 942 } else if (isEndOfEditableOrNonEditableContent(visibleEnd)) {
942 // At the end of the editable region. We can bail here as well. 943 // At the end of the editable region. We can bail here as well.
943 return nullptr; 944 return nullptr;
944 } 945 }
945 } 946 }
946 947
947 if (visibleParagraphEnd.isNull()) 948 if (visibleParagraphEnd.isNull())
948 return nullptr; 949 return nullptr;
949 950
950 RefPtrWillBeRawPtr<Element> newBlock = insertNewDefaultParagraphElementAt(up streamStart); 951 RefPtrWillBeRawPtr<HTMLElement> newBlock = insertNewDefaultParagraphElementA t(upstreamStart);
951 952
952 bool endWasBr = isHTMLBRElement(*visibleParagraphEnd.deepEquivalent().deprec atedNode()); 953 bool endWasBr = isHTMLBRElement(*visibleParagraphEnd.deepEquivalent().deprec atedNode());
953 954
954 // Inserting default paragraph element can change visible position. We 955 // Inserting default paragraph element can change visible position. We
955 // should update visible positions before use them. 956 // should update visible positions before use them.
956 visiblePos = VisiblePosition(pos, VP_DEFAULT_AFFINITY); 957 visiblePos = VisiblePosition(pos, VP_DEFAULT_AFFINITY);
957 visibleParagraphStart = VisiblePosition(startOfParagraph(visiblePos)); 958 visibleParagraphStart = VisiblePosition(startOfParagraph(visiblePos));
958 visibleParagraphEnd = VisiblePosition(endOfParagraph(visiblePos)); 959 visibleParagraphEnd = VisiblePosition(endOfParagraph(visiblePos));
959 moveParagraphs(visibleParagraphStart, visibleParagraphEnd, VisiblePosition(f irstPositionInNode(newBlock.get()))); 960 moveParagraphs(visibleParagraphStart, visibleParagraphEnd, VisiblePosition(f irstPositionInNode(newBlock.get())));
960 961
961 if (newBlock->lastChild() && isHTMLBRElement(*newBlock->lastChild()) && !end WasBr) 962 if (newBlock->lastChild() && isHTMLBRElement(*newBlock->lastChild()) && !end WasBr)
962 removeNode(newBlock->lastChild()); 963 removeNode(newBlock->lastChild());
963 964
964 return newBlock.release(); 965 return newBlock.release();
965 } 966 }
966 967
967 void CompositeEditCommand::pushAnchorElementDown(Node* anchorNode) 968 void CompositeEditCommand::pushAnchorElementDown(Element* anchorNode)
968 { 969 {
969 if (!anchorNode) 970 if (!anchorNode)
970 return; 971 return;
971 972
972 ASSERT(anchorNode->isLink()); 973 ASSERT(anchorNode->isLink());
973 974
974 setEndingSelection(VisibleSelection::selectionFromContentsOfNode(anchorNode) ); 975 setEndingSelection(VisibleSelection::selectionFromContentsOfNode(anchorNode) );
975 applyStyledElement(toElement(anchorNode)); 976 applyStyledElement(anchorNode);
976 // Clones of anchorNode have been pushed down, now remove it. 977 // Clones of anchorNode have been pushed down, now remove it.
977 if (anchorNode->inDocument()) 978 if (anchorNode->inDocument())
978 removeNodePreservingChildren(anchorNode); 979 removeNodePreservingChildren(anchorNode);
979 } 980 }
980 981
981 // Clone the paragraph between start and end under blockElement, 982 // Clone the paragraph between start and end under blockElement,
982 // preserving the hierarchy up to outerNode. 983 // preserving the hierarchy up to outerNode.
983 984
984 void CompositeEditCommand::cloneParagraphUnderNewElement(const Position& start, const Position& end, Node* passedOuterNode, Element* blockElement) 985 void CompositeEditCommand::cloneParagraphUnderNewElement(const Position& start, const Position& end, Node* passedOuterNode, Element* blockElement)
985 { 986 {
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
1362 return false; 1363 return false;
1363 1364
1364 if (!isStartOfParagraph(caret) || !isEndOfParagraph(caret)) 1365 if (!isStartOfParagraph(caret) || !isEndOfParagraph(caret))
1365 return false; 1366 return false;
1366 1367
1367 VisiblePosition previous(caret.previous(CannotCrossEditingBoundary)); 1368 VisiblePosition previous(caret.previous(CannotCrossEditingBoundary));
1368 // Only move forward if there's nothing before the caret, or if there's unqu oted content before it. 1369 // Only move forward if there's nothing before the caret, or if there's unqu oted content before it.
1369 if (enclosingNodeOfType(previous.deepEquivalent(), &isMailBlockquote)) 1370 if (enclosingNodeOfType(previous.deepEquivalent(), &isMailBlockquote))
1370 return false; 1371 return false;
1371 1372
1372 RefPtrWillBeRawPtr<Node> br = createBreakElement(document()); 1373 RefPtrWillBeRawPtr<HTMLBRElement> br = createBreakElement(document());
1373 // We want to replace this quoted paragraph with an unquoted one, so insert a br 1374 // We want to replace this quoted paragraph with an unquoted one, so insert a br
1374 // to hold the caret before the highest blockquote. 1375 // to hold the caret before the highest blockquote.
1375 insertNodeBefore(br, highestBlockquote); 1376 insertNodeBefore(br, highestBlockquote);
1376 VisiblePosition atBR(positionBeforeNode(br.get())); 1377 VisiblePosition atBR(positionBeforeNode(br.get()));
1377 // If the br we inserted collapsed, for example foo<br><blockquote>...</bloc kquote>, insert 1378 // If the br we inserted collapsed, for example foo<br><blockquote>...</bloc kquote>, insert
1378 // a second one. 1379 // a second one.
1379 if (!isStartOfParagraph(atBR)) 1380 if (!isStartOfParagraph(atBR))
1380 insertNodeBefore(createBreakElement(document()), br); 1381 insertNodeBefore(createBreakElement(document()), br);
1381 setEndingSelection(VisibleSelection(atBR, endingSelection().isDirectional()) ); 1382 setEndingSelection(VisibleSelection(atBR, endingSelection().isDirectional()) );
1382 1383
(...skipping 23 matching lines...) Expand all
1406 // Operations use this function to avoid inserting content into an anchor when a t the start or the end of 1407 // Operations use this function to avoid inserting content into an anchor when a t the start or the end of
1407 // that anchor, as in NSTextView. 1408 // that anchor, as in NSTextView.
1408 // FIXME: This is only an approximation of NSTextViews insertion behavior, which varies depending on how 1409 // FIXME: This is only an approximation of NSTextViews insertion behavior, which varies depending on how
1409 // the caret was made. 1410 // the caret was made.
1410 Position CompositeEditCommand::positionAvoidingSpecialElementBoundary(const Posi tion& original) 1411 Position CompositeEditCommand::positionAvoidingSpecialElementBoundary(const Posi tion& original)
1411 { 1412 {
1412 if (original.isNull()) 1413 if (original.isNull())
1413 return original; 1414 return original;
1414 1415
1415 VisiblePosition visiblePos(original); 1416 VisiblePosition visiblePos(original);
1416 Node* enclosingAnchor = enclosingAnchorElement(original); 1417 Element* enclosingAnchor = enclosingAnchorElement(original);
1417 Position result = original; 1418 Position result = original;
1418 1419
1419 if (!enclosingAnchor) 1420 if (!enclosingAnchor)
1420 return result; 1421 return result;
1421 1422
1422 // Don't avoid block level anchors, because that would insert content into t he wrong paragraph. 1423 // Don't avoid block level anchors, because that would insert content into t he wrong paragraph.
1423 if (enclosingAnchor && !isBlock(enclosingAnchor)) { 1424 if (enclosingAnchor && !isBlock(enclosingAnchor)) {
1424 VisiblePosition firstInAnchor(firstPositionInNode(enclosingAnchor)); 1425 VisiblePosition firstInAnchor(firstPositionInNode(enclosingAnchor));
1425 VisiblePosition lastInAnchor(lastPositionInNode(enclosingAnchor)); 1426 VisiblePosition lastInAnchor(lastPositionInNode(enclosingAnchor));
1426 // If visually just after the anchor, insert *inside* the anchor unless it's the last 1427 // If visually just after the anchor, insert *inside* the anchor unless it's the last
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1473 ASSERT(start != end); 1474 ASSERT(start != end);
1474 1475
1475 if (shouldSplitAncestor && end->parentNode()) 1476 if (shouldSplitAncestor && end->parentNode())
1476 end = end->parentNode(); 1477 end = end->parentNode();
1477 if (!start->isDescendantOf(end)) 1478 if (!start->isDescendantOf(end))
1478 return end; 1479 return end;
1479 1480
1480 RefPtrWillBeRawPtr<Node> endNode = end; 1481 RefPtrWillBeRawPtr<Node> endNode = end;
1481 RefPtrWillBeRawPtr<Node> node = nullptr; 1482 RefPtrWillBeRawPtr<Node> node = nullptr;
1482 for (node = start; node->parentNode() != endNode; node = node->parentNode()) { 1483 for (node = start; node->parentNode() != endNode; node = node->parentNode()) {
1483 if (!node->parentNode()->isElementNode()) 1484 Element* parentElement = node->parentElement();
1485 if (!parentElement)
1484 break; 1486 break;
1485 // Do not split a node when doing so introduces an empty node. 1487 // Do not split a node when doing so introduces an empty node.
1486 VisiblePosition positionInParent(firstPositionInNode(node->parentNode()) ); 1488 VisiblePosition positionInParent(firstPositionInNode(parentElement));
1487 VisiblePosition positionInNode(firstPositionInOrBeforeNode(node.get())); 1489 VisiblePosition positionInNode(firstPositionInOrBeforeNode(node.get()));
1488 if (positionInParent != positionInNode) 1490 if (positionInParent != positionInNode)
1489 splitElement(toElement(node->parentNode()), node); 1491 splitElement(parentElement, node);
1490 } 1492 }
1491 1493
1492 return node.release(); 1494 return node.release();
1493 } 1495 }
1494 1496
1495 PassRefPtrWillBeRawPtr<Element> createBlockPlaceholderElement(Document& document )
1496 {
1497 return document.createElement(brTag, false);
1498 }
1499
1500 void CompositeEditCommand::trace(Visitor* visitor) 1497 void CompositeEditCommand::trace(Visitor* visitor)
1501 { 1498 {
1502 visitor->trace(m_commands); 1499 visitor->trace(m_commands);
1503 visitor->trace(m_composition); 1500 visitor->trace(m_composition);
1504 EditCommand::trace(visitor); 1501 EditCommand::trace(visitor);
1505 } 1502 }
1506 1503
1507 } // namespace blink 1504 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/editing/CompositeEditCommand.h ('k') | Source/core/editing/DeleteSelectionCommand.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698