OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2006, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2010 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 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
120 // ends "inside" that paragraph, so it would be confusing if InsertUn{Ordere d}List | 120 // ends "inside" that paragraph, so it would be confusing if InsertUn{Ordere d}List |
121 // operated on that paragraph. | 121 // operated on that paragraph. |
122 // FIXME: We paint the gap before some paragraphs that are indented with lef t | 122 // FIXME: We paint the gap before some paragraphs that are indented with lef t |
123 // margin/padding, but not others. We should make the gap painting more con sistent and | 123 // margin/padding, but not others. We should make the gap painting more con sistent and |
124 // then use a left margin/padding rule here. | 124 // then use a left margin/padding rule here. |
125 if (visibleEnd != visibleStart && isStartOfParagraph(visibleEnd, CanSkipOver EditingBoundary)) | 125 if (visibleEnd != visibleStart && isStartOfParagraph(visibleEnd, CanSkipOver EditingBoundary)) |
126 setEndingSelection(VisibleSelection(visibleStart, visibleEnd.previous(Ca nnotCrossEditingBoundary), endingSelection().isDirectional())); | 126 setEndingSelection(VisibleSelection(visibleStart, visibleEnd.previous(Ca nnotCrossEditingBoundary), endingSelection().isDirectional())); |
127 | 127 |
128 const QualifiedName& listTag = (m_type == OrderedList) ? olTag : ulTag; | 128 const QualifiedName& listTag = (m_type == OrderedList) ? olTag : ulTag; |
129 if (endingSelection().isRange()) { | 129 if (endingSelection().isRange()) { |
130 bool forceCreateList = false; | |
leviw_travelin_and_unemployed
2013/12/18 21:39:42
nit: forceListCreation?
| |
130 VisibleSelection selection = selectionForParagraphIteration(endingSelect ion()); | 131 VisibleSelection selection = selectionForParagraphIteration(endingSelect ion()); |
131 ASSERT(selection.isRange()); | 132 ASSERT(selection.isRange()); |
132 VisiblePosition startOfSelection = selection.visibleStart(); | 133 VisiblePosition startOfSelection = selection.visibleStart(); |
133 VisiblePosition endOfSelection = selection.visibleEnd(); | 134 VisiblePosition endOfSelection = selection.visibleEnd(); |
134 VisiblePosition startOfLastParagraph = startOfParagraph(endOfSelection, CanSkipOverEditingBoundary); | 135 VisiblePosition startOfLastParagraph = startOfParagraph(endOfSelection, CanSkipOverEditingBoundary); |
136 RefPtr<Range> currentSelection = endingSelection().firstRange(); | |
137 | |
138 RefPtr<ContainerNode> scopeForStartOfSelection; | |
139 RefPtr<ContainerNode> scopeForEndOfSelection; | |
140 // FIXME: This is an inefficient way to keep selection alive because ind exForVisiblePosition walks from | |
141 // the beginning of the document to the endOfSelection everytime this co de is executed. | |
142 // But not using index is hard because there are so many ways we can los e selection inside doApplyForSingleParagraph. | |
143 int indexForStartOfSelection = indexForVisiblePosition(startOfSelection, scopeForStartOfSelection); | |
144 int indexForEndOfSelection = indexForVisiblePosition(endOfSelection, sco peForEndOfSelection); | |
135 | 145 |
136 if (startOfParagraph(startOfSelection, CanSkipOverEditingBoundary) != st artOfLastParagraph) { | 146 if (startOfParagraph(startOfSelection, CanSkipOverEditingBoundary) != st artOfLastParagraph) { |
137 RefPtr<ContainerNode> scope; | 147 forceCreateList = !selectionHasListOfType(selection, listTag); |
138 int indexForEndOfSelection = indexForVisiblePosition(endOfSelection, scope); | |
139 bool forceCreateList = !selectionHasListOfType(selection, listTag); | |
140 | |
141 RefPtr<Range> currentSelection = endingSelection().firstRange(); | |
142 VisiblePosition startOfCurrentParagraph = startOfSelection; | 148 VisiblePosition startOfCurrentParagraph = startOfSelection; |
143 while (!inSameParagraph(startOfCurrentParagraph, startOfLastParagrap h, CanCrossEditingBoundary)) { | 149 while (!inSameParagraph(startOfCurrentParagraph, startOfLastParagrap h, CanCrossEditingBoundary)) { |
144 // doApply() may operate on and remove the last paragraph of the selection from the document | 150 // doApply() may operate on and remove the last paragraph of the selection from the document |
145 // if it's in the same list item as startOfCurrentParagraph. Re turn early to avoid an | 151 // if it's in the same list item as startOfCurrentParagraph. Re turn early to avoid an |
146 // infinite loop and because there is no more work to be done. | 152 // infinite loop and because there is no more work to be done. |
147 // FIXME(<rdar://problem/5983974>): The endingSelection() may be incorrect here. Compute | 153 // FIXME(<rdar://problem/5983974>): The endingSelection() may be incorrect here. Compute |
148 // the new location of endOfSelection and use it as the end of t he new selection. | 154 // the new location of endOfSelection and use it as the end of t he new selection. |
149 if (!startOfLastParagraph.deepEquivalent().inDocument()) | 155 if (!startOfLastParagraph.deepEquivalent().inDocument()) |
150 return; | 156 return; |
151 setEndingSelection(startOfCurrentParagraph); | 157 setEndingSelection(startOfCurrentParagraph); |
152 | 158 |
153 // Save and restore endOfSelection and startOfLastParagraph when necessary | 159 // Save and restore endOfSelection and startOfLastParagraph when necessary |
154 // since moveParagraph and movePragraphWithClones can remove nod es. | 160 // since moveParagraph and movePragraphWithClones can remove nod es. |
155 // FIXME: This is an inefficient way to keep selection alive bec ause indexForVisiblePosition walks from | |
156 // the beginning of the document to the endOfSelection everytime this code is executed. | |
157 // But not using index is hard because there are so many ways we can lose selection inside doApplyForSingleParagraph. | |
158 doApplyForSingleParagraph(forceCreateList, listTag, currentSelec tion.get()); | 161 doApplyForSingleParagraph(forceCreateList, listTag, currentSelec tion.get()); |
159 if (endOfSelection.isNull() || endOfSelection.isOrphan() || star tOfLastParagraph.isNull() || startOfLastParagraph.isOrphan()) { | 162 if (endOfSelection.isNull() || endOfSelection.isOrphan() || star tOfLastParagraph.isNull() || startOfLastParagraph.isOrphan()) { |
160 endOfSelection = visiblePositionForIndex(indexForEndOfSelect ion, scope.get()); | 163 endOfSelection = visiblePositionForIndex(indexForEndOfSelect ion, scopeForEndOfSelection.get()); |
161 // If endOfSelection is null, then some contents have been d eleted from the document. | 164 // If endOfSelection is null, then some contents have been d eleted from the document. |
162 // This should never happen and if it did, exit early immedi ately because we've lost the loop invariant. | 165 // This should never happen and if it did, exit early immedi ately because we've lost the loop invariant. |
163 ASSERT(endOfSelection.isNotNull()); | 166 ASSERT(endOfSelection.isNotNull()); |
164 if (endOfSelection.isNull()) | 167 if (endOfSelection.isNull()) |
165 return; | 168 return; |
166 startOfLastParagraph = startOfParagraph(endOfSelection, CanS kipOverEditingBoundary); | 169 startOfLastParagraph = startOfParagraph(endOfSelection, CanS kipOverEditingBoundary); |
167 } | 170 } |
168 | 171 |
169 // Fetch the start of the selection after moving the first parag raph, | |
170 // because moving the paragraph will invalidate the original sta rt. | |
171 // We'll use the new start to restore the original selection aft er | |
172 // we modified all selected paragraphs. | |
173 if (startOfCurrentParagraph == startOfSelection) | |
174 startOfSelection = endingSelection().visibleStart(); | |
175 | |
176 startOfCurrentParagraph = startOfNextParagraph(endingSelection() .visibleStart()); | 172 startOfCurrentParagraph = startOfNextParagraph(endingSelection() .visibleStart()); |
177 } | 173 } |
178 setEndingSelection(endOfSelection); | 174 setEndingSelection(endOfSelection); |
179 doApplyForSingleParagraph(forceCreateList, listTag, currentSelection .get()); | |
180 // Fetch the end of the selection, for the reason mentioned above. | |
181 if (endOfSelection.isNull() || endOfSelection.isOrphan()) { | |
182 endOfSelection = visiblePositionForIndex(indexForEndOfSelection, scope.get()); | |
183 if (endOfSelection.isNull()) | |
184 return; | |
185 } | |
186 setEndingSelection(VisibleSelection(startOfSelection, endOfSelection , endingSelection().isDirectional())); | |
187 return; | |
188 } | 175 } |
176 doApplyForSingleParagraph(forceCreateList, listTag, currentSelection.get ()); | |
177 // Fetch the end of the selection, for the reason mentioned above. | |
178 if (endOfSelection.isNull() || endOfSelection.isOrphan()) { | |
179 endOfSelection = visiblePositionForIndex(indexForEndOfSelection, sco peForEndOfSelection.get()); | |
180 if (endOfSelection.isNull()) | |
181 return; | |
182 } | |
183 if (startOfSelection.isNull() || startOfSelection.isOrphan()) { | |
184 startOfSelection = visiblePositionForIndex(indexForStartOfSelection, scopeForStartOfSelection.get()); | |
185 if (startOfSelection.isNull()) | |
186 return; | |
187 } | |
188 setEndingSelection(VisibleSelection(startOfSelection, endOfSelection, en dingSelection().isDirectional())); | |
189 return; | |
189 } | 190 } |
190 | 191 |
191 doApplyForSingleParagraph(false, listTag, endingSelection().firstRange().get ()); | 192 doApplyForSingleParagraph(false, listTag, endingSelection().firstRange().get ()); |
192 } | 193 } |
193 | 194 |
194 void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const Qu alifiedName& listTag, Range* currentSelection) | 195 void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const Qu alifiedName& listTag, Range* currentSelection) |
195 { | 196 { |
196 // FIXME: This will produce unexpected results for a selection that starts j ust before a | 197 // FIXME: This will produce unexpected results for a selection that starts j ust before a |
197 // table and ends inside the first cell, selectionForParagraphIteration shou ld probably | 198 // table and ends inside the first cell, selectionForParagraphIteration shou ld probably |
198 // be renamed and deployed inside setEndingSelection(). | 199 // be renamed and deployed inside setEndingSelection(). |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
386 start = startOfParagraph(originalStart, CanSkipOverEditingBoundary); | 387 start = startOfParagraph(originalStart, CanSkipOverEditingBoundary); |
387 end = endOfParagraph(start, CanSkipOverEditingBoundary); | 388 end = endOfParagraph(start, CanSkipOverEditingBoundary); |
388 } | 389 } |
389 } | 390 } |
390 | 391 |
391 moveParagraph(start, end, positionBeforeNode(placeholder.get()), true); | 392 moveParagraph(start, end, positionBeforeNode(placeholder.get()), true); |
392 | 393 |
393 if (listElement) | 394 if (listElement) |
394 return mergeWithNeighboringLists(listElement); | 395 return mergeWithNeighboringLists(listElement); |
395 | 396 |
396 if (canMergeLists(previousList, nextList)) | 397 if (canMergeLists(previousList, nextList)) { |
397 mergeIdenticalElements(previousList, nextList); | 398 mergeIdenticalElements(previousList, nextList); |
399 document().updateLayoutIgnorePendingStylesheets(); | |
leviw_travelin_and_unemployed
2013/12/18 21:39:42
Why?
| |
400 } | |
398 | 401 |
399 return listElement; | 402 return listElement; |
400 } | 403 } |
401 | 404 |
402 } | 405 } |
OLD | NEW |