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

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

Issue 2366693005: Mark paragraph-related functions deprecated in VisibleUnits (Closed)
Patch Set: Add output for DCHECK Created 4 years, 2 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 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 VisiblePosition startOfInsertedContent = positionAtStartOfInsertedContent(); 429 VisiblePosition startOfInsertedContent = positionAtStartOfInsertedContent();
430 VisiblePosition prev = previousPositionOf(startOfInsertedContent, CannotCros sEditingBoundary); 430 VisiblePosition prev = previousPositionOf(startOfInsertedContent, CannotCros sEditingBoundary);
431 if (prev.isNull()) 431 if (prev.isNull())
432 return false; 432 return false;
433 433
434 // When we have matching quote levels, its ok to merge more frequently. 434 // When we have matching quote levels, its ok to merge more frequently.
435 // For a successful merge, we still need to make sure that the inserted cont ent starts with the beginning of a paragraph. 435 // For a successful merge, we still need to make sure that the inserted cont ent starts with the beginning of a paragraph.
436 // And we should only merge here if the selection start was inside a mail bl ockquote. This prevents against removing a 436 // And we should only merge here if the selection start was inside a mail bl ockquote. This prevents against removing a
437 // blockquote from newly pasted quoted content that was pasted into an unquo ted position. If that unquoted position happens 437 // blockquote from newly pasted quoted content that was pasted into an unquo ted position. If that unquoted position happens
438 // to be right after another blockquote, we don't want to merge and risk str ipping a valid block (and newline) from the pasted content. 438 // to be right after another blockquote, we don't want to merge and risk str ipping a valid block (and newline) from the pasted content.
439 if (isStartOfParagraph(startOfInsertedContent) && selectionStartWasInsideMai lBlockquote && hasMatchingQuoteLevel(prev, positionAtEndOfInsertedContent())) 439 if (isStartOfParagraphDeprecated(startOfInsertedContent) && selectionStartWa sInsideMailBlockquote && hasMatchingQuoteLevel(prev, positionAtEndOfInsertedCont ent()))
440 return true; 440 return true;
441 441
442 return !selectionStartWasStartOfParagraph 442 return !selectionStartWasStartOfParagraph
443 && !fragmentHasInterchangeNewlineAtStart 443 && !fragmentHasInterchangeNewlineAtStart
444 && isStartOfParagraph(startOfInsertedContent) 444 && isStartOfParagraphDeprecated(startOfInsertedContent)
445 && !isHTMLBRElement(*startOfInsertedContent.deepEquivalent().anchorNode( )) 445 && !isHTMLBRElement(*startOfInsertedContent.deepEquivalent().anchorNode( ))
446 && shouldMerge(startOfInsertedContent, prev); 446 && shouldMerge(startOfInsertedContent, prev);
447 } 447 }
448 448
449 bool ReplaceSelectionCommand::shouldMergeEnd(bool selectionEndWasEndOfParagraph) 449 bool ReplaceSelectionCommand::shouldMergeEnd(bool selectionEndWasEndOfParagraph)
450 { 450 {
451 VisiblePosition endOfInsertedContent(positionAtEndOfInsertedContent()); 451 VisiblePosition endOfInsertedContent(positionAtEndOfInsertedContent());
452 VisiblePosition next = nextPositionOf(endOfInsertedContent, CannotCrossEditi ngBoundary); 452 VisiblePosition next = nextPositionOf(endOfInsertedContent, CannotCrossEditi ngBoundary);
453 if (next.isNull()) 453 if (next.isNull())
454 return false; 454 return false;
455 455
456 return !selectionEndWasEndOfParagraph 456 return !selectionEndWasEndOfParagraph
457 && isEndOfParagraph(endOfInsertedContent) 457 && isEndOfParagraphDeprecated(endOfInsertedContent)
458 && !isHTMLBRElement(*endOfInsertedContent.deepEquivalent().anchorNode()) 458 && !isHTMLBRElement(*endOfInsertedContent.deepEquivalent().anchorNode())
459 && shouldMerge(endOfInsertedContent, next); 459 && shouldMerge(endOfInsertedContent, next);
460 } 460 }
461 461
462 static bool isMailPasteAsQuotationHTMLBlockQuoteElement(const Node* node) 462 static bool isMailPasteAsQuotationHTMLBlockQuoteElement(const Node* node)
463 { 463 {
464 if (!node || !node->isHTMLElement()) 464 if (!node || !node->isHTMLElement())
465 return false; 465 return false;
466 const HTMLElement& element = toHTMLElement(*node); 466 const HTMLElement& element = toHTMLElement(*node);
467 if (!element.hasTagName(blockquoteTag) || element.getAttribute(classAttr) != ApplePasteAsQuotation) 467 if (!element.hasTagName(blockquoteTag) || element.getAttribute(classAttr) != ApplePasteAsQuotation)
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 // Bail to avoid infinite recursion. 928 // Bail to avoid infinite recursion.
929 if (m_movingParagraph) { 929 if (m_movingParagraph) {
930 NOTREACHED(); 930 NOTREACHED();
931 return; 931 return;
932 } 932 }
933 933
934 // Merging two paragraphs will destroy the moved one's block styles. Always move the end of inserted forward 934 // Merging two paragraphs will destroy the moved one's block styles. Always move the end of inserted forward
935 // to preserve the block style of the paragraph already in the document, unl ess the paragraph to move would 935 // to preserve the block style of the paragraph already in the document, unl ess the paragraph to move would
936 // include the what was the start of the selection that was pasted into, so that we preserve that paragraph's 936 // include the what was the start of the selection that was pasted into, so that we preserve that paragraph's
937 // block styles. 937 // block styles.
938 bool mergeForward = !(inSameParagraph(startOfInsertedContent, endOfInsertedC ontent) && !isStartOfParagraph(startOfInsertedContent)); 938 bool mergeForward = !(inSameParagraphDeprecated(startOfInsertedContent, endO fInsertedContent) && !isStartOfParagraphDeprecated(startOfInsertedContent));
939 939
940 VisiblePosition destination = mergeForward ? nextPositionOf(endOfInsertedCon tent) : endOfInsertedContent; 940 VisiblePosition destination = mergeForward ? nextPositionOf(endOfInsertedCon tent) : endOfInsertedContent;
941 VisiblePosition startOfParagraphToMove = mergeForward ? startOfParagraph(end OfInsertedContent) : nextPositionOf(endOfInsertedContent); 941 VisiblePosition startOfParagraphToMove = mergeForward ? startOfParagraphDepr ecated(endOfInsertedContent) : nextPositionOf(endOfInsertedContent);
942 942
943 // Merging forward could result in deleting the destination anchor node. 943 // Merging forward could result in deleting the destination anchor node.
944 // To avoid this, we add a placeholder node before the start of the paragrap h. 944 // To avoid this, we add a placeholder node before the start of the paragrap h.
945 if (endOfParagraph(startOfParagraphToMove).deepEquivalent() == destination.d eepEquivalent()) { 945 if (endOfParagraphDeprecated(startOfParagraphToMove).deepEquivalent() == des tination.deepEquivalent()) {
946 HTMLBRElement* placeholder = HTMLBRElement::create(document()); 946 HTMLBRElement* placeholder = HTMLBRElement::create(document());
947 insertNodeBefore(placeholder, startOfParagraphToMove.deepEquivalent().an chorNode(), editingState); 947 insertNodeBefore(placeholder, startOfParagraphToMove.deepEquivalent().an chorNode(), editingState);
948 if (editingState->isAborted()) 948 if (editingState->isAborted())
949 return; 949 return;
950 destination = VisiblePosition::beforeNode(placeholder); 950 destination = VisiblePosition::beforeNode(placeholder);
951 } 951 }
952 952
953 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToMove) , destination, editingState); 953 moveParagraph(startOfParagraphToMove, endOfParagraphDeprecated(startOfParagr aphToMove), destination, editingState);
954 if (editingState->isAborted()) 954 if (editingState->isAborted())
955 return; 955 return;
956 956
957 // Merging forward will remove m_endOfInsertedContent from the document. 957 // Merging forward will remove m_endOfInsertedContent from the document.
958 if (mergeForward) { 958 if (mergeForward) {
959 if (m_startOfInsertedContent.isOrphan()) 959 if (m_startOfInsertedContent.isOrphan())
960 m_startOfInsertedContent = endingSelection().visibleStart().deepEqui valent(); 960 m_startOfInsertedContent = endingSelection().visibleStart().deepEqui valent();
961 m_endOfInsertedContent = endingSelection().visibleEnd().deepEquivalent() ; 961 m_endOfInsertedContent = endingSelection().visibleEnd().deepEquivalent() ;
962 // If we merged text nodes, m_endOfInsertedContent could be null. If 962 // If we merged text nodes, m_endOfInsertedContent could be null. If
963 // this is the case, we use m_startOfInsertedContent. 963 // this is the case, we use m_startOfInsertedContent.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1041 m_matchStyle = false; 1041 m_matchStyle = false;
1042 1042
1043 if (m_matchStyle) { 1043 if (m_matchStyle) {
1044 m_insertionStyle = EditingStyle::create(selection.start()); 1044 m_insertionStyle = EditingStyle::create(selection.start());
1045 m_insertionStyle->mergeTypingStyle(&document()); 1045 m_insertionStyle->mergeTypingStyle(&document());
1046 } 1046 }
1047 1047
1048 const VisiblePosition visibleStart = selection.visibleStart(); 1048 const VisiblePosition visibleStart = selection.visibleStart();
1049 const VisiblePosition visibleEnd = selection.visibleEnd(); 1049 const VisiblePosition visibleEnd = selection.visibleEnd();
1050 1050
1051 const bool selectionEndWasEndOfParagraph = isEndOfParagraph(visibleEnd); 1051 const bool selectionEndWasEndOfParagraph = isEndOfParagraphDeprecated(visibl eEnd);
1052 const bool selectionStartWasStartOfParagraph = isStartOfParagraph(visibleSta rt); 1052 const bool selectionStartWasStartOfParagraph = isStartOfParagraphDeprecated( visibleStart);
1053 1053
1054 Element* enclosingBlockOfVisibleStart = enclosingBlock(visibleStart.deepEqui valent().anchorNode()); 1054 Element* enclosingBlockOfVisibleStart = enclosingBlock(visibleStart.deepEqui valent().anchorNode());
1055 1055
1056 const bool startIsInsideMailBlockquote = enclosingNodeOfType(selection.start (), isMailHTMLBlockquoteElement, CanCrossEditingBoundary); 1056 const bool startIsInsideMailBlockquote = enclosingNodeOfType(selection.start (), isMailHTMLBlockquoteElement, CanCrossEditingBoundary);
1057 const bool selectionIsPlainText = !selection.isContentRichlyEditable(); 1057 const bool selectionIsPlainText = !selection.isContentRichlyEditable();
1058 Element* currentRoot = selection.rootEditableElement(); 1058 Element* currentRoot = selection.rootEditableElement();
1059 1059
1060 if ((selectionStartWasStartOfParagraph && selectionEndWasEndOfParagraph && ! startIsInsideMailBlockquote) 1060 if ((selectionStartWasStartOfParagraph && selectionEndWasEndOfParagraph && ! startIsInsideMailBlockquote)
1061 || enclosingBlockOfVisibleStart == currentRoot 1061 || enclosingBlockOfVisibleStart == currentRoot
1062 || isListItem(enclosingBlockOfVisibleStart) 1062 || isListItem(enclosingBlockOfVisibleStart)
1063 || selectionIsPlainText) { 1063 || selectionIsPlainText) {
1064 m_preventNesting = false; 1064 m_preventNesting = false;
1065 } 1065 }
1066 1066
1067 if (selection.isRange()) { 1067 if (selection.isRange()) {
1068 // When the end of the selection being pasted into is at the end of a pa ragraph, and that selection 1068 // When the end of the selection being pasted into is at the end of a pa ragraph, and that selection
1069 // spans multiple blocks, not merging may leave an empty line. 1069 // spans multiple blocks, not merging may leave an empty line.
1070 // When the start of the selection being pasted into is at the start of a block, not merging 1070 // When the start of the selection being pasted into is at the start of a block, not merging
1071 // will leave hanging block(s). 1071 // will leave hanging block(s).
1072 // Merge blocks if the start of the selection was in a Mail blockquote, since we handle 1072 // Merge blocks if the start of the selection was in a Mail blockquote, since we handle
1073 // that case specially to prevent nesting. 1073 // that case specially to prevent nesting.
1074 bool mergeBlocksAfterDelete = startIsInsideMailBlockquote || isEndOfPara graph(visibleEnd) || isStartOfBlock(visibleStart); 1074 bool mergeBlocksAfterDelete = startIsInsideMailBlockquote || isEndOfPara graphDeprecated(visibleEnd) || isStartOfBlock(visibleStart);
1075 // FIXME: We should only expand to include fully selected special elemen ts if we are copying a 1075 // FIXME: We should only expand to include fully selected special elemen ts if we are copying a
1076 // selection and pasting it on top of itself. 1076 // selection and pasting it on top of itself.
1077 deleteSelection(editingState, false, mergeBlocksAfterDelete, false); 1077 deleteSelection(editingState, false, mergeBlocksAfterDelete, false);
1078 if (editingState->isAborted()) 1078 if (editingState->isAborted())
1079 return; 1079 return;
1080 if (fragment.hasInterchangeNewlineAtStart()) { 1080 if (fragment.hasInterchangeNewlineAtStart()) {
1081 VisiblePosition startAfterDelete = endingSelection().visibleStart(); 1081 VisiblePosition startAfterDelete = endingSelection().visibleStart();
1082 if (isEndOfParagraph(startAfterDelete) && !isStartOfParagraph(startA fterDelete) && !isEndOfEditableOrNonEditableContent(startAfterDelete)) 1082 if (isEndOfParagraphDeprecated(startAfterDelete) && !isStartOfParagr aphDeprecated(startAfterDelete) && !isEndOfEditableOrNonEditableContent(startAft erDelete))
1083 setEndingSelection(nextPositionOf(startAfterDelete)); 1083 setEndingSelection(nextPositionOf(startAfterDelete));
1084 else 1084 else
1085 insertParagraphSeparator(editingState); 1085 insertParagraphSeparator(editingState);
1086 if (editingState->isAborted()) 1086 if (editingState->isAborted())
1087 return; 1087 return;
1088 } 1088 }
1089 } else { 1089 } else {
1090 DCHECK(selection.isCaret()); 1090 DCHECK(selection.isCaret());
1091 if (fragment.hasInterchangeNewlineAtStart()) { 1091 if (fragment.hasInterchangeNewlineAtStart()) {
1092 const VisiblePosition next = nextPositionOf(visibleStart, CannotCros sEditingBoundary); 1092 const VisiblePosition next = nextPositionOf(visibleStart, CannotCros sEditingBoundary);
1093 if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleSta rt) && next.isNotNull()) 1093 if (isEndOfParagraphDeprecated(visibleStart) && !isStartOfParagraphD eprecated(visibleStart) && next.isNotNull())
1094 setEndingSelection(next); 1094 setEndingSelection(next);
1095 else 1095 else
1096 insertParagraphSeparator(editingState); 1096 insertParagraphSeparator(editingState);
1097 if (editingState->isAborted()) 1097 if (editingState->isAborted())
1098 return; 1098 return;
1099 } 1099 }
1100 // We split the current paragraph in two to avoid nesting the blocks fro m the fragment inside the current block. 1100 // We split the current paragraph in two to avoid nesting the blocks fro m the fragment inside the current block.
1101 // For example paste <div>foo</div><div>bar</div><div>baz</div> into <di v>x^x</div>, where ^ is the caret. 1101 // For example paste <div>foo</div><div>bar</div><div>baz</div> into <di v>x^x</div>, where ^ is the caret.
1102 // As long as the div styles are the same, visually you'd expect: <div> xbar</div><div>bar</div><div>bazx</div>, 1102 // As long as the div styles are the same, visually you'd expect: <div> xbar</div><div>bar</div><div>bazx</div>,
1103 // not <div>xbar<div>bar</div><div>bazx</div></div>. 1103 // not <div>xbar<div>bar</div><div>bazx</div></div>.
1104 // Don't do this if the selection started in a Mail blockquote. 1104 // Don't do this if the selection started in a Mail blockquote.
1105 if (m_preventNesting && !startIsInsideMailBlockquote && !isEndOfParagrap h(endingSelection().visibleStart()) && !isStartOfParagraph(endingSelection().vis ibleStart())) { 1105 if (m_preventNesting && !startIsInsideMailBlockquote && !isEndOfParagrap hDeprecated(endingSelection().visibleStart()) && !isStartOfParagraphDeprecated(e ndingSelection().visibleStart())) {
1106 insertParagraphSeparator(editingState); 1106 insertParagraphSeparator(editingState);
1107 if (editingState->isAborted()) 1107 if (editingState->isAborted())
1108 return; 1108 return;
1109 setEndingSelection(previousPositionOf(endingSelection().visibleStart ())); 1109 setEndingSelection(previousPositionOf(endingSelection().visibleStart ()));
1110 } 1110 }
1111 } 1111 }
1112 1112
1113 Position insertionPos = endingSelection().start(); 1113 Position insertionPos = endingSelection().start();
1114 // We don't want any of the pasted content to end up nested in a Mail blockq uote, so first break 1114 // We don't want any of the pasted content to end up nested in a Mail blockq uote, so first break
1115 // out of any surrounding Mail blockquotes. Unless we're inserting in a tabl e, in which case 1115 // out of any surrounding Mail blockquotes. Unless we're inserting in a tabl e, in which case
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1277 1277
1278 // Scripts specified in javascript protocol may remove |enclosingBlockOfInse rtionPos| 1278 // Scripts specified in javascript protocol may remove |enclosingBlockOfInse rtionPos|
1279 // during insertion, e.g. <iframe src="javascript:..."> 1279 // during insertion, e.g. <iframe src="javascript:...">
1280 if (enclosingBlockOfInsertionPos && !enclosingBlockOfInsertionPos->isConnect ed()) 1280 if (enclosingBlockOfInsertionPos && !enclosingBlockOfInsertionPos->isConnect ed())
1281 enclosingBlockOfInsertionPos = nullptr; 1281 enclosingBlockOfInsertionPos = nullptr;
1282 1282
1283 VisiblePosition startOfInsertedContent = createVisiblePositionDeprecated(fir stPositionInOrBeforeNode(insertedNodes.firstNodeInserted())); 1283 VisiblePosition startOfInsertedContent = createVisiblePositionDeprecated(fir stPositionInOrBeforeNode(insertedNodes.firstNodeInserted()));
1284 1284
1285 // We inserted before the enclosingBlockOfInsertionPos to prevent nesting, a nd the content before the enclosingBlockOfInsertionPos wasn't in its own block a nd 1285 // We inserted before the enclosingBlockOfInsertionPos to prevent nesting, a nd the content before the enclosingBlockOfInsertionPos wasn't in its own block a nd
1286 // didn't have a br after it, so the inserted content ended up in the same p aragraph. 1286 // didn't have a br after it, so the inserted content ended up in the same p aragraph.
1287 if (!startOfInsertedContent.isNull() && enclosingBlockOfInsertionPos && inse rtionPos.anchorNode() == enclosingBlockOfInsertionPos->parentNode() && (unsigned )insertionPos.computeEditingOffset() < enclosingBlockOfInsertionPos->nodeIndex() && !isStartOfParagraph(startOfInsertedContent)) { 1287 if (!startOfInsertedContent.isNull() && enclosingBlockOfInsertionPos && inse rtionPos.anchorNode() == enclosingBlockOfInsertionPos->parentNode() && (unsigned )insertionPos.computeEditingOffset() < enclosingBlockOfInsertionPos->nodeIndex() && !isStartOfParagraphDeprecated(startOfInsertedContent)) {
1288 insertNodeAt(HTMLBRElement::create(document()), startOfInsertedContent.d eepEquivalent(), editingState); 1288 insertNodeAt(HTMLBRElement::create(document()), startOfInsertedContent.d eepEquivalent(), editingState);
1289 if (editingState->isAborted()) 1289 if (editingState->isAborted())
1290 return; 1290 return;
1291 } 1291 }
1292 1292
1293 if (endBR && (plainTextFragment || (shouldRemoveEndBR(endBR, originalVisPosB eforeEndBR) && !(fragment.hasInterchangeNewlineAtEnd() && selectionIsPlainText)) )) { 1293 if (endBR && (plainTextFragment || (shouldRemoveEndBR(endBR, originalVisPosB eforeEndBR) && !(fragment.hasInterchangeNewlineAtEnd() && selectionIsPlainText)) )) {
1294 ContainerNode* parent = endBR->parentNode(); 1294 ContainerNode* parent = endBR->parentNode();
1295 insertedNodes.willRemoveNode(*endBR); 1295 insertedNodes.willRemoveNode(*endBR);
1296 removeNode(endBR, editingState); 1296 removeNode(endBR, editingState);
1297 if (editingState->isAborted()) 1297 if (editingState->isAborted())
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1340 } 1340 }
1341 1341
1342 // Merging the the first paragraph of inserted content with the content that came 1342 // Merging the the first paragraph of inserted content with the content that came
1343 // before the selection that was pasted into would also move content aft er 1343 // before the selection that was pasted into would also move content aft er
1344 // the selection that was pasted into if: only one paragraph was being p asted, 1344 // the selection that was pasted into if: only one paragraph was being p asted,
1345 // and it was not wrapped in a block, the selection that was pasted into ended 1345 // and it was not wrapped in a block, the selection that was pasted into ended
1346 // at the end of a block and the next paragraph didn't start at the star t of a block. 1346 // at the end of a block and the next paragraph didn't start at the star t of a block.
1347 // Insert a line break just after the inserted content to separate it fr om what 1347 // Insert a line break just after the inserted content to separate it fr om what
1348 // comes after and prevent that from happening. 1348 // comes after and prevent that from happening.
1349 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent(); 1349 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent();
1350 if (startOfParagraph(endOfInsertedContent).deepEquivalent() == startOfPa ragraphToMove.deepEquivalent()) { 1350 if (startOfParagraphDeprecated(endOfInsertedContent).deepEquivalent() == startOfParagraphToMove.deepEquivalent()) {
1351 insertNodeAt(HTMLBRElement::create(document()), endOfInsertedContent .deepEquivalent(), editingState); 1351 insertNodeAt(HTMLBRElement::create(document()), endOfInsertedContent .deepEquivalent(), editingState);
1352 if (editingState->isAborted()) 1352 if (editingState->isAborted())
1353 return; 1353 return;
1354 // Mutation events (bug 22634) triggered by inserting the <br> might have removed the content we're about to move 1354 // Mutation events (bug 22634) triggered by inserting the <br> might have removed the content we're about to move
1355 if (!startOfParagraphToMove.deepEquivalent().isConnected()) 1355 if (!startOfParagraphToMove.deepEquivalent().isConnected())
1356 return; 1356 return;
1357 } 1357 }
1358 1358
1359 // FIXME: Maintain positions for the start and end of inserted content i nstead of keeping nodes. The nodes are 1359 // FIXME: Maintain positions for the start and end of inserted content i nstead of keeping nodes. The nodes are
1360 // only ever used to create positions where inserted content starts/ends . 1360 // only ever used to create positions where inserted content starts/ends .
1361 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToM ove), destination, editingState); 1361 moveParagraph(startOfParagraphToMove, endOfParagraphDeprecated(startOfPa ragraphToMove), destination, editingState);
1362 if (editingState->isAborted()) 1362 if (editingState->isAborted())
1363 return; 1363 return;
1364 m_startOfInsertedContent = mostForwardCaretPosition(endingSelection().vi sibleStart().deepEquivalent()); 1364 m_startOfInsertedContent = mostForwardCaretPosition(endingSelection().vi sibleStart().deepEquivalent());
1365 if (m_endOfInsertedContent.isOrphan()) 1365 if (m_endOfInsertedContent.isOrphan())
1366 m_endOfInsertedContent = mostBackwardCaretPosition(endingSelection() .visibleEnd().deepEquivalent()); 1366 m_endOfInsertedContent = mostBackwardCaretPosition(endingSelection() .visibleEnd().deepEquivalent());
1367 } 1367 }
1368 1368
1369 Position lastPositionToSelect; 1369 Position lastPositionToSelect;
1370 if (fragment.hasInterchangeNewlineAtEnd()) { 1370 if (fragment.hasInterchangeNewlineAtEnd()) {
1371 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent(); 1371 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent();
1372 VisiblePosition next = nextPositionOf(endOfInsertedContent, CannotCrossE ditingBoundary); 1372 VisiblePosition next = nextPositionOf(endOfInsertedContent, CannotCrossE ditingBoundary);
1373 1373
1374 if (selectionEndWasEndOfParagraph || !isEndOfParagraph(endOfInsertedCont ent) || next.isNull()) { 1374 if (selectionEndWasEndOfParagraph || !isEndOfParagraphDeprecated(endOfIn sertedContent) || next.isNull()) {
1375 if (HTMLTextFormControlElement* textControl = enclosingTextFormContr ol(currentRoot)) { 1375 if (HTMLTextFormControlElement* textControl = enclosingTextFormContr ol(currentRoot)) {
1376 if (!insertedNodes.lastLeafInserted()->nextSibling()) { 1376 if (!insertedNodes.lastLeafInserted()->nextSibling()) {
1377 insertNodeAfter(textControl->createPlaceholderBreakElement() , insertedNodes.lastLeafInserted(), editingState); 1377 insertNodeAfter(textControl->createPlaceholderBreakElement() , insertedNodes.lastLeafInserted(), editingState);
1378 if (editingState->isAborted()) 1378 if (editingState->isAborted())
1379 return; 1379 return;
1380 } 1380 }
1381 setEndingSelection(VisiblePosition::afterNode(insertedNodes.last LeafInserted())); 1381 setEndingSelection(VisiblePosition::afterNode(insertedNodes.last LeafInserted()));
1382 // Select up to the paragraph separator that was added. 1382 // Select up to the paragraph separator that was added.
1383 lastPositionToSelect = endingSelection().visibleStart().deepEqui valent(); 1383 lastPositionToSelect = endingSelection().visibleStart().deepEqui valent();
1384 } else if (!isStartOfParagraph(endOfInsertedContent)) { 1384 } else if (!isStartOfParagraphDeprecated(endOfInsertedContent)) {
1385 setEndingSelection(endOfInsertedContent); 1385 setEndingSelection(endOfInsertedContent);
1386 Element* enclosingBlockElement = enclosingBlock(endOfInsertedCon tent.deepEquivalent().anchorNode()); 1386 Element* enclosingBlockElement = enclosingBlock(endOfInsertedCon tent.deepEquivalent().anchorNode());
1387 if (isListItem(enclosingBlockElement)) { 1387 if (isListItem(enclosingBlockElement)) {
1388 HTMLLIElement* newListItem = HTMLLIElement::create(document( )); 1388 HTMLLIElement* newListItem = HTMLLIElement::create(document( ));
1389 insertNodeAfter(newListItem, enclosingBlockElement, editingS tate); 1389 insertNodeAfter(newListItem, enclosingBlockElement, editingS tate);
1390 if (editingState->isAborted()) 1390 if (editingState->isAborted())
1391 return; 1391 return;
1392 setEndingSelection(VisiblePosition::firstPositionInNode(newL istItem)); 1392 setEndingSelection(VisiblePosition::firstPositionInNode(newL istItem));
1393 } else { 1393 } else {
1394 // Use a default paragraph element (a plain div) for the emp ty paragraph, using the last paragraph 1394 // Use a default paragraph element (a plain div) for the emp ty paragraph, using the last paragraph
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 if (!endBR || !endBR->isConnected()) 1435 if (!endBR || !endBR->isConnected())
1436 return false; 1436 return false;
1437 1437
1438 VisiblePosition visiblePos = VisiblePosition::beforeNode(endBR); 1438 VisiblePosition visiblePos = VisiblePosition::beforeNode(endBR);
1439 1439
1440 // Don't remove the br if nothing was inserted. 1440 // Don't remove the br if nothing was inserted.
1441 if (previousPositionOf(visiblePos).deepEquivalent() == originalVisPosBeforeE ndBR.deepEquivalent()) 1441 if (previousPositionOf(visiblePos).deepEquivalent() == originalVisPosBeforeE ndBR.deepEquivalent())
1442 return false; 1442 return false;
1443 1443
1444 // Remove the br if it is collapsed away and so is unnecessary. 1444 // Remove the br if it is collapsed away and so is unnecessary.
1445 if (!document().inNoQuirksMode() && isEndOfBlock(visiblePos) && !isStartOfPa ragraph(visiblePos)) 1445 if (!document().inNoQuirksMode() && isEndOfBlock(visiblePos) && !isStartOfPa ragraphDeprecated(visiblePos))
1446 return true; 1446 return true;
1447 1447
1448 // A br that was originally holding a line open should be displaced by inser ted content or turned into a line break. 1448 // A br that was originally holding a line open should be displaced by inser ted content or turned into a line break.
1449 // A br that was originally acting as a line break should still be acting as a line break, not as a placeholder. 1449 // A br that was originally acting as a line break should still be acting as a line break, not as a placeholder.
1450 return isStartOfParagraph(visiblePos) && isEndOfParagraph(visiblePos); 1450 return isStartOfParagraphDeprecated(visiblePos) && isEndOfParagraphDeprecate d(visiblePos);
1451 } 1451 }
1452 1452
1453 bool ReplaceSelectionCommand::shouldPerformSmartReplace() const 1453 bool ReplaceSelectionCommand::shouldPerformSmartReplace() const
1454 { 1454 {
1455 if (!m_smartReplace) 1455 if (!m_smartReplace)
1456 return false; 1456 return false;
1457 1457
1458 HTMLTextFormControlElement* textControl = enclosingTextFormControl(positionA tStartOfInsertedContent().deepEquivalent()); 1458 HTMLTextFormControlElement* textControl = enclosingTextFormControl(positionA tStartOfInsertedContent().deepEquivalent());
1459 if (isHTMLInputElement(textControl) && toHTMLInputElement(textControl)->type () == InputTypeNames::password) 1459 if (isHTMLInputElement(textControl) && toHTMLInputElement(textControl)->type () == InputTypeNames::password)
1460 return false; // Disable smart replace for password fields. 1460 return false; // Disable smart replace for password fields.
(...skipping 12 matching lines...) Expand all
1473 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent(); 1473 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent();
1474 1474
1475 Position endUpstream = mostBackwardCaretPosition(endOfInsertedContent.deepEq uivalent()); 1475 Position endUpstream = mostBackwardCaretPosition(endOfInsertedContent.deepEq uivalent());
1476 Node* endNode = endUpstream.computeNodeBeforePosition(); 1476 Node* endNode = endUpstream.computeNodeBeforePosition();
1477 int endOffset = endNode && endNode->isTextNode() ? toText(endNode)->length() : 0; 1477 int endOffset = endNode && endNode->isTextNode() ? toText(endNode)->length() : 0;
1478 if (endUpstream.isOffsetInAnchor()) { 1478 if (endUpstream.isOffsetInAnchor()) {
1479 endNode = endUpstream.computeContainerNode(); 1479 endNode = endUpstream.computeContainerNode();
1480 endOffset = endUpstream.offsetInContainerNode(); 1480 endOffset = endUpstream.offsetInContainerNode();
1481 } 1481 }
1482 1482
1483 bool needsTrailingSpace = !isEndOfParagraph(endOfInsertedContent) && !isChar acterSmartReplaceExemptConsideringNonBreakingSpace(characterAfter(endOfInsertedC ontent), false); 1483 bool needsTrailingSpace = !isEndOfParagraphDeprecated(endOfInsertedContent) && !isCharacterSmartReplaceExemptConsideringNonBreakingSpace(characterAfter(endO fInsertedContent), false);
1484 if (needsTrailingSpace && endNode) { 1484 if (needsTrailingSpace && endNode) {
1485 bool collapseWhiteSpace = !endNode->layoutObject() || endNode->layoutObj ect()->style()->collapseWhiteSpace(); 1485 bool collapseWhiteSpace = !endNode->layoutObject() || endNode->layoutObj ect()->style()->collapseWhiteSpace();
1486 if (endNode->isTextNode()) { 1486 if (endNode->isTextNode()) {
1487 insertTextIntoNode(toText(endNode), endOffset, collapseWhiteSpace ? nonBreakingSpaceString() : " "); 1487 insertTextIntoNode(toText(endNode), endOffset, collapseWhiteSpace ? nonBreakingSpaceString() : " ");
1488 if (m_endOfInsertedContent.computeContainerNode() == endNode) 1488 if (m_endOfInsertedContent.computeContainerNode() == endNode)
1489 m_endOfInsertedContent = Position(endNode, m_endOfInsertedConten t.offsetInContainerNode() + 1); 1489 m_endOfInsertedContent = Position(endNode, m_endOfInsertedConten t.offsetInContainerNode() + 1);
1490 } else { 1490 } else {
1491 Text* node = document().createEditingTextNode(collapseWhiteSpace ? n onBreakingSpaceString() : " "); 1491 Text* node = document().createEditingTextNode(collapseWhiteSpace ? n onBreakingSpaceString() : " ");
1492 insertNodeAfter(node, endNode, editingState); 1492 insertNodeAfter(node, endNode, editingState);
1493 if (editingState->isAborted()) 1493 if (editingState->isAborted())
1494 return; 1494 return;
1495 updateNodesInserted(node); 1495 updateNodesInserted(node);
1496 } 1496 }
1497 } 1497 }
1498 1498
1499 document().updateStyleAndLayout(); 1499 document().updateStyleAndLayout();
1500 1500
1501 Position startDownstream = mostForwardCaretPosition(startOfInsertedContent.d eepEquivalent()); 1501 Position startDownstream = mostForwardCaretPosition(startOfInsertedContent.d eepEquivalent());
1502 Node* startNode = startDownstream.computeNodeAfterPosition(); 1502 Node* startNode = startDownstream.computeNodeAfterPosition();
1503 unsigned startOffset = 0; 1503 unsigned startOffset = 0;
1504 if (startDownstream.isOffsetInAnchor()) { 1504 if (startDownstream.isOffsetInAnchor()) {
1505 startNode = startDownstream.computeContainerNode(); 1505 startNode = startDownstream.computeContainerNode();
1506 startOffset = startDownstream.offsetInContainerNode(); 1506 startOffset = startDownstream.offsetInContainerNode();
1507 } 1507 }
1508 1508
1509 bool needsLeadingSpace = !isStartOfParagraph(startOfInsertedContent) && !isC haracterSmartReplaceExemptConsideringNonBreakingSpace(characterBefore(startOfIns ertedContent), true); 1509 bool needsLeadingSpace = !isStartOfParagraphDeprecated(startOfInsertedConten t) && !isCharacterSmartReplaceExemptConsideringNonBreakingSpace(characterBefore( startOfInsertedContent), true);
1510 if (needsLeadingSpace && startNode) { 1510 if (needsLeadingSpace && startNode) {
1511 bool collapseWhiteSpace = !startNode->layoutObject() || startNode->layou tObject()->style()->collapseWhiteSpace(); 1511 bool collapseWhiteSpace = !startNode->layoutObject() || startNode->layou tObject()->style()->collapseWhiteSpace();
1512 if (startNode->isTextNode()) { 1512 if (startNode->isTextNode()) {
1513 insertTextIntoNode(toText(startNode), startOffset, collapseWhiteSpac e ? nonBreakingSpaceString() : " "); 1513 insertTextIntoNode(toText(startNode), startOffset, collapseWhiteSpac e ? nonBreakingSpaceString() : " ");
1514 if (m_endOfInsertedContent.computeContainerNode() == startNode && m_ endOfInsertedContent.offsetInContainerNode()) 1514 if (m_endOfInsertedContent.computeContainerNode() == startNode && m_ endOfInsertedContent.offsetInContainerNode())
1515 m_endOfInsertedContent = Position(startNode, m_endOfInsertedCont ent.offsetInContainerNode() + 1); 1515 m_endOfInsertedContent = Position(startNode, m_endOfInsertedCont ent.offsetInContainerNode() + 1);
1516 } else { 1516 } else {
1517 Text* node = document().createEditingTextNode(collapseWhiteSpace ? n onBreakingSpaceString() : " "); 1517 Text* node = document().createEditingTextNode(collapseWhiteSpace ? n onBreakingSpaceString() : " ");
1518 // Don't updateNodesInserted. Doing so would set m_endOfInsertedCont ent to be the node containing the leading space, 1518 // Don't updateNodesInserted. Doing so would set m_endOfInsertedCont ent to be the node containing the leading space,
1519 // but m_endOfInsertedContent is supposed to mark the end of pasted content. 1519 // but m_endOfInsertedContent is supposed to mark the end of pasted content.
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1644 return m_inputType; 1644 return m_inputType;
1645 } 1645 }
1646 1646
1647 // If the user is inserting a list into an existing list, instead of nesting the list, 1647 // If the user is inserting a list into an existing list, instead of nesting the list,
1648 // we put the list items into the existing list. 1648 // we put the list items into the existing list.
1649 Node* ReplaceSelectionCommand::insertAsListItems(HTMLElement* listElement, Eleme nt* insertionBlock, const Position& insertPos, InsertedNodes& insertedNodes, Edi tingState* editingState) 1649 Node* ReplaceSelectionCommand::insertAsListItems(HTMLElement* listElement, Eleme nt* insertionBlock, const Position& insertPos, InsertedNodes& insertedNodes, Edi tingState* editingState)
1650 { 1650 {
1651 while (listElement->hasOneChild() && isHTMLListElement(listElement->firstChi ld())) 1651 while (listElement->hasOneChild() && isHTMLListElement(listElement->firstChi ld()))
1652 listElement = toHTMLElement(listElement->firstChild()); 1652 listElement = toHTMLElement(listElement->firstChild());
1653 1653
1654 bool isStart = isStartOfParagraph(createVisiblePositionDeprecated(insertPos) ); 1654 bool isStart = isStartOfParagraphDeprecated(createVisiblePositionDeprecated( insertPos));
1655 bool isEnd = isEndOfParagraph(createVisiblePositionDeprecated(insertPos)); 1655 bool isEnd = isEndOfParagraphDeprecated(createVisiblePositionDeprecated(inse rtPos));
1656 bool isMiddle = !isStart && !isEnd; 1656 bool isMiddle = !isStart && !isEnd;
1657 Node* lastNode = insertionBlock; 1657 Node* lastNode = insertionBlock;
1658 1658
1659 // If we're in the middle of a list item, we should split it into two separa te 1659 // If we're in the middle of a list item, we should split it into two separa te
1660 // list items and insert these nodes between them. 1660 // list items and insert these nodes between them.
1661 if (isMiddle) { 1661 if (isMiddle) {
1662 int textNodeOffset = insertPos.offsetInContainerNode(); 1662 int textNodeOffset = insertPos.offsetInContainerNode();
1663 if (insertPos.anchorNode()->isTextNode() && textNodeOffset > 0) 1663 if (insertPos.anchorNode()->isTextNode() && textNodeOffset > 0)
1664 splitTextNode(toText(insertPos.anchorNode()), textNodeOffset); 1664 splitTextNode(toText(insertPos.anchorNode()), textNodeOffset);
1665 splitTreeToNode(insertPos.anchorNode(), lastNode, true); 1665 splitTreeToNode(insertPos.anchorNode(), lastNode, true);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1758 visitor->trace(m_startOfInsertedContent); 1758 visitor->trace(m_startOfInsertedContent);
1759 visitor->trace(m_endOfInsertedContent); 1759 visitor->trace(m_endOfInsertedContent);
1760 visitor->trace(m_insertionStyle); 1760 visitor->trace(m_insertionStyle);
1761 visitor->trace(m_documentFragment); 1761 visitor->trace(m_documentFragment);
1762 visitor->trace(m_startOfInsertedRange); 1762 visitor->trace(m_startOfInsertedRange);
1763 visitor->trace(m_endOfInsertedRange); 1763 visitor->trace(m_endOfInsertedRange);
1764 CompositeEditCommand::trace(visitor); 1764 CompositeEditCommand::trace(visitor);
1765 } 1765 }
1766 1766
1767 } // namespace blink 1767 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698