Chromium Code Reviews| 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; | |
| 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 listItemElement->document().updateLayoutIgnorePendingStylesheets(); | |
|
yosin_UTC9
2013/12/13 01:10:41
nit: Just |document()|, which is member function o
| |
| 400 } | |
| 398 | 401 |
| 399 return listElement; | 402 return listElement; |
| 400 } | 403 } |
| 401 | 404 |
| 402 } | 405 } |
| OLD | NEW |