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

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

Issue 2410813002: Prune most of the deprecated functions from CompositeEditCommand (Closed)
Patch Set: 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 838 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 upstream--; 849 upstream--;
850 850
851 int downstream = endOffset; 851 int downstream = endOffset;
852 while ((unsigned)downstream < text.length() && isWhitespace(text[downstream])) 852 while ((unsigned)downstream < text.length() && isWhitespace(text[downstream]))
853 downstream++; 853 downstream++;
854 854
855 int length = downstream - upstream; 855 int length = downstream - upstream;
856 if (!length) 856 if (!length)
857 return; 857 return;
858 858
859 document().updateStyleAndLayoutIgnorePendingStylesheets();
859 VisiblePosition visibleUpstreamPos = 860 VisiblePosition visibleUpstreamPos =
yosin_UTC9 2016/10/12 02:12:06 BTW, should we replace |VisiblePosition| to |const
Xiaocheng 2016/10/12 02:15:54 Do you mean a global s/VisiblePosition/const Visib
860 createVisiblePositionDeprecated(Position(textNode, upstream)); 861 createVisiblePosition(Position(textNode, upstream));
861 VisiblePosition visibleDownstreamPos = 862 VisiblePosition visibleDownstreamPos =
862 createVisiblePositionDeprecated(Position(textNode, downstream)); 863 createVisiblePosition(Position(textNode, downstream));
863 864
864 String string = text.substring(upstream, length); 865 String string = text.substring(upstream, length);
865 // FIXME: Because of the problem mentioned at the top of this function, we 866 // FIXME: Because of the problem mentioned at the top of this function, we
866 // must also use nbsps at the start/end of the string because this function 867 // must also use nbsps at the start/end of the string because this function
867 // doesn't get all surrounding whitespace, just the whitespace in the 868 // doesn't get all surrounding whitespace, just the whitespace in the
868 // current text node. However, if the next sibling node is a text node 869 // current text node. However, if the next sibling node is a text node
869 // (not empty, see http://crbug.com/632300), we should use a plain space. 870 // (not empty, see http://crbug.com/632300), we should use a plain space.
870 // See http://crbug.com/310149 871 // See http://crbug.com/310149
871 const bool nextSiblingIsTextNode = 872 const bool nextSiblingIsTextNode =
872 textNode->nextSibling() && textNode->nextSibling()->isTextNode() && 873 textNode->nextSibling() && textNode->nextSibling()->isTextNode() &&
873 toText(textNode->nextSibling())->data().length(); 874 toText(textNode->nextSibling())->data().length();
874 const bool shouldEmitNBSPbeforeEnd = 875 const bool shouldEmitNBSPbeforeEnd =
875 (isEndOfParagraphDeprecated(visibleDownstreamPos) || 876 (isEndOfParagraph(visibleDownstreamPos) ||
876 (unsigned)downstream == text.length()) && 877 (unsigned)downstream == text.length()) &&
877 !nextSiblingIsTextNode; 878 !nextSiblingIsTextNode;
878 String rebalancedString = stringWithRebalancedWhitespace( 879 String rebalancedString = stringWithRebalancedWhitespace(
879 string, isStartOfParagraphDeprecated(visibleUpstreamPos) || !upstream, 880 string, isStartOfParagraph(visibleUpstreamPos) || !upstream,
880 shouldEmitNBSPbeforeEnd); 881 shouldEmitNBSPbeforeEnd);
881 882
882 if (string != rebalancedString) 883 if (string != rebalancedString)
883 replaceTextInNodePreservingMarkers(textNode, upstream, length, 884 replaceTextInNodePreservingMarkers(textNode, upstream, length,
884 rebalancedString); 885 rebalancedString);
885 } 886 }
886 887
887 void CompositeEditCommand::prepareWhitespaceAtPositionForSplit( 888 void CompositeEditCommand::prepareWhitespaceAtPositionForSplit(
888 Position& position) { 889 Position& position) {
889 if (!isRichlyEditablePosition(position)) 890 if (!isRichlyEditablePosition(position))
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 : 0; 1047 : 0;
1047 int endOffset = textNode == end.anchorNode() 1048 int endOffset = textNode == end.anchorNode()
1048 ? end.computeOffsetInContainerNode() 1049 ? end.computeOffsetInContainerNode()
1049 : static_cast<int>(textNode->length()); 1050 : static_cast<int>(textNode->length());
1050 deleteInsignificantText(textNode, startOffset, endOffset); 1051 deleteInsignificantText(textNode, startOffset, endOffset);
1051 } 1052 }
1052 } 1053 }
1053 1054
1054 void CompositeEditCommand::deleteInsignificantTextDownstream( 1055 void CompositeEditCommand::deleteInsignificantTextDownstream(
1055 const Position& pos) { 1056 const Position& pos) {
1057 DCHECK(!document().needsLayoutTreeUpdate());
1056 Position end = mostForwardCaretPosition( 1058 Position end = mostForwardCaretPosition(
1057 nextPositionOf(createVisiblePositionDeprecated(pos, VP_DEFAULT_AFFINITY)) 1059 nextPositionOf(createVisiblePosition(pos, VP_DEFAULT_AFFINITY))
1058 .deepEquivalent()); 1060 .deepEquivalent());
1059 deleteInsignificantText(pos, end); 1061 deleteInsignificantText(pos, end);
1060 } 1062 }
1061 1063
1062 HTMLBRElement* CompositeEditCommand::appendBlockPlaceholder( 1064 HTMLBRElement* CompositeEditCommand::appendBlockPlaceholder(
1063 Element* container, 1065 Element* container,
1064 EditingState* editingState) { 1066 EditingState* editingState) {
1065 if (!container) 1067 if (!container)
1066 return nullptr; 1068 return nullptr;
1067 1069
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1142 if (editingState->isAborted()) 1144 if (editingState->isAborted())
1143 return nullptr; 1145 return nullptr;
1144 return paragraphElement; 1146 return paragraphElement;
1145 } 1147 }
1146 1148
1147 // If the paragraph is not entirely within it's own block, create one and move 1149 // If the paragraph is not entirely within it's own block, create one and move
1148 // the paragraph into it, and return that block. Otherwise return 0. 1150 // the paragraph into it, and return that block. Otherwise return 0.
1149 HTMLElement* CompositeEditCommand::moveParagraphContentsToNewBlockIfNecessary( 1151 HTMLElement* CompositeEditCommand::moveParagraphContentsToNewBlockIfNecessary(
1150 const Position& pos, 1152 const Position& pos,
1151 EditingState* editingState) { 1153 EditingState* editingState) {
1154 DCHECK(!document().needsLayoutTreeUpdate());
1152 DCHECK(isEditablePosition(pos)) << pos; 1155 DCHECK(isEditablePosition(pos)) << pos;
1153 1156
1154 // It's strange that this function is responsible for verifying that pos has 1157 // It's strange that this function is responsible for verifying that pos has
1155 // not been invalidated by an earlier call to this function. The caller, 1158 // not been invalidated by an earlier call to this function. The caller,
1156 // applyBlockStyle, should do this. 1159 // applyBlockStyle, should do this.
1157 VisiblePosition visiblePos = 1160 VisiblePosition visiblePos = createVisiblePosition(pos, VP_DEFAULT_AFFINITY);
1158 createVisiblePositionDeprecated(pos, VP_DEFAULT_AFFINITY); 1161 VisiblePosition visibleParagraphStart = startOfParagraph(visiblePos);
1159 VisiblePosition visibleParagraphStart = 1162 VisiblePosition visibleParagraphEnd = endOfParagraph(visiblePos);
1160 startOfParagraphDeprecated(visiblePos);
1161 VisiblePosition visibleParagraphEnd = endOfParagraphDeprecated(visiblePos);
1162 VisiblePosition next = nextPositionOf(visibleParagraphEnd); 1163 VisiblePosition next = nextPositionOf(visibleParagraphEnd);
1163 VisiblePosition visibleEnd = next.isNotNull() ? next : visibleParagraphEnd; 1164 VisiblePosition visibleEnd = next.isNotNull() ? next : visibleParagraphEnd;
1164 1165
1165 Position upstreamStart = 1166 Position upstreamStart =
1166 mostBackwardCaretPosition(visibleParagraphStart.deepEquivalent()); 1167 mostBackwardCaretPosition(visibleParagraphStart.deepEquivalent());
1167 Position upstreamEnd = mostBackwardCaretPosition(visibleEnd.deepEquivalent()); 1168 Position upstreamEnd = mostBackwardCaretPosition(visibleEnd.deepEquivalent());
1168 1169
1169 // If there are no VisiblePositions in the same block as pos then 1170 // If there are no VisiblePositions in the same block as pos then
1170 // upstreamStart will be outside the paragraph 1171 // upstreamStart will be outside the paragraph
1171 if (comparePositions(pos, upstreamStart) < 0) 1172 if (comparePositions(pos, upstreamStart) < 0)
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1207 HTMLElement* newBlock = 1208 HTMLElement* newBlock =
1208 insertNewDefaultParagraphElementAt(upstreamStart, editingState); 1209 insertNewDefaultParagraphElementAt(upstreamStart, editingState);
1209 if (editingState->isAborted()) 1210 if (editingState->isAborted())
1210 return nullptr; 1211 return nullptr;
1211 1212
1212 bool endWasBr = 1213 bool endWasBr =
1213 isHTMLBRElement(*visibleParagraphEnd.deepEquivalent().anchorNode()); 1214 isHTMLBRElement(*visibleParagraphEnd.deepEquivalent().anchorNode());
1214 1215
1215 // Inserting default paragraph element can change visible position. We 1216 // Inserting default paragraph element can change visible position. We
1216 // should update visible positions before use them. 1217 // should update visible positions before use them.
1217 visiblePos = createVisiblePositionDeprecated(pos, VP_DEFAULT_AFFINITY); 1218 document().updateStyleAndLayoutIgnorePendingStylesheets();
1218 visibleParagraphStart = startOfParagraphDeprecated(visiblePos); 1219 visiblePos = createVisiblePosition(pos, VP_DEFAULT_AFFINITY);
1219 visibleParagraphEnd = endOfParagraphDeprecated(visiblePos); 1220 visibleParagraphStart = startOfParagraph(visiblePos);
1221 visibleParagraphEnd = endOfParagraph(visiblePos);
1220 moveParagraphs(visibleParagraphStart, visibleParagraphEnd, 1222 moveParagraphs(visibleParagraphStart, visibleParagraphEnd,
1221 VisiblePosition::firstPositionInNode(newBlock), editingState); 1223 VisiblePosition::firstPositionInNode(newBlock), editingState);
1222 if (editingState->isAborted()) 1224 if (editingState->isAborted())
1223 return nullptr; 1225 return nullptr;
1224 1226
1225 if (newBlock->lastChild() && isHTMLBRElement(*newBlock->lastChild()) && 1227 if (newBlock->lastChild() && isHTMLBRElement(*newBlock->lastChild()) &&
1226 !endWasBr) { 1228 !endWasBr) {
1227 removeNode(newBlock->lastChild(), editingState); 1229 removeNode(newBlock->lastChild(), editingState);
1228 if (editingState->isAborted()) 1230 if (editingState->isAborted())
1229 return nullptr; 1231 return nullptr;
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 } 1348 }
1347 1349
1348 // There are bugs in deletion when it removes a fully selected table/list. 1350 // There are bugs in deletion when it removes a fully selected table/list.
1349 // It expands and removes the entire table/list, but will let content 1351 // It expands and removes the entire table/list, but will let content
1350 // before and after the table/list collapse onto one line. 1352 // before and after the table/list collapse onto one line.
1351 // Deleting a paragraph will leave a placeholder. Remove it (and prune 1353 // Deleting a paragraph will leave a placeholder. Remove it (and prune
1352 // empty or unrendered parents). 1354 // empty or unrendered parents).
1353 1355
1354 void CompositeEditCommand::cleanupAfterDeletion(EditingState* editingState, 1356 void CompositeEditCommand::cleanupAfterDeletion(EditingState* editingState,
1355 VisiblePosition destination) { 1357 VisiblePosition destination) {
1356 VisiblePosition caretAfterDelete = endingSelection().visibleStartDeprecated(); 1358 document().updateStyleAndLayoutIgnorePendingStylesheets();
1359
1360 VisiblePosition caretAfterDelete = endingSelection().visibleStart();
1357 Node* destinationNode = destination.deepEquivalent().anchorNode(); 1361 Node* destinationNode = destination.deepEquivalent().anchorNode();
1358 if (caretAfterDelete.deepEquivalent() != destination.deepEquivalent() && 1362 if (caretAfterDelete.deepEquivalent() != destination.deepEquivalent() &&
1359 isStartOfParagraphDeprecated(caretAfterDelete) && 1363 isStartOfParagraph(caretAfterDelete) &&
1360 isEndOfParagraphDeprecated(caretAfterDelete)) { 1364 isEndOfParagraph(caretAfterDelete)) {
1361 // Note: We want the rightmost candidate. 1365 // Note: We want the rightmost candidate.
1362 Position position = 1366 Position position =
1363 mostForwardCaretPosition(caretAfterDelete.deepEquivalent()); 1367 mostForwardCaretPosition(caretAfterDelete.deepEquivalent());
1364 Node* node = position.anchorNode(); 1368 Node* node = position.anchorNode();
1365 1369
1366 // Bail if we'd remove an ancestor of our destination. 1370 // Bail if we'd remove an ancestor of our destination.
1367 if (destinationNode && destinationNode->isDescendantOf(node)) 1371 if (destinationNode && destinationNode->isDescendantOf(node))
1368 return; 1372 return;
1369 1373
1370 // Normally deletion will leave a br as a placeholder. 1374 // Normally deletion will leave a br as a placeholder.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1424 startOfParagraphToMove.deepEquivalent() == 1428 startOfParagraphToMove.deepEquivalent() ==
1425 endOfParagraphToMove.deepEquivalent() 1429 endOfParagraphToMove.deepEquivalent()
1426 ? start 1430 ? start
1427 : mostBackwardCaretPosition(endOfParagraphToMove.deepEquivalent()); 1431 : mostBackwardCaretPosition(endOfParagraphToMove.deepEquivalent());
1428 if (comparePositions(start, end) > 0) 1432 if (comparePositions(start, end) > 0)
1429 end = start; 1433 end = start;
1430 1434
1431 cloneParagraphUnderNewElement(start, end, outerNode, blockElement, 1435 cloneParagraphUnderNewElement(start, end, outerNode, blockElement,
1432 editingState); 1436 editingState);
1433 1437
1434 setEndingSelection(createVisibleSelectionDeprecated(start, end)); 1438 document().updateStyleAndLayoutIgnorePendingStylesheets();
1439
1440 setEndingSelection(createVisibleSelection(start, end));
1435 deleteSelection(editingState, false, false, false); 1441 deleteSelection(editingState, false, false, false);
1436 if (editingState->isAborted()) 1442 if (editingState->isAborted())
1437 return; 1443 return;
1438 1444
1439 // There are bugs in deletion when it removes a fully selected table/list. 1445 // There are bugs in deletion when it removes a fully selected table/list.
1440 // It expands and removes the entire table/list, but will let content 1446 // It expands and removes the entire table/list, but will let content
1441 // before and after the table/list collapse onto one line. 1447 // before and after the table/list collapse onto one line.
1442 1448
1443 cleanupAfterDeletion(editingState); 1449 cleanupAfterDeletion(editingState);
1444 if (editingState->isAborted()) 1450 if (editingState->isAborted())
1445 return; 1451 return;
1446 1452
1453 document().updateStyleAndLayoutIgnorePendingStylesheets();
1454
1447 // Add a br if pruning an empty block level element caused a collapse. For 1455 // Add a br if pruning an empty block level element caused a collapse. For
1448 // example: 1456 // example:
1449 // foo^ 1457 // foo^
1450 // <div>bar</div> 1458 // <div>bar</div>
1451 // baz 1459 // baz
1452 // Imagine moving 'bar' to ^. 'bar' will be deleted and its div pruned. That 1460 // Imagine moving 'bar' to ^. 'bar' will be deleted and its div pruned. That
1453 // would cause 'baz' to collapse onto the line with 'foobar' unless we insert 1461 // would cause 'baz' to collapse onto the line with 'foobar' unless we insert
1454 // a br. Must recononicalize these two VisiblePositions after the pruning 1462 // a br. Must recononicalize these two VisiblePositions after the pruning
1455 // above. 1463 // above.
1456 // TODO(yosin): We should abort when |beforeParagraph| is a orphan when 1464 // TODO(yosin): We should abort when |beforeParagraph| is a orphan when
1457 // we have a sample. 1465 // we have a sample.
1458 beforeParagraph = 1466 beforeParagraph = createVisiblePosition(beforeParagraph.deepEquivalent());
1459 createVisiblePositionDeprecated(beforeParagraph.deepEquivalent());
1460 if (afterParagraph.isOrphan()) { 1467 if (afterParagraph.isOrphan()) {
1461 editingState->abort(); 1468 editingState->abort();
1462 return; 1469 return;
1463 } 1470 }
1464 afterParagraph = 1471 afterParagraph = createVisiblePosition(afterParagraph.deepEquivalent());
1465 createVisiblePositionDeprecated(afterParagraph.deepEquivalent());
1466 1472
1467 if (beforeParagraph.isNotNull() && 1473 if (beforeParagraph.isNotNull() &&
1468 !isDisplayInsideTable(beforeParagraph.deepEquivalent().anchorNode()) && 1474 !isDisplayInsideTable(beforeParagraph.deepEquivalent().anchorNode()) &&
1469 ((!isEndOfParagraphDeprecated(beforeParagraph) && 1475 ((!isEndOfParagraph(beforeParagraph) &&
1470 !isStartOfParagraphDeprecated(beforeParagraph)) || 1476 !isStartOfParagraph(beforeParagraph)) ||
1471 beforeParagraph.deepEquivalent() == afterParagraph.deepEquivalent())) { 1477 beforeParagraph.deepEquivalent() == afterParagraph.deepEquivalent())) {
1472 // FIXME: Trim text between beforeParagraph and afterParagraph if they 1478 // FIXME: Trim text between beforeParagraph and afterParagraph if they
1473 // aren't equal. 1479 // aren't equal.
1474 insertNodeAt(HTMLBRElement::create(document()), 1480 insertNodeAt(HTMLBRElement::create(document()),
1475 beforeParagraph.deepEquivalent(), editingState); 1481 beforeParagraph.deepEquivalent(), editingState);
1476 } 1482 }
1477 } 1483 }
1478 1484
1485 // TODO(xiaochengh): Ensure valid VisiblePositions are passed to this function.
1479 void CompositeEditCommand::moveParagraph( 1486 void CompositeEditCommand::moveParagraph(
1480 const VisiblePosition& startOfParagraphToMove, 1487 const VisiblePosition& startOfParagraphToMove,
1481 const VisiblePosition& endOfParagraphToMove, 1488 const VisiblePosition& endOfParagraphToMove,
1482 const VisiblePosition& destination, 1489 const VisiblePosition& destination,
1483 EditingState* editingState, 1490 EditingState* editingState,
1484 ShouldPreserveSelection shouldPreserveSelection, 1491 ShouldPreserveSelection shouldPreserveSelection,
1485 ShouldPreserveStyle shouldPreserveStyle, 1492 ShouldPreserveStyle shouldPreserveStyle,
1486 Node* constrainingAncestor) { 1493 Node* constrainingAncestor) {
1487 DCHECK(isStartOfParagraphDeprecated(startOfParagraphToMove)) 1494 DCHECK(isStartOfParagraphDeprecated(startOfParagraphToMove))
1488 << startOfParagraphToMove; 1495 << startOfParagraphToMove;
1489 DCHECK(isEndOfParagraphDeprecated(endOfParagraphToMove)) 1496 DCHECK(isEndOfParagraphDeprecated(endOfParagraphToMove))
1490 << endOfParagraphToMove; 1497 << endOfParagraphToMove;
1491 moveParagraphs(startOfParagraphToMove, endOfParagraphToMove, destination, 1498 moveParagraphs(startOfParagraphToMove, endOfParagraphToMove, destination,
1492 editingState, shouldPreserveSelection, shouldPreserveStyle, 1499 editingState, shouldPreserveSelection, shouldPreserveStyle,
1493 constrainingAncestor); 1500 constrainingAncestor);
1494 } 1501 }
1495 1502
1503 // TODO(xiaochengh): Ensure valid VisiblePositions are passed to this function,
1504 // and do proper recalculation after mutations so that they are still valid when
1505 // being used.
1496 void CompositeEditCommand::moveParagraphs( 1506 void CompositeEditCommand::moveParagraphs(
1497 const VisiblePosition& startOfParagraphToMove, 1507 const VisiblePosition& startOfParagraphToMove,
1498 const VisiblePosition& endOfParagraphToMove, 1508 const VisiblePosition& endOfParagraphToMove,
1499 const VisiblePosition& destination, 1509 const VisiblePosition& destination,
1500 EditingState* editingState, 1510 EditingState* editingState,
1501 ShouldPreserveSelection shouldPreserveSelection, 1511 ShouldPreserveSelection shouldPreserveSelection,
1502 ShouldPreserveStyle shouldPreserveStyle, 1512 ShouldPreserveStyle shouldPreserveStyle,
1503 Node* constrainingAncestor) { 1513 Node* constrainingAncestor) {
1504 if (startOfParagraphToMove.deepEquivalent() == destination.deepEquivalent() || 1514 if (startOfParagraphToMove.deepEquivalent() == destination.deepEquivalent() ||
1505 startOfParagraphToMove.isNull()) 1515 startOfParagraphToMove.isNull())
1506 return; 1516 return;
1507 1517
1518 document().updateStyleAndLayoutIgnorePendingStylesheets();
1519
1508 int startIndex = -1; 1520 int startIndex = -1;
1509 int endIndex = -1; 1521 int endIndex = -1;
1510 int destinationIndex = -1; 1522 int destinationIndex = -1;
1511 bool originalIsDirectional = endingSelection().isDirectional(); 1523 bool originalIsDirectional = endingSelection().isDirectional();
1512 if (shouldPreserveSelection == PreserveSelection && 1524 if (shouldPreserveSelection == PreserveSelection &&
1513 !endingSelection().isNone()) { 1525 !endingSelection().isNone()) {
1514 VisiblePosition visibleStart = endingSelection().visibleStartDeprecated(); 1526 VisiblePosition visibleStart = endingSelection().visibleStart();
1515 VisiblePosition visibleEnd = endingSelection().visibleEndDeprecated(); 1527 VisiblePosition visibleEnd = endingSelection().visibleEnd();
1516 1528
1517 bool startAfterParagraph = 1529 bool startAfterParagraph =
1518 comparePositions(visibleStart, endOfParagraphToMove) > 0; 1530 comparePositions(visibleStart, endOfParagraphToMove) > 0;
1519 bool endBeforeParagraph = 1531 bool endBeforeParagraph =
1520 comparePositions(visibleEnd, startOfParagraphToMove) < 0; 1532 comparePositions(visibleEnd, startOfParagraphToMove) < 0;
1521 1533
1522 if (!startAfterParagraph && !endBeforeParagraph) { 1534 if (!startAfterParagraph && !endBeforeParagraph) {
1523 bool startInParagraph = 1535 bool startInParagraph =
1524 comparePositions(visibleStart, startOfParagraphToMove) >= 0; 1536 comparePositions(visibleStart, startOfParagraphToMove) >= 0;
1525 bool endInParagraph = 1537 bool endInParagraph =
1526 comparePositions(visibleEnd, endOfParagraphToMove) <= 0; 1538 comparePositions(visibleEnd, endOfParagraphToMove) <= 0;
1527 1539
1528 // TextIterator::rangeLength requires clean layout.
1529 document().updateStyleAndLayoutIgnorePendingStylesheets();
1530
1531 startIndex = 0; 1540 startIndex = 0;
1532 if (startInParagraph) 1541 if (startInParagraph)
1533 startIndex = TextIterator::rangeLength( 1542 startIndex = TextIterator::rangeLength(
1534 startOfParagraphToMove.toParentAnchoredPosition(), 1543 startOfParagraphToMove.toParentAnchoredPosition(),
1535 visibleStart.toParentAnchoredPosition(), true); 1544 visibleStart.toParentAnchoredPosition(), true);
1536 1545
1537 endIndex = 0; 1546 endIndex = 0;
1538 if (endInParagraph) 1547 if (endInParagraph)
1539 endIndex = TextIterator::rangeLength( 1548 endIndex = TextIterator::rangeLength(
1540 startOfParagraphToMove.toParentAnchoredPosition(), 1549 startOfParagraphToMove.toParentAnchoredPosition(),
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1585 styleInEmptyParagraph = 1594 styleInEmptyParagraph =
1586 EditingStyle::create(startOfParagraphToMove.deepEquivalent()); 1595 EditingStyle::create(startOfParagraphToMove.deepEquivalent());
1587 styleInEmptyParagraph->mergeTypingStyle(&document()); 1596 styleInEmptyParagraph->mergeTypingStyle(&document());
1588 // The moved paragraph should assume the block style of the destination. 1597 // The moved paragraph should assume the block style of the destination.
1589 styleInEmptyParagraph->removeBlockProperties(); 1598 styleInEmptyParagraph->removeBlockProperties();
1590 } 1599 }
1591 1600
1592 // FIXME (5098931): We should add a new insert action 1601 // FIXME (5098931): We should add a new insert action
1593 // "WebViewInsertActionMoved" and call shouldInsertFragment here. 1602 // "WebViewInsertActionMoved" and call shouldInsertFragment here.
1594 1603
1595 setEndingSelection(createVisibleSelectionDeprecated(start, end)); 1604 DCHECK(!document().needsLayoutTreeUpdate());
1605
1606 setEndingSelection(createVisibleSelection(start, end));
1596 document() 1607 document()
1597 .frame() 1608 .frame()
1598 ->spellChecker() 1609 ->spellChecker()
1599 .clearMisspellingsAndBadGrammarForMovingParagraphs(endingSelection()); 1610 .clearMisspellingsAndBadGrammarForMovingParagraphs(endingSelection());
1600 deleteSelection(editingState, false, false, false); 1611 deleteSelection(editingState, false, false, false);
1601 if (editingState->isAborted()) 1612 if (editingState->isAborted())
1602 return; 1613 return;
1603 1614
1604 DCHECK(destination.deepEquivalent().isConnected()) << destination; 1615 DCHECK(destination.deepEquivalent().isConnected()) << destination;
1605 cleanupAfterDeletion(editingState, destination); 1616 cleanupAfterDeletion(editingState, destination);
1606 if (editingState->isAborted()) 1617 if (editingState->isAborted())
1607 return; 1618 return;
1608 DCHECK(destination.deepEquivalent().isConnected()) << destination; 1619 DCHECK(destination.deepEquivalent().isConnected()) << destination;
1609 1620
1621 document().updateStyleAndLayoutIgnorePendingStylesheets();
1622
1610 // Add a br if pruning an empty block level element caused a collapse. For 1623 // Add a br if pruning an empty block level element caused a collapse. For
1611 // example: 1624 // example:
1612 // foo^ 1625 // foo^
1613 // <div>bar</div> 1626 // <div>bar</div>
1614 // baz 1627 // baz
1615 // Imagine moving 'bar' to ^. 'bar' will be deleted and its div pruned. That 1628 // Imagine moving 'bar' to ^. 'bar' will be deleted and its div pruned. That
1616 // would cause 'baz' to collapse onto the line with 'foobar' unless we insert 1629 // would cause 'baz' to collapse onto the line with 'foobar' unless we insert
1617 // a br. Must recononicalize these two VisiblePositions after the pruning 1630 // a br. Must recononicalize these two VisiblePositions after the pruning
1618 // above. 1631 // above.
1619 VisiblePosition beforeParagraph = 1632 VisiblePosition beforeParagraph =
1620 createVisiblePositionDeprecated(beforeParagraphPosition.position()); 1633 createVisiblePosition(beforeParagraphPosition.position());
1621 VisiblePosition afterParagraph = 1634 VisiblePosition afterParagraph =
1622 createVisiblePositionDeprecated(afterParagraphPosition.position()); 1635 createVisiblePosition(afterParagraphPosition.position());
1623 if (beforeParagraph.isNotNull() && 1636 if (beforeParagraph.isNotNull() &&
1624 (!isEndOfParagraphDeprecated(beforeParagraph) || 1637 (!isEndOfParagraph(beforeParagraph) ||
1625 beforeParagraph.deepEquivalent() == afterParagraph.deepEquivalent())) { 1638 beforeParagraph.deepEquivalent() == afterParagraph.deepEquivalent())) {
1626 // FIXME: Trim text between beforeParagraph and afterParagraph if they 1639 // FIXME: Trim text between beforeParagraph and afterParagraph if they
1627 // aren't equal. 1640 // aren't equal.
1628 insertNodeAt(HTMLBRElement::create(document()), 1641 insertNodeAt(HTMLBRElement::create(document()),
1629 beforeParagraph.deepEquivalent(), editingState); 1642 beforeParagraph.deepEquivalent(), editingState);
1630 if (editingState->isAborted()) 1643 if (editingState->isAborted())
1631 return; 1644 return;
1632 // Need an updateLayout here in case inserting the br has split a text node. 1645 // Need an updateLayout here in case inserting the br has split a text node.
1633 document().updateStyleAndLayoutIgnorePendingStylesheets(); 1646 document().updateStyleAndLayoutIgnorePendingStylesheets();
1634 } 1647 }
(...skipping 14 matching lines...) Expand all
1649 ReplaceSelectionCommand::SelectReplacement | 1662 ReplaceSelectionCommand::SelectReplacement |
1650 ReplaceSelectionCommand::MovingParagraph; 1663 ReplaceSelectionCommand::MovingParagraph;
1651 if (shouldPreserveStyle == DoNotPreserveStyle) 1664 if (shouldPreserveStyle == DoNotPreserveStyle)
1652 options |= ReplaceSelectionCommand::MatchStyle; 1665 options |= ReplaceSelectionCommand::MatchStyle;
1653 applyCommandToComposite( 1666 applyCommandToComposite(
1654 ReplaceSelectionCommand::create(document(), fragment, options), 1667 ReplaceSelectionCommand::create(document(), fragment, options),
1655 editingState); 1668 editingState);
1656 if (editingState->isAborted()) 1669 if (editingState->isAborted())
1657 return; 1670 return;
1658 1671
1672 document().updateStyleAndLayoutIgnorePendingStylesheets();
1673
1659 document() 1674 document()
1660 .frame() 1675 .frame()
1661 ->spellChecker() 1676 ->spellChecker()
1662 .markMisspellingsAndBadGrammarForMovingParagraphs(endingSelection()); 1677 .markMisspellingsAndBadGrammarForMovingParagraphs(endingSelection());
1663 1678
1664 // If the selection is in an empty paragraph, restore styles from the old 1679 // If the selection is in an empty paragraph, restore styles from the old
1665 // empty paragraph to the new empty paragraph. 1680 // empty paragraph to the new empty paragraph.
1666 bool selectionIsEmptyParagraph = 1681 bool selectionIsEmptyParagraph =
1667 endingSelection().isCaret() && 1682 endingSelection().isCaret() &&
1668 isStartOfParagraphDeprecated( 1683 isStartOfParagraph(endingSelection().visibleStart()) &&
1669 endingSelection().visibleStartDeprecated()) && 1684 isEndOfParagraph(endingSelection().visibleStart());
1670 isEndOfParagraphDeprecated(endingSelection().visibleStartDeprecated());
1671 if (styleInEmptyParagraph && selectionIsEmptyParagraph) { 1685 if (styleInEmptyParagraph && selectionIsEmptyParagraph) {
1672 applyStyle(styleInEmptyParagraph, editingState); 1686 applyStyle(styleInEmptyParagraph, editingState);
1673 if (editingState->isAborted()) 1687 if (editingState->isAborted())
1674 return; 1688 return;
1675 } 1689 }
1676 1690
1677 if (shouldPreserveSelection == DoNotPreserveSelection || startIndex == -1) 1691 if (shouldPreserveSelection == DoNotPreserveSelection || startIndex == -1)
1678 return; 1692 return;
1679 Element* documentElement = document().documentElement(); 1693 Element* documentElement = document().documentElement();
1680 if (!documentElement) 1694 if (!documentElement)
1681 return; 1695 return;
1682 1696
1683 // We need clean layout in order to compute plain-text ranges below. 1697 // We need clean layout in order to compute plain-text ranges below.
1684 document().updateStyleAndLayoutIgnorePendingStylesheets(); 1698 document().updateStyleAndLayoutIgnorePendingStylesheets();
1685 1699
1686 // Fragment creation (using createMarkup) incorrectly uses regular spaces 1700 // Fragment creation (using createMarkup) incorrectly uses regular spaces
1687 // instead of nbsps for some spaces that were rendered (11475), which causes 1701 // instead of nbsps for some spaces that were rendered (11475), which causes
1688 // spaces to be collapsed during the move operation. This results in a call 1702 // spaces to be collapsed during the move operation. This results in a call
1689 // to rangeFromLocationAndLength with a location past the end of the 1703 // to rangeFromLocationAndLength with a location past the end of the
1690 // document (which will return null). 1704 // document (which will return null).
1691 EphemeralRange startRange = PlainTextRange(destinationIndex + startIndex) 1705 EphemeralRange startRange = PlainTextRange(destinationIndex + startIndex)
1692 .createRangeForSelection(*documentElement); 1706 .createRangeForSelection(*documentElement);
1693 if (startRange.isNull()) 1707 if (startRange.isNull())
1694 return; 1708 return;
1695 EphemeralRange endRange = PlainTextRange(destinationIndex + endIndex) 1709 EphemeralRange endRange = PlainTextRange(destinationIndex + endIndex)
1696 .createRangeForSelection(*documentElement); 1710 .createRangeForSelection(*documentElement);
1697 if (endRange.isNull()) 1711 if (endRange.isNull())
1698 return; 1712 return;
1699 setEndingSelection(createVisibleSelectionDeprecated( 1713 setEndingSelection(createVisibleSelection(
1700 startRange.startPosition(), endRange.startPosition(), 1714 startRange.startPosition(), endRange.startPosition(),
1701 TextAffinity::Downstream, originalIsDirectional)); 1715 TextAffinity::Downstream, originalIsDirectional));
1702 } 1716 }
1703 1717
1704 // FIXME: Send an appropriate shouldDeleteRange call. 1718 // FIXME: Send an appropriate shouldDeleteRange call.
1705 bool CompositeEditCommand::breakOutOfEmptyListItem(EditingState* editingState) { 1719 bool CompositeEditCommand::breakOutOfEmptyListItem(EditingState* editingState) {
1720 DCHECK(!document().needsLayoutTreeUpdate());
1706 Node* emptyListItem = 1721 Node* emptyListItem =
1707 enclosingEmptyListItem(endingSelection().visibleStartDeprecated()); 1722 enclosingEmptyListItem(endingSelection().visibleStart());
1708 if (!emptyListItem) 1723 if (!emptyListItem)
1709 return false; 1724 return false;
1710 1725
1711 EditingStyle* style = EditingStyle::create(endingSelection().start()); 1726 EditingStyle* style = EditingStyle::create(endingSelection().start());
1712 style->mergeTypingStyle(&document()); 1727 style->mergeTypingStyle(&document());
1713 1728
1714 ContainerNode* listNode = emptyListItem->parentNode(); 1729 ContainerNode* listNode = emptyListItem->parentNode();
1715 // FIXME: Can't we do something better when the immediate parent wasn't a list 1730 // FIXME: Can't we do something better when the immediate parent wasn't a list
1716 // node? 1731 // node?
1717 if (!listNode || 1732 if (!listNode ||
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 ? emptyListItem 1805 ? emptyListItem
1791 : listNode, 1806 : listNode,
1792 editingState); 1807 editingState);
1793 if (editingState->isAborted()) 1808 if (editingState->isAborted())
1794 return false; 1809 return false;
1795 } 1810 }
1796 1811
1797 appendBlockPlaceholder(newBlock, editingState); 1812 appendBlockPlaceholder(newBlock, editingState);
1798 if (editingState->isAborted()) 1813 if (editingState->isAborted())
1799 return false; 1814 return false;
1800 setEndingSelection(createVisibleSelectionDeprecated( 1815
1816 document().updateStyleAndLayoutIgnorePendingStylesheets();
1817 setEndingSelection(createVisibleSelection(
1801 Position::firstPositionInNode(newBlock), TextAffinity::Downstream, 1818 Position::firstPositionInNode(newBlock), TextAffinity::Downstream,
1802 endingSelection().isDirectional())); 1819 endingSelection().isDirectional()));
1803 1820
1804 style->prepareToApplyAt(endingSelection().start()); 1821 style->prepareToApplyAt(endingSelection().start());
1805 if (!style->isEmpty()) { 1822 if (!style->isEmpty()) {
1806 applyStyle(style, editingState); 1823 applyStyle(style, editingState);
1807 if (editingState->isAborted()) 1824 if (editingState->isAborted())
1808 return false; 1825 return false;
1809 } 1826 }
1810 1827
1811 return true; 1828 return true;
1812 } 1829 }
1813 1830
1814 // If the caret is in an empty quoted paragraph, and either there is nothing 1831 // If the caret is in an empty quoted paragraph, and either there is nothing
1815 // before that paragraph, or what is before is unquoted, and the user presses 1832 // before that paragraph, or what is before is unquoted, and the user presses
1816 // delete, unquote that paragraph. 1833 // delete, unquote that paragraph.
1817 bool CompositeEditCommand::breakOutOfEmptyMailBlockquotedParagraph( 1834 bool CompositeEditCommand::breakOutOfEmptyMailBlockquotedParagraph(
1818 EditingState* editingState) { 1835 EditingState* editingState) {
1819 if (!endingSelection().isCaret()) 1836 if (!endingSelection().isCaret())
1820 return false; 1837 return false;
1821 1838
1822 VisiblePosition caret = endingSelection().visibleStartDeprecated(); 1839 document().updateStyleAndLayoutIgnorePendingStylesheets();
1840
1841 VisiblePosition caret = endingSelection().visibleStart();
1823 HTMLQuoteElement* highestBlockquote = 1842 HTMLQuoteElement* highestBlockquote =
1824 toHTMLQuoteElement(highestEnclosingNodeOfType( 1843 toHTMLQuoteElement(highestEnclosingNodeOfType(
1825 caret.deepEquivalent(), &isMailHTMLBlockquoteElement)); 1844 caret.deepEquivalent(), &isMailHTMLBlockquoteElement));
1826 if (!highestBlockquote) 1845 if (!highestBlockquote)
1827 return false; 1846 return false;
1828 1847
1829 if (!isStartOfParagraphDeprecated(caret) || 1848 if (!isStartOfParagraph(caret) || !isEndOfParagraph(caret))
1830 !isEndOfParagraphDeprecated(caret))
1831 return false; 1849 return false;
1832 1850
1833 VisiblePosition previous = 1851 VisiblePosition previous =
1834 previousPositionOf(caret, CannotCrossEditingBoundary); 1852 previousPositionOf(caret, CannotCrossEditingBoundary);
1835 // Only move forward if there's nothing before the caret, or if there's 1853 // Only move forward if there's nothing before the caret, or if there's
1836 // unquoted content before it. 1854 // unquoted content before it.
1837 if (enclosingNodeOfType(previous.deepEquivalent(), 1855 if (enclosingNodeOfType(previous.deepEquivalent(),
1838 &isMailHTMLBlockquoteElement)) 1856 &isMailHTMLBlockquoteElement))
1839 return false; 1857 return false;
1840 1858
1841 HTMLBRElement* br = HTMLBRElement::create(document()); 1859 HTMLBRElement* br = HTMLBRElement::create(document());
1842 // We want to replace this quoted paragraph with an unquoted one, so insert a 1860 // We want to replace this quoted paragraph with an unquoted one, so insert a
1843 // br to hold the caret before the highest blockquote. 1861 // br to hold the caret before the highest blockquote.
1844 insertNodeBefore(br, highestBlockquote, editingState); 1862 insertNodeBefore(br, highestBlockquote, editingState);
1845 if (editingState->isAborted()) 1863 if (editingState->isAborted())
1846 return false; 1864 return false;
1865
1866 document().updateStyleAndLayoutIgnorePendingStylesheets();
1867
1847 VisiblePosition atBR = VisiblePosition::beforeNode(br); 1868 VisiblePosition atBR = VisiblePosition::beforeNode(br);
1848 // If the br we inserted collapsed, for example: 1869 // If the br we inserted collapsed, for example:
1849 // foo<br><blockquote>...</blockquote> 1870 // foo<br><blockquote>...</blockquote>
1850 // insert a second one. 1871 // insert a second one.
1851 if (!isStartOfParagraphDeprecated(atBR)) { 1872 if (!isStartOfParagraph(atBR)) {
1852 insertNodeBefore(HTMLBRElement::create(document()), br, editingState); 1873 insertNodeBefore(HTMLBRElement::create(document()), br, editingState);
1853 if (editingState->isAborted()) 1874 if (editingState->isAborted())
1854 return false; 1875 return false;
1876 document().updateStyleAndLayoutIgnorePendingStylesheets();
1855 } 1877 }
1856 setEndingSelection(createVisibleSelectionDeprecated( 1878 setEndingSelection(createVisibleSelection(atBR.toPositionWithAffinity(),
1857 atBR, endingSelection().isDirectional())); 1879 endingSelection().isDirectional()));
1858 1880
1859 // If this is an empty paragraph there must be a line break here. 1881 // If this is an empty paragraph there must be a line break here.
1860 if (!lineBreakExistsAtVisiblePosition(caret)) 1882 if (!lineBreakExistsAtVisiblePosition(caret))
1861 return false; 1883 return false;
1862 1884
1863 Position caretPos(mostForwardCaretPosition(caret.deepEquivalent())); 1885 Position caretPos(mostForwardCaretPosition(caret.deepEquivalent()));
1864 // A line break is either a br or a preserved newline. 1886 // A line break is either a br or a preserved newline.
1865 DCHECK(isHTMLBRElement(caretPos.anchorNode()) || 1887 DCHECK(isHTMLBRElement(caretPos.anchorNode()) ||
1866 (caretPos.anchorNode()->isTextNode() && 1888 (caretPos.anchorNode()->isTextNode() &&
1867 caretPos.anchorNode()->layoutObject()->style()->preserveNewline())) 1889 caretPos.anchorNode()->layoutObject()->style()->preserveNewline()))
(...skipping 22 matching lines...) Expand all
1890 // Operations use this function to avoid inserting content into an anchor when 1912 // Operations use this function to avoid inserting content into an anchor when
1891 // at the start or the end of that anchor, as in NSTextView. 1913 // at the start or the end of that anchor, as in NSTextView.
1892 // FIXME: This is only an approximation of NSTextViews insertion behavior, which 1914 // FIXME: This is only an approximation of NSTextViews insertion behavior, which
1893 // varies depending on how the caret was made. 1915 // varies depending on how the caret was made.
1894 Position CompositeEditCommand::positionAvoidingSpecialElementBoundary( 1916 Position CompositeEditCommand::positionAvoidingSpecialElementBoundary(
1895 const Position& original, 1917 const Position& original,
1896 EditingState* editingState) { 1918 EditingState* editingState) {
1897 if (original.isNull()) 1919 if (original.isNull())
1898 return original; 1920 return original;
1899 1921
1900 VisiblePosition visiblePos = createVisiblePositionDeprecated(original); 1922 document().updateStyleAndLayoutIgnorePendingStylesheets();
1923 VisiblePosition visiblePos = createVisiblePosition(original);
1901 Element* enclosingAnchor = enclosingAnchorElement(original); 1924 Element* enclosingAnchor = enclosingAnchorElement(original);
1902 Position result = original; 1925 Position result = original;
1903 1926
1904 if (!enclosingAnchor) 1927 if (!enclosingAnchor)
1905 return result; 1928 return result;
1906 1929
1907 // Don't avoid block level anchors, because that would insert content into the 1930 // Don't avoid block level anchors, because that would insert content into the
1908 // wrong paragraph. 1931 // wrong paragraph.
1909 if (enclosingAnchor && !isEnclosingBlock(enclosingAnchor)) { 1932 if (enclosingAnchor && !isEnclosingBlock(enclosingAnchor)) {
1910 VisiblePosition firstInAnchor = 1933 VisiblePosition firstInAnchor =
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1975 end = end->parentNode(); 1998 end = end->parentNode();
1976 if (!start->isDescendantOf(end)) 1999 if (!start->isDescendantOf(end))
1977 return end; 2000 return end;
1978 2001
1979 Node* endNode = end; 2002 Node* endNode = end;
1980 Node* node = nullptr; 2003 Node* node = nullptr;
1981 for (node = start; node->parentNode() != endNode; node = node->parentNode()) { 2004 for (node = start; node->parentNode() != endNode; node = node->parentNode()) {
1982 Element* parentElement = node->parentElement(); 2005 Element* parentElement = node->parentElement();
1983 if (!parentElement) 2006 if (!parentElement)
1984 break; 2007 break;
2008
2009 document().updateStyleAndLayoutIgnorePendingStylesheets();
2010
1985 // Do not split a node when doing so introduces an empty node. 2011 // Do not split a node when doing so introduces an empty node.
1986 VisiblePosition positionInParent = 2012 VisiblePosition positionInParent =
1987 VisiblePosition::firstPositionInNode(parentElement); 2013 VisiblePosition::firstPositionInNode(parentElement);
1988 VisiblePosition positionInNode = 2014 VisiblePosition positionInNode =
1989 createVisiblePositionDeprecated(firstPositionInOrBeforeNode(node)); 2015 createVisiblePosition(firstPositionInOrBeforeNode(node));
1990 if (positionInParent.deepEquivalent() != positionInNode.deepEquivalent()) 2016 if (positionInParent.deepEquivalent() != positionInNode.deepEquivalent())
1991 splitElement(parentElement, node); 2017 splitElement(parentElement, node);
1992 } 2018 }
1993 2019
1994 return node; 2020 return node;
1995 } 2021 }
1996 2022
1997 DEFINE_TRACE(CompositeEditCommand) { 2023 DEFINE_TRACE(CompositeEditCommand) {
1998 visitor->trace(m_commands); 2024 visitor->trace(m_commands);
1999 visitor->trace(m_composition); 2025 visitor->trace(m_composition);
2000 EditCommand::trace(visitor); 2026 EditCommand::trace(visitor);
2001 } 2027 }
2002 2028
2003 } // namespace blink 2029 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698