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

Side by Side Diff: Source/core/editing/InsertListCommand.cpp

Issue 182383012: Have positionInParentBeforeNode() / positionInParentAfterNode() take a reference (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase Created 6 years, 9 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 | Annotate | Revision Log
OLDNEW
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 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 // the new location of endOfSelection and use it as the end of t he new selection. 149 // the new location of endOfSelection and use it as the end of t he new selection.
150 if (!startOfLastParagraph.deepEquivalent().inDocument()) 150 if (!startOfLastParagraph.deepEquivalent().inDocument())
151 return; 151 return;
152 setEndingSelection(startOfCurrentParagraph); 152 setEndingSelection(startOfCurrentParagraph);
153 153
154 // Save and restore endOfSelection and startOfLastParagraph when necessary 154 // Save and restore endOfSelection and startOfLastParagraph when necessary
155 // since moveParagraph and movePragraphWithClones can remove nod es. 155 // since moveParagraph and movePragraphWithClones can remove nod es.
156 // FIXME: This is an inefficient way to keep selection alive bec ause indexForVisiblePosition walks from 156 // FIXME: This is an inefficient way to keep selection alive bec ause indexForVisiblePosition walks from
157 // the beginning of the document to the endOfSelection everytime this code is executed. 157 // the beginning of the document to the endOfSelection everytime this code is executed.
158 // But not using index is hard because there are so many ways we can lose selection inside doApplyForSingleParagraph. 158 // But not using index is hard because there are so many ways we can lose selection inside doApplyForSingleParagraph.
159 doApplyForSingleParagraph(forceCreateList, listTag, currentSelec tion.get()); 159 doApplyForSingleParagraph(forceCreateList, listTag, *currentSele ction);
160 if (endOfSelection.isNull() || endOfSelection.isOrphan() || star tOfLastParagraph.isNull() || startOfLastParagraph.isOrphan()) { 160 if (endOfSelection.isNull() || endOfSelection.isOrphan() || star tOfLastParagraph.isNull() || startOfLastParagraph.isOrphan()) {
161 endOfSelection = visiblePositionForIndex(indexForEndOfSelect ion, scope.get()); 161 endOfSelection = visiblePositionForIndex(indexForEndOfSelect ion, scope.get());
162 // If endOfSelection is null, then some contents have been d eleted from the document. 162 // If endOfSelection is null, then some contents have been d eleted from the document.
163 // This should never happen and if it did, exit early immedi ately because we've lost the loop invariant. 163 // This should never happen and if it did, exit early immedi ately because we've lost the loop invariant.
164 ASSERT(endOfSelection.isNotNull()); 164 ASSERT(endOfSelection.isNotNull());
165 if (endOfSelection.isNull()) 165 if (endOfSelection.isNull())
166 return; 166 return;
167 startOfLastParagraph = startOfParagraph(endOfSelection, CanS kipOverEditingBoundary); 167 startOfLastParagraph = startOfParagraph(endOfSelection, CanS kipOverEditingBoundary);
168 } 168 }
169 169
170 // Fetch the start of the selection after moving the first parag raph, 170 // Fetch the start of the selection after moving the first parag raph,
171 // because moving the paragraph will invalidate the original sta rt. 171 // because moving the paragraph will invalidate the original sta rt.
172 // We'll use the new start to restore the original selection aft er 172 // We'll use the new start to restore the original selection aft er
173 // we modified all selected paragraphs. 173 // we modified all selected paragraphs.
174 if (startOfCurrentParagraph == startOfSelection) 174 if (startOfCurrentParagraph == startOfSelection)
175 startOfSelection = endingSelection().visibleStart(); 175 startOfSelection = endingSelection().visibleStart();
176 176
177 startOfCurrentParagraph = startOfNextParagraph(endingSelection() .visibleStart()); 177 startOfCurrentParagraph = startOfNextParagraph(endingSelection() .visibleStart());
178 } 178 }
179 setEndingSelection(endOfSelection); 179 setEndingSelection(endOfSelection);
180 doApplyForSingleParagraph(forceCreateList, listTag, currentSelection .get()); 180 doApplyForSingleParagraph(forceCreateList, listTag, *currentSelectio n);
181 // Fetch the end of the selection, for the reason mentioned above. 181 // Fetch the end of the selection, for the reason mentioned above.
182 if (endOfSelection.isNull() || endOfSelection.isOrphan()) { 182 if (endOfSelection.isNull() || endOfSelection.isOrphan()) {
183 endOfSelection = visiblePositionForIndex(indexForEndOfSelection, scope.get()); 183 endOfSelection = visiblePositionForIndex(indexForEndOfSelection, scope.get());
184 if (endOfSelection.isNull()) 184 if (endOfSelection.isNull())
185 return; 185 return;
186 } 186 }
187 setEndingSelection(VisibleSelection(startOfSelection, endOfSelection , endingSelection().isDirectional())); 187 setEndingSelection(VisibleSelection(startOfSelection, endOfSelection , endingSelection().isDirectional()));
188 return; 188 return;
189 } 189 }
190 } 190 }
191 191
192 doApplyForSingleParagraph(false, listTag, endingSelection().firstRange().get ()); 192 ASSERT(endingSelection().firstRange());
193 doApplyForSingleParagraph(false, listTag, *endingSelection().firstRange());
193 } 194 }
194 195
195 void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const Qu alifiedName& listTag, Range* currentSelection) 196 void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const Qu alifiedName& listTag, Range& currentSelection)
196 { 197 {
197 // FIXME: This will produce unexpected results for a selection that starts j ust before a 198 // FIXME: This will produce unexpected results for a selection that starts j ust before a
198 // table and ends inside the first cell, selectionForParagraphIteration shou ld probably 199 // table and ends inside the first cell, selectionForParagraphIteration shou ld probably
199 // be renamed and deployed inside setEndingSelection(). 200 // be renamed and deployed inside setEndingSelection().
200 Node* selectionNode = endingSelection().start().deprecatedNode(); 201 Node* selectionNode = endingSelection().start().deprecatedNode();
201 Node* listChildNode = enclosingListChild(selectionNode); 202 Node* listChildNode = enclosingListChild(selectionNode);
202 bool switchListType = false; 203 bool switchListType = false;
203 if (listChildNode) { 204 if (listChildNode) {
204 // Remove the list chlild. 205 // Remove the list chlild.
205 RefPtr<HTMLElement> listNode = enclosingList(listChildNode); 206 RefPtr<HTMLElement> listNode = enclosingList(listChildNode);
206 if (!listNode) { 207 if (!listNode) {
207 listNode = fixOrphanedListChild(listChildNode); 208 listNode = fixOrphanedListChild(listChildNode);
208 listNode = mergeWithNeighboringLists(listNode); 209 listNode = mergeWithNeighboringLists(listNode);
209 } 210 }
210 if (!listNode->hasTagName(listTag)) 211 if (!listNode->hasTagName(listTag))
211 // listChildNode will be removed from the list and a list of type m_ type will be created. 212 // listChildNode will be removed from the list and a list of type m_ type will be created.
212 switchListType = true; 213 switchListType = true;
213 214
214 // If the list is of the desired type, and we are not removing the list, then exit early. 215 // If the list is of the desired type, and we are not removing the list, then exit early.
215 if (!switchListType && forceCreateList) 216 if (!switchListType && forceCreateList)
216 return; 217 return;
217 218
218 // If the entire list is selected, then convert the whole list. 219 // If the entire list is selected, then convert the whole list.
219 if (switchListType && isNodeVisiblyContainedWithin(listNode.get(), curre ntSelection)) { 220 if (switchListType && isNodeVisiblyContainedWithin(*listNode, currentSel ection)) {
220 bool rangeStartIsInList = visiblePositionBeforeNode(listNode.get()) == VisiblePosition(currentSelection->startPosition()); 221 bool rangeStartIsInList = visiblePositionBeforeNode(*listNode) == Vi siblePosition(currentSelection.startPosition());
221 bool rangeEndIsInList = visiblePositionAfterNode(listNode.get()) == VisiblePosition(currentSelection->endPosition()); 222 bool rangeEndIsInList = visiblePositionAfterNode(*listNode) == Visib lePosition(currentSelection.endPosition());
222 223
223 RefPtr<HTMLElement> newList = createHTMLElement(document(), listTag) ; 224 RefPtr<HTMLElement> newList = createHTMLElement(document(), listTag) ;
224 insertNodeBefore(newList, listNode); 225 insertNodeBefore(newList, listNode);
225 226
226 Node* firstChildInList = enclosingListChild(VisiblePosition(firstPos itionInNode(listNode.get())).deepEquivalent().deprecatedNode(), listNode.get()); 227 Node* firstChildInList = enclosingListChild(VisiblePosition(firstPos itionInNode(listNode.get())).deepEquivalent().deprecatedNode(), listNode.get());
227 Node* outerBlock = firstChildInList && firstChildInList->isBlockFlow Element() ? firstChildInList : listNode.get(); 228 Node* outerBlock = firstChildInList && firstChildInList->isBlockFlow Element() ? firstChildInList : listNode.get();
228 229
229 moveParagraphWithClones(VisiblePosition(firstPositionInNode(listNode .get())), VisiblePosition(lastPositionInNode(listNode.get())), newList.get(), ou terBlock); 230 moveParagraphWithClones(VisiblePosition(firstPositionInNode(listNode .get())), VisiblePosition(lastPositionInNode(listNode.get())), newList.get(), ou terBlock);
230 231
231 // Manually remove listNode because moveParagraphWithClones sometime s leaves it behind in the document. 232 // Manually remove listNode because moveParagraphWithClones sometime s leaves it behind in the document.
232 // See the bug 33668 and editing/execCommand/insert-list-orphaned-it em-with-nested-lists.html. 233 // See the bug 33668 and editing/execCommand/insert-list-orphaned-it em-with-nested-lists.html.
233 // FIXME: This might be a bug in moveParagraphWithClones or deleteSe lection. 234 // FIXME: This might be a bug in moveParagraphWithClones or deleteSe lection.
234 if (listNode && listNode->inDocument()) 235 if (listNode && listNode->inDocument())
235 removeNode(listNode); 236 removeNode(listNode);
236 237
237 newList = mergeWithNeighboringLists(newList); 238 newList = mergeWithNeighboringLists(newList);
238 239
239 // Restore the start and the end of current selection if they starte d inside listNode 240 // Restore the start and the end of current selection if they starte d inside listNode
240 // because moveParagraphWithClones could have removed them. 241 // because moveParagraphWithClones could have removed them.
241 if (rangeStartIsInList && newList) 242 if (rangeStartIsInList && newList)
242 currentSelection->setStart(newList, 0, IGNORE_EXCEPTION); 243 currentSelection.setStart(newList, 0, IGNORE_EXCEPTION);
243 if (rangeEndIsInList && newList) 244 if (rangeEndIsInList && newList)
244 currentSelection->setEnd(newList, lastOffsetInNode(newList.get() ), IGNORE_EXCEPTION); 245 currentSelection.setEnd(newList, lastOffsetInNode(newList.get()) , IGNORE_EXCEPTION);
245 246
246 setEndingSelection(VisiblePosition(firstPositionInNode(newList.get() ))); 247 setEndingSelection(VisiblePosition(firstPositionInNode(newList.get() )));
247 248
248 return; 249 return;
249 } 250 }
250 251
251 unlistifyParagraph(endingSelection().visibleStart(), listNode.get(), lis tChildNode); 252 unlistifyParagraph(endingSelection().visibleStart(), listNode.get(), lis tChildNode);
252 } 253 }
253 254
254 if (!listChildNode || switchListType || forceCreateList) 255 if (!listChildNode || switchListType || forceCreateList)
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 368
368 // Insert the list at a position visually equivalent to start of the 369 // Insert the list at a position visually equivalent to start of the
369 // paragraph that is being moved into the list. 370 // paragraph that is being moved into the list.
370 // Try to avoid inserting it somewhere where it will be surrounded by 371 // Try to avoid inserting it somewhere where it will be surrounded by
371 // inline ancestors of start, since it is easier for editing to produce 372 // inline ancestors of start, since it is easier for editing to produce
372 // clean markup when inline elements are pushed down as far as possible. 373 // clean markup when inline elements are pushed down as far as possible.
373 Position insertionPos(start.deepEquivalent().upstream()); 374 Position insertionPos(start.deepEquivalent().upstream());
374 // Also avoid the containing list item. 375 // Also avoid the containing list item.
375 Node* listChild = enclosingListChild(insertionPos.deprecatedNode()); 376 Node* listChild = enclosingListChild(insertionPos.deprecatedNode());
376 if (listChild && listChild->hasTagName(liTag)) 377 if (listChild && listChild->hasTagName(liTag))
377 insertionPos = positionInParentBeforeNode(listChild); 378 insertionPos = positionInParentBeforeNode(*listChild);
378 379
379 insertNodeAt(listElement, insertionPos); 380 insertNodeAt(listElement, insertionPos);
380 381
381 // We inserted the list at the start of the content we're about to move 382 // We inserted the list at the start of the content we're about to move
382 // Update the start of content, so we don't try to move the list into it self. bug 19066 383 // Update the start of content, so we don't try to move the list into it self. bug 19066
383 // Layout is necessary since start's node's inline renderers may have be en destroyed by the insertion 384 // Layout is necessary since start's node's inline renderers may have be en destroyed by the insertion
384 // The end of the content may have changed after the insertion and layou t so update it as well. 385 // The end of the content may have changed after the insertion and layou t so update it as well.
385 if (insertionPos == start.deepEquivalent()) { 386 if (insertionPos == start.deepEquivalent()) {
386 listElement->document().updateLayoutIgnorePendingStylesheets(); 387 listElement->document().updateLayoutIgnorePendingStylesheets();
387 start = startOfParagraph(originalStart, CanSkipOverEditingBoundary); 388 start = startOfParagraph(originalStart, CanSkipOverEditingBoundary);
388 end = endOfParagraph(start, CanSkipOverEditingBoundary); 389 end = endOfParagraph(start, CanSkipOverEditingBoundary);
389 } 390 }
390 } 391 }
391 392
392 moveParagraph(start, end, VisiblePosition(positionBeforeNode(placeholder.get ())), true); 393 moveParagraph(start, end, VisiblePosition(positionBeforeNode(placeholder.get ())), true);
393 394
394 if (listElement) 395 if (listElement)
395 return mergeWithNeighboringLists(listElement); 396 return mergeWithNeighboringLists(listElement);
396 397
397 if (canMergeLists(previousList, nextList)) 398 if (canMergeLists(previousList, nextList))
398 mergeIdenticalElements(previousList, nextList); 399 mergeIdenticalElements(previousList, nextList);
399 400
400 return listElement; 401 return listElement;
401 } 402 }
402 403
403 } 404 }
OLDNEW
« no previous file with comments | « Source/core/editing/InsertListCommand.h ('k') | Source/core/editing/InsertParagraphSeparatorCommand.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698