Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 962 afterParagraph = VisiblePosition(afterParagraph.deepEquivalent()); | 962 afterParagraph = VisiblePosition(afterParagraph.deepEquivalent()); |
| 963 } | 963 } |
| 964 | 964 |
| 965 void CompositeEditCommand::moveParagraph(const VisiblePosition& startOfParagraph ToMove, const VisiblePosition& endOfParagraphToMove, const VisiblePosition& dest ination, bool preserveSelection, bool preserveStyle, Node* constrainingAncestor) | 965 void CompositeEditCommand::moveParagraph(const VisiblePosition& startOfParagraph ToMove, const VisiblePosition& endOfParagraphToMove, const VisiblePosition& dest ination, bool preserveSelection, bool preserveStyle, Node* constrainingAncestor) |
| 966 { | 966 { |
| 967 ASSERT(isStartOfParagraph(startOfParagraphToMove)); | 967 ASSERT(isStartOfParagraph(startOfParagraphToMove)); |
| 968 ASSERT(isEndOfParagraph(endOfParagraphToMove)); | 968 ASSERT(isEndOfParagraph(endOfParagraphToMove)); |
| 969 moveParagraphs(startOfParagraphToMove, endOfParagraphToMove, destination, pr eserveSelection, preserveStyle, constrainingAncestor); | 969 moveParagraphs(startOfParagraphToMove, endOfParagraphToMove, destination, pr eserveSelection, preserveStyle, constrainingAncestor); |
| 970 } | 970 } |
| 971 | 971 |
| 972 void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap hToMove, const VisiblePosition& endOfParagraphToMove, const VisiblePosition& des tination, bool preserveSelection, bool preserveStyle, Node* constrainingAncestor ) | 972 void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap hToMove, const VisiblePosition& endOfParagraphToMove, const VisiblePosition& des tination, bool preserveSelection, bool preserveStyle, Node* constrainingAncestor ) |
|
eseidel
2014/10/24 22:48:21
I'm sure this horribly breaks editing.
| |
| 973 { | 973 { |
|
esprehn
2014/10/24 22:52:06
Can you add a FIXME or something? Just deleting th
| |
| 974 if (startOfParagraphToMove == destination || startOfParagraphToMove.isNull() ) | |
| 975 return; | |
| 976 | |
| 977 int startIndex = -1; | |
| 978 int endIndex = -1; | |
| 979 int destinationIndex = -1; | |
| 980 bool originalIsDirectional = endingSelection().isDirectional(); | |
| 981 if (preserveSelection && !endingSelection().isNone()) { | |
| 982 VisiblePosition visibleStart = endingSelection().visibleStart(); | |
| 983 VisiblePosition visibleEnd = endingSelection().visibleEnd(); | |
| 984 | |
| 985 bool startAfterParagraph = comparePositions(visibleStart, endOfParagraph ToMove) > 0; | |
| 986 bool endBeforeParagraph = comparePositions(visibleEnd, startOfParagraphT oMove) < 0; | |
| 987 | |
| 988 if (!startAfterParagraph && !endBeforeParagraph) { | |
| 989 bool startInParagraph = comparePositions(visibleStart, startOfParagr aphToMove) >= 0; | |
| 990 bool endInParagraph = comparePositions(visibleEnd, endOfParagraphToM ove) <= 0; | |
| 991 | |
| 992 startIndex = 0; | |
| 993 if (startInParagraph) { | |
| 994 RefPtrWillBeRawPtr<Range> startRange = Range::create(document(), startOfParagraphToMove.deepEquivalent().parentAnchoredEquivalent(), visibleStar t.deepEquivalent().parentAnchoredEquivalent()); | |
| 995 startIndex = TextIterator::rangeLength(startRange.get(), true); | |
| 996 } | |
| 997 | |
| 998 endIndex = 0; | |
| 999 if (endInParagraph) { | |
| 1000 RefPtrWillBeRawPtr<Range> endRange = Range::create(document(), s tartOfParagraphToMove.deepEquivalent().parentAnchoredEquivalent(), visibleEnd.de epEquivalent().parentAnchoredEquivalent()); | |
| 1001 endIndex = TextIterator::rangeLength(endRange.get(), true); | |
| 1002 } | |
| 1003 } | |
| 1004 } | |
| 1005 | |
| 1006 VisiblePosition beforeParagraph = startOfParagraphToMove.previous(CannotCros sEditingBoundary); | |
| 1007 VisiblePosition afterParagraph(endOfParagraphToMove.next(CannotCrossEditingB oundary)); | |
| 1008 | |
| 1009 // We upstream() the end and downstream() the start so that we don't include collapsed whitespace in the move. | |
| 1010 // When we paste a fragment, spaces after the end and before the start are t reated as though they were rendered. | |
| 1011 Position start = startOfParagraphToMove.deepEquivalent().downstream(); | |
| 1012 Position end = endOfParagraphToMove.deepEquivalent().upstream(); | |
| 1013 | |
| 1014 // start and end can't be used directly to create a Range; they are "editing positions" | |
| 1015 Position startRangeCompliant = start.parentAnchoredEquivalent(); | |
| 1016 Position endRangeCompliant = end.parentAnchoredEquivalent(); | |
| 1017 RefPtrWillBeRawPtr<Range> range = Range::create(document(), startRangeCompli ant.deprecatedNode(), startRangeCompliant.deprecatedEditingOffset(), endRangeCom pliant.deprecatedNode(), endRangeCompliant.deprecatedEditingOffset()); | |
| 1018 | |
| 1019 // FIXME: This is an inefficient way to preserve style on nodes in the parag raph to move. It | |
| 1020 // shouldn't matter though, since moved paragraphs will usually be quite sma ll. | |
| 1021 RefPtrWillBeRawPtr<DocumentFragment> fragment = startOfParagraphToMove != en dOfParagraphToMove ? | |
| 1022 createFragmentFromMarkup(document(), createMarkup(range.get(), 0, DoNotA nnotateForInterchange, true, DoNotResolveURLs, constrainingAncestor)) : nullptr; | |
| 1023 | |
| 1024 // A non-empty paragraph's style is moved when we copy and move it. We don' t move | |
| 1025 // anything if we're given an empty paragraph, but an empty paragraph can ha ve style | |
| 1026 // too, <div><b><br></b></div> for example. Save it so that we can preserve it later. | |
| 1027 RefPtrWillBeRawPtr<EditingStyle> styleInEmptyParagraph = nullptr; | |
| 1028 if (startOfParagraphToMove == endOfParagraphToMove && preserveStyle) { | |
| 1029 styleInEmptyParagraph = EditingStyle::create(startOfParagraphToMove.deep Equivalent()); | |
| 1030 styleInEmptyParagraph->mergeTypingStyle(&document()); | |
| 1031 // The moved paragraph should assume the block style of the destination. | |
| 1032 styleInEmptyParagraph->removeBlockProperties(); | |
| 1033 } | |
| 1034 | |
| 1035 // FIXME (5098931): We should add a new insert action "WebViewInsertActionMo ved" and call shouldInsertFragment here. | |
| 1036 | |
| 1037 setEndingSelection(VisibleSelection(start, end, DOWNSTREAM)); | |
| 1038 document().frame()->spellChecker().clearMisspellingsAndBadGrammar(endingSele ction()); | |
| 1039 deleteSelection(false, false, false); | |
| 1040 | |
| 1041 ASSERT(destination.deepEquivalent().inDocument()); | |
| 1042 cleanupAfterDeletion(destination); | |
| 1043 ASSERT(destination.deepEquivalent().inDocument()); | |
| 1044 | |
| 1045 // Add a br if pruning an empty block level element caused a collapse. For e xample: | |
| 1046 // foo^ | |
| 1047 // <div>bar</div> | |
| 1048 // baz | |
| 1049 // Imagine moving 'bar' to ^. 'bar' will be deleted and its div pruned. That would | |
| 1050 // cause 'baz' to collapse onto the line with 'foobar' unless we insert a br . | |
| 1051 // Must recononicalize these two VisiblePositions after the pruning above. | |
| 1052 beforeParagraph = VisiblePosition(beforeParagraph.deepEquivalent()); | |
| 1053 afterParagraph = VisiblePosition(afterParagraph.deepEquivalent()); | |
| 1054 if (beforeParagraph.isNotNull() && (!isEndOfParagraph(beforeParagraph) || be foreParagraph == afterParagraph)) { | |
| 1055 // Need an updateLayout here in case inserting the br has split a text n ode. | |
| 1056 document().updateLayoutIgnorePendingStylesheets(); | |
| 1057 } | |
| 1058 | |
| 1059 RefPtrWillBeRawPtr<Range> startToDestinationRange(Range::create(document(), firstPositionInNode(document().documentElement()), destination.deepEquivalent(). parentAnchoredEquivalent())); | |
| 1060 destinationIndex = TextIterator::rangeLength(startToDestinationRange.get(), true); | |
| 1061 | |
| 1062 setEndingSelection(VisibleSelection(destination, originalIsDirectional)); | |
| 1063 ASSERT(endingSelection().isCaretOrRange()); | |
| 1064 ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::S electReplacement | ReplaceSelectionCommand::MovingParagraph; | |
| 1065 if (!preserveStyle) | |
| 1066 options |= ReplaceSelectionCommand::MatchStyle; | |
| 1067 applyCommandToComposite(ReplaceSelectionCommand::create(document(), fragment , options)); | |
| 1068 | |
| 1069 document().frame()->spellChecker().markMisspellingsAndBadGrammar(endingSelec tion()); | |
| 1070 | |
| 1071 if (preserveSelection && startIndex != -1) { | |
| 1072 if (Element* documentElement = document().documentElement()) { | |
| 1073 // Fragment creation (using createMarkup) incorrectly uses regular | |
| 1074 // spaces instead of nbsps for some spaces that were rendered (11475 ), which | |
| 1075 // causes spaces to be collapsed during the move operation. This res ults | |
| 1076 // in a call to rangeFromLocationAndLength with a location past the end | |
| 1077 // of the document (which will return null). | |
| 1078 RefPtrWillBeRawPtr<Range> start = PlainTextRange(destinationIndex + startIndex).createRangeForSelection(*documentElement); | |
| 1079 RefPtrWillBeRawPtr<Range> end = PlainTextRange(destinationIndex + en dIndex).createRangeForSelection(*documentElement); | |
| 1080 if (start && end) | |
| 1081 setEndingSelection(VisibleSelection(start->startPosition(), end- >startPosition(), DOWNSTREAM, originalIsDirectional)); | |
| 1082 } | |
| 1083 } | |
| 1084 } | 974 } |
| 1085 | 975 |
| 1086 // FIXME: Send an appropriate shouldDeleteRange call. | 976 // FIXME: Send an appropriate shouldDeleteRange call. |
| 1087 bool CompositeEditCommand::breakOutOfEmptyListItem() | 977 bool CompositeEditCommand::breakOutOfEmptyListItem() |
| 1088 { | 978 { |
| 1089 return false; | 979 return false; |
| 1090 } | 980 } |
| 1091 | 981 |
| 1092 // If the caret is in an empty quoted paragraph, and either there is nothing bef ore that | 982 // If the caret is in an empty quoted paragraph, and either there is nothing bef ore that |
| 1093 // paragraph, or what is before is unquoted, and the user presses delete, unquot e that paragraph. | 983 // paragraph, or what is before is unquoted, and the user presses delete, unquot e that paragraph. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1187 } | 1077 } |
| 1188 | 1078 |
| 1189 void CompositeEditCommand::trace(Visitor* visitor) | 1079 void CompositeEditCommand::trace(Visitor* visitor) |
| 1190 { | 1080 { |
| 1191 visitor->trace(m_commands); | 1081 visitor->trace(m_commands); |
| 1192 visitor->trace(m_composition); | 1082 visitor->trace(m_composition); |
| 1193 EditCommand::trace(visitor); | 1083 EditCommand::trace(visitor); |
| 1194 } | 1084 } |
| 1195 | 1085 |
| 1196 } // namespace blink | 1086 } // namespace blink |
| OLD | NEW |