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

Side by Side Diff: Source/core/editing/commands/ReplaceSelectionCommand.cpp

Issue 1302353002: Get rid of redundant member function PositionAlgorithm<Strategy>::{upstream,downstream} (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: 2015-08-22T04:51:20 Rebase Created 5 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2009, 2010, 2011 Google Inc. All rights reserved. 3 * Copyright (C) 2009, 2010, 2011 Google Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 1005 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 ASSERT(isHTMLBRElement(br)); 1016 ASSERT(isHTMLBRElement(br));
1017 // Insert content between the two blockquotes, but remove the br (since it was just a placeholder). 1017 // Insert content between the two blockquotes, but remove the br (since it was just a placeholder).
1018 insertionPos = positionInParentBeforeNode(*br); 1018 insertionPos = positionInParentBeforeNode(*br);
1019 removeNode(br); 1019 removeNode(br);
1020 } 1020 }
1021 1021
1022 // Inserting content could cause whitespace to collapse, e.g. inserting <div >foo</div> into hello^ world. 1022 // Inserting content could cause whitespace to collapse, e.g. inserting <div >foo</div> into hello^ world.
1023 prepareWhitespaceAtPositionForSplit(insertionPos); 1023 prepareWhitespaceAtPositionForSplit(insertionPos);
1024 1024
1025 // If the downstream node has been removed there's no point in continuing. 1025 // If the downstream node has been removed there's no point in continuing.
1026 if (!insertionPos.downstream().anchorNode()) 1026 if (!mostForwardCaretPosition(insertionPos).anchorNode())
1027 return; 1027 return;
1028 1028
1029 // NOTE: This would be an incorrect usage of downstream() if downstream() we re changed to mean the last position after 1029 // NOTE: This would be an incorrect usage of downstream() if downstream() we re changed to mean the last position after
1030 // p that maps to the same visible position as p (since in the case where a br is at the end of a block and collapsed 1030 // p that maps to the same visible position as p (since in the case where a br is at the end of a block and collapsed
1031 // away, there are positions after the br which map to the same visible posi tion as [br, 0]). 1031 // away, there are positions after the br which map to the same visible posi tion as [br, 0]).
1032 HTMLBRElement* endBR = isHTMLBRElement(*insertionPos.downstream().anchorNode ()) ? toHTMLBRElement(insertionPos.downstream().anchorNode()) : 0; 1032 HTMLBRElement* endBR = isHTMLBRElement(*mostForwardCaretPosition(insertionPo s).anchorNode()) ? toHTMLBRElement(mostForwardCaretPosition(insertionPos).anchor Node()) : 0;
1033 VisiblePosition originalVisPosBeforeEndBR; 1033 VisiblePosition originalVisPosBeforeEndBR;
1034 if (endBR) 1034 if (endBR)
1035 originalVisPosBeforeEndBR = VisiblePosition(positionBeforeNode(endBR)).p revious(); 1035 originalVisPosBeforeEndBR = VisiblePosition(positionBeforeNode(endBR)).p revious();
1036 1036
1037 RefPtrWillBeRawPtr<Element> enclosingBlockOfInsertionPos = enclosingBlock(in sertionPos.anchorNode()); 1037 RefPtrWillBeRawPtr<Element> enclosingBlockOfInsertionPos = enclosingBlock(in sertionPos.anchorNode());
1038 1038
1039 // Adjust insertionPos to prevent nesting. 1039 // Adjust insertionPos to prevent nesting.
1040 // If the start was in a Mail blockquote, we will have already handled adjus ting insertionPos above. 1040 // If the start was in a Mail blockquote, we will have already handled adjus ting insertionPos above.
1041 if (m_preventNesting && enclosingBlockOfInsertionPos && !isTableCell(enclosi ngBlockOfInsertionPos.get()) && !startIsInsideMailBlockquote) { 1041 if (m_preventNesting && enclosingBlockOfInsertionPos && !isTableCell(enclosi ngBlockOfInsertionPos.get()) && !startIsInsideMailBlockquote) {
1042 ASSERT(enclosingBlockOfInsertionPos != currentRoot); 1042 ASSERT(enclosingBlockOfInsertionPos != currentRoot);
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 if (startOfParagraph(endOfInsertedContent).deepEquivalent() == startOfPa ragraphToMove.deepEquivalent()) { 1212 if (startOfParagraph(endOfInsertedContent).deepEquivalent() == startOfPa ragraphToMove.deepEquivalent()) {
1213 insertNodeAt(createBreakElement(document()).get(), endOfInsertedCont ent.deepEquivalent()); 1213 insertNodeAt(createBreakElement(document()).get(), endOfInsertedCont ent.deepEquivalent());
1214 // Mutation events (bug 22634) triggered by inserting the <br> might have removed the content we're about to move 1214 // Mutation events (bug 22634) triggered by inserting the <br> might have removed the content we're about to move
1215 if (!startOfParagraphToMove.deepEquivalent().inDocument()) 1215 if (!startOfParagraphToMove.deepEquivalent().inDocument())
1216 return; 1216 return;
1217 } 1217 }
1218 1218
1219 // FIXME: Maintain positions for the start and end of inserted content i nstead of keeping nodes. The nodes are 1219 // FIXME: Maintain positions for the start and end of inserted content i nstead of keeping nodes. The nodes are
1220 // only ever used to create positions where inserted content starts/ends . 1220 // only ever used to create positions where inserted content starts/ends .
1221 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToM ove), destination); 1221 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToM ove), destination);
1222 m_startOfInsertedContent = endingSelection().visibleStart().deepEquivale nt().downstream(); 1222 m_startOfInsertedContent = mostForwardCaretPosition(endingSelection().vi sibleStart().deepEquivalent());
1223 if (m_endOfInsertedContent.isOrphan()) 1223 if (m_endOfInsertedContent.isOrphan())
1224 m_endOfInsertedContent = endingSelection().visibleEnd().deepEquivale nt().upstream(); 1224 m_endOfInsertedContent = mostBackwardCaretPosition(endingSelection() .visibleEnd().deepEquivalent());
1225 } 1225 }
1226 1226
1227 Position lastPositionToSelect; 1227 Position lastPositionToSelect;
1228 if (fragment.hasInterchangeNewlineAtEnd()) { 1228 if (fragment.hasInterchangeNewlineAtEnd()) {
1229 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent(); 1229 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent();
1230 VisiblePosition next = endOfInsertedContent.next(CannotCrossEditingBound ary); 1230 VisiblePosition next = endOfInsertedContent.next(CannotCrossEditingBound ary);
1231 1231
1232 if (selectionEndWasEndOfParagraph || !isEndOfParagraph(endOfInsertedCont ent) || next.isNull()) { 1232 if (selectionEndWasEndOfParagraph || !isEndOfParagraph(endOfInsertedCont ent) || next.isNull()) {
1233 if (!isStartOfParagraph(endOfInsertedContent)) { 1233 if (!isStartOfParagraph(endOfInsertedContent)) {
1234 setEndingSelection(endOfInsertedContent); 1234 setEndingSelection(endOfInsertedContent);
1235 Element* enclosingBlockElement = enclosingBlock(endOfInsertedCon tent.deepEquivalent().anchorNode()); 1235 Element* enclosingBlockElement = enclosingBlock(endOfInsertedCon tent.deepEquivalent().anchorNode());
1236 if (isListItem(enclosingBlockElement)) { 1236 if (isListItem(enclosingBlockElement)) {
1237 RefPtrWillBeRawPtr<HTMLLIElement> newListItem = createListIt emElement(document()); 1237 RefPtrWillBeRawPtr<HTMLLIElement> newListItem = createListIt emElement(document());
1238 insertNodeAfter(newListItem, enclosingBlockElement); 1238 insertNodeAfter(newListItem, enclosingBlockElement);
1239 setEndingSelection(VisiblePosition(firstPositionInNode(newLi stItem.get()))); 1239 setEndingSelection(VisiblePosition(firstPositionInNode(newLi stItem.get())));
1240 } else { 1240 } else {
1241 // Use a default paragraph element (a plain div) for the emp ty paragraph, using the last paragraph 1241 // Use a default paragraph element (a plain div) for the emp ty paragraph, using the last paragraph
1242 // block's style seems to annoy users. 1242 // block's style seems to annoy users.
1243 insertParagraphSeparator(true, !startIsInsideMailBlockquote && highestEnclosingNodeOfType(endOfInsertedContent.deepEquivalent(), 1243 insertParagraphSeparator(true, !startIsInsideMailBlockquote && highestEnclosingNodeOfType(endOfInsertedContent.deepEquivalent(),
1244 isMailHTMLBlockquoteElement, CannotCrossEditingBoundary, insertedNodes.firstNodeInserted()->parentNode())); 1244 isMailHTMLBlockquoteElement, CannotCrossEditingBoundary, insertedNodes.firstNodeInserted()->parentNode()));
1245 } 1245 }
1246 1246
1247 // Select up to the paragraph separator that was added. 1247 // Select up to the paragraph separator that was added.
1248 lastPositionToSelect = endingSelection().visibleStart().deepEqui valent(); 1248 lastPositionToSelect = endingSelection().visibleStart().deepEqui valent();
1249 updateNodesInserted(lastPositionToSelect.anchorNode()); 1249 updateNodesInserted(lastPositionToSelect.anchorNode());
1250 } 1250 }
1251 } else { 1251 } else {
1252 // Select up to the beginning of the next paragraph. 1252 // Select up to the beginning of the next paragraph.
1253 lastPositionToSelect = next.deepEquivalent().downstream(); 1253 lastPositionToSelect = mostForwardCaretPosition(next.deepEquivalent( ));
1254 } 1254 }
1255 } else { 1255 } else {
1256 mergeEndIfNeeded(); 1256 mergeEndIfNeeded();
1257 } 1257 }
1258 1258
1259 if (HTMLQuoteElement* mailBlockquote = toHTMLQuoteElement(enclosingNodeOfTyp e(positionAtStartOfInsertedContent().deepEquivalent(), isMailPasteAsQuotationHTM LBlockQuoteElement))) 1259 if (HTMLQuoteElement* mailBlockquote = toHTMLQuoteElement(enclosingNodeOfTyp e(positionAtStartOfInsertedContent().deepEquivalent(), isMailPasteAsQuotationHTM LBlockQuoteElement)))
1260 removeElementAttribute(mailBlockquote, classAttr); 1260 removeElementAttribute(mailBlockquote, classAttr);
1261 1261
1262 if (shouldPerformSmartReplace()) 1262 if (shouldPerformSmartReplace())
1263 addSpacesForSmartReplace(); 1263 addSpacesForSmartReplace();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1305 static bool isCharacterSmartReplaceExemptConsideringNonBreakingSpace(UChar32 cha racter, bool previousCharacter) 1305 static bool isCharacterSmartReplaceExemptConsideringNonBreakingSpace(UChar32 cha racter, bool previousCharacter)
1306 { 1306 {
1307 return isCharacterSmartReplaceExempt(character == noBreakSpaceCharacter ? ' ' : character, previousCharacter); 1307 return isCharacterSmartReplaceExempt(character == noBreakSpaceCharacter ? ' ' : character, previousCharacter);
1308 } 1308 }
1309 1309
1310 void ReplaceSelectionCommand::addSpacesForSmartReplace() 1310 void ReplaceSelectionCommand::addSpacesForSmartReplace()
1311 { 1311 {
1312 VisiblePosition startOfInsertedContent = positionAtStartOfInsertedContent(); 1312 VisiblePosition startOfInsertedContent = positionAtStartOfInsertedContent();
1313 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent(); 1313 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent();
1314 1314
1315 Position endUpstream = endOfInsertedContent.deepEquivalent().upstream(); 1315 Position endUpstream = mostBackwardCaretPosition(endOfInsertedContent.deepEq uivalent());
1316 Node* endNode = endUpstream.computeNodeBeforePosition(); 1316 Node* endNode = endUpstream.computeNodeBeforePosition();
1317 int endOffset = endNode && endNode->isTextNode() ? toText(endNode)->length() : 0; 1317 int endOffset = endNode && endNode->isTextNode() ? toText(endNode)->length() : 0;
1318 if (endUpstream.isOffsetInAnchor()) { 1318 if (endUpstream.isOffsetInAnchor()) {
1319 endNode = endUpstream.computeContainerNode(); 1319 endNode = endUpstream.computeContainerNode();
1320 endOffset = endUpstream.offsetInContainerNode(); 1320 endOffset = endUpstream.offsetInContainerNode();
1321 } 1321 }
1322 1322
1323 bool needsTrailingSpace = !isEndOfParagraph(endOfInsertedContent) && !isChar acterSmartReplaceExemptConsideringNonBreakingSpace(endOfInsertedContent.characte rAfter(), false); 1323 bool needsTrailingSpace = !isEndOfParagraph(endOfInsertedContent) && !isChar acterSmartReplaceExemptConsideringNonBreakingSpace(endOfInsertedContent.characte rAfter(), false);
1324 if (needsTrailingSpace && endNode) { 1324 if (needsTrailingSpace && endNode) {
1325 bool collapseWhiteSpace = !endNode->layoutObject() || endNode->layoutObj ect()->style()->collapseWhiteSpace(); 1325 bool collapseWhiteSpace = !endNode->layoutObject() || endNode->layoutObj ect()->style()->collapseWhiteSpace();
1326 if (endNode->isTextNode()) { 1326 if (endNode->isTextNode()) {
1327 insertTextIntoNode(toText(endNode), endOffset, collapseWhiteSpace ? nonBreakingSpaceString() : " "); 1327 insertTextIntoNode(toText(endNode), endOffset, collapseWhiteSpace ? nonBreakingSpaceString() : " ");
1328 if (m_endOfInsertedContent.computeContainerNode() == endNode) 1328 if (m_endOfInsertedContent.computeContainerNode() == endNode)
1329 m_endOfInsertedContent = Position(endNode, m_endOfInsertedConten t.offsetInContainerNode() + 1); 1329 m_endOfInsertedContent = Position(endNode, m_endOfInsertedConten t.offsetInContainerNode() + 1);
1330 } else { 1330 } else {
1331 RefPtrWillBeRawPtr<Text> node = document().createEditingTextNode(col lapseWhiteSpace ? nonBreakingSpaceString() : " "); 1331 RefPtrWillBeRawPtr<Text> node = document().createEditingTextNode(col lapseWhiteSpace ? nonBreakingSpaceString() : " ");
1332 insertNodeAfter(node, endNode); 1332 insertNodeAfter(node, endNode);
1333 updateNodesInserted(node.get()); 1333 updateNodesInserted(node.get());
1334 } 1334 }
1335 } 1335 }
1336 1336
1337 document().updateLayout(); 1337 document().updateLayout();
1338 1338
1339 Position startDownstream = startOfInsertedContent.deepEquivalent().downstrea m(); 1339 Position startDownstream = mostForwardCaretPosition(startOfInsertedContent.d eepEquivalent());
1340 Node* startNode = startDownstream.computeNodeAfterPosition(); 1340 Node* startNode = startDownstream.computeNodeAfterPosition();
1341 unsigned startOffset = 0; 1341 unsigned startOffset = 0;
1342 if (startDownstream.isOffsetInAnchor()) { 1342 if (startDownstream.isOffsetInAnchor()) {
1343 startNode = startDownstream.computeContainerNode(); 1343 startNode = startDownstream.computeContainerNode();
1344 startOffset = startDownstream.offsetInContainerNode(); 1344 startOffset = startDownstream.offsetInContainerNode();
1345 } 1345 }
1346 1346
1347 bool needsLeadingSpace = !isStartOfParagraph(startOfInsertedContent) && !isC haracterSmartReplaceExemptConsideringNonBreakingSpace(startOfInsertedContent.pre vious().characterAfter(), true); 1347 bool needsLeadingSpace = !isStartOfParagraph(startOfInsertedContent) && !isC haracterSmartReplaceExemptConsideringNonBreakingSpace(startOfInsertedContent.pre vious().characterAfter(), true);
1348 if (needsLeadingSpace && startNode) { 1348 if (needsLeadingSpace && startNode) {
1349 bool collapseWhiteSpace = !startNode->layoutObject() || startNode->layou tObject()->style()->collapseWhiteSpace(); 1349 bool collapseWhiteSpace = !startNode->layoutObject() || startNode->layou tObject()->style()->collapseWhiteSpace();
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1519 return false; 1519 return false;
1520 1520
1521 // FIXME: Would be nice to handle smart replace in the fast path. 1521 // FIXME: Would be nice to handle smart replace in the fast path.
1522 if (m_smartReplace || fragment.hasInterchangeNewlineAtStart() || fragment.ha sInterchangeNewlineAtEnd()) 1522 if (m_smartReplace || fragment.hasInterchangeNewlineAtStart() || fragment.ha sInterchangeNewlineAtEnd())
1523 return false; 1523 return false;
1524 1524
1525 // e.g. when "bar" is inserted after "foo" in <div><u>foo</u></div>, "bar" s hould not be underlined. 1525 // e.g. when "bar" is inserted after "foo" in <div><u>foo</u></div>, "bar" s hould not be underlined.
1526 if (elementToSplitToAvoidPastingIntoInlineElementsWithStyle(endingSelection( ).start())) 1526 if (elementToSplitToAvoidPastingIntoInlineElementsWithStyle(endingSelection( ).start()))
1527 return false; 1527 return false;
1528 1528
1529 RefPtrWillBeRawPtr<Node> nodeAfterInsertionPos = endingSelection().end().dow nstream().anchorNode(); 1529 RefPtrWillBeRawPtr<Node> nodeAfterInsertionPos = mostForwardCaretPosition(en dingSelection().end()).anchorNode();
1530 Text* textNode = toText(fragment.firstChild()); 1530 Text* textNode = toText(fragment.firstChild());
1531 // Our fragment creation code handles tabs, spaces, and newlines, so we don' t have to worry about those here. 1531 // Our fragment creation code handles tabs, spaces, and newlines, so we don' t have to worry about those here.
1532 1532
1533 Position start = endingSelection().start(); 1533 Position start = endingSelection().start();
1534 Position end = replaceSelectedTextInNode(textNode->data()); 1534 Position end = replaceSelectedTextInNode(textNode->data());
1535 if (end.isNull()) 1535 if (end.isNull())
1536 return false; 1536 return false;
1537 1537
1538 if (nodeAfterInsertionPos && nodeAfterInsertionPos->parentNode() && isHTMLBR Element(*nodeAfterInsertionPos) 1538 if (nodeAfterInsertionPos && nodeAfterInsertionPos->parentNode() && isHTMLBR Element(*nodeAfterInsertionPos)
1539 && shouldRemoveEndBR(toHTMLBRElement(nodeAfterInsertionPos.get()), Visib lePosition(positionBeforeNode(nodeAfterInsertionPos.get())))) 1539 && shouldRemoveEndBR(toHTMLBRElement(nodeAfterInsertionPos.get()), Visib lePosition(positionBeforeNode(nodeAfterInsertionPos.get()))))
1540 removeNodeAndPruneAncestors(nodeAfterInsertionPos.get()); 1540 removeNodeAndPruneAncestors(nodeAfterInsertionPos.get());
1541 1541
1542 VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, en d); 1542 VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, en d);
1543 1543
1544 setEndingSelection(selectionAfterReplace); 1544 setEndingSelection(selectionAfterReplace);
1545 1545
1546 return true; 1546 return true;
1547 } 1547 }
1548 1548
1549 DEFINE_TRACE(ReplaceSelectionCommand) 1549 DEFINE_TRACE(ReplaceSelectionCommand)
1550 { 1550 {
1551 visitor->trace(m_startOfInsertedContent); 1551 visitor->trace(m_startOfInsertedContent);
1552 visitor->trace(m_endOfInsertedContent); 1552 visitor->trace(m_endOfInsertedContent);
1553 visitor->trace(m_insertionStyle); 1553 visitor->trace(m_insertionStyle);
1554 visitor->trace(m_documentFragment); 1554 visitor->trace(m_documentFragment);
1555 CompositeEditCommand::trace(visitor); 1555 CompositeEditCommand::trace(visitor);
1556 } 1556 }
1557 1557
1558 } // namespace blink 1558 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/editing/commands/InsertTextCommand.cpp ('k') | Source/core/editing/commands/TypingCommand.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698