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

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

Issue 1695153002: Editing: Make the |EditingState*| argument of CompositeEditCommand::removeNode mandatory. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: ; Created 4 years, 10 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
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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 using namespace HTMLNames; 43 using namespace HTMLNames;
44 44
45 static Node* enclosingListChild(Node* node, Node* listNode) 45 static Node* enclosingListChild(Node* node, Node* listNode)
46 { 46 {
47 Node* listChild = enclosingListChild(node); 47 Node* listChild = enclosingListChild(node);
48 while (listChild && enclosingList(listChild) != listNode) 48 while (listChild && enclosingList(listChild) != listNode)
49 listChild = enclosingListChild(listChild->parentNode()); 49 listChild = enclosingListChild(listChild->parentNode());
50 return listChild; 50 return listChild;
51 } 51 }
52 52
53 HTMLUListElement* InsertListCommand::fixOrphanedListChild(Node* node) 53 HTMLUListElement* InsertListCommand::fixOrphanedListChild(Node* node, EditingSta te* editingState)
54 { 54 {
55 RefPtrWillBeRawPtr<HTMLUListElement> listElement = HTMLUListElement::create( document()); 55 RefPtrWillBeRawPtr<HTMLUListElement> listElement = HTMLUListElement::create( document());
56 insertNodeBefore(listElement, node); 56 insertNodeBefore(listElement, node, editingState);
57 removeNode(node); 57 if (editingState->isAborted())
58 appendNode(node, listElement); 58 return nullptr;
59 removeNode(node, editingState);
60 if (editingState->isAborted())
61 return nullptr;
62 appendNode(node, listElement, editingState);
63 if (editingState->isAborted())
64 return nullptr;
59 return listElement.get(); 65 return listElement.get();
60 } 66 }
61 67
62 PassRefPtrWillBeRawPtr<HTMLElement> InsertListCommand::mergeWithNeighboringLists (PassRefPtrWillBeRawPtr<HTMLElement> passedList) 68 PassRefPtrWillBeRawPtr<HTMLElement> InsertListCommand::mergeWithNeighboringLists (PassRefPtrWillBeRawPtr<HTMLElement> passedList, EditingState* editingState)
63 { 69 {
64 RefPtrWillBeRawPtr<HTMLElement> list = passedList; 70 RefPtrWillBeRawPtr<HTMLElement> list = passedList;
65 Element* previousList = ElementTraversal::previousSibling(*list); 71 Element* previousList = ElementTraversal::previousSibling(*list);
66 if (canMergeLists(previousList, list.get())) 72 if (canMergeLists(previousList, list.get())) {
67 mergeIdenticalElements(previousList, list); 73 mergeIdenticalElements(previousList, list, editingState);
74 if (editingState->isAborted())
75 return nullptr;
76 }
68 77
69 if (!list) 78 if (!list)
70 return nullptr; 79 return nullptr;
71 80
72 Element* nextSibling = ElementTraversal::nextSibling(*list); 81 Element* nextSibling = ElementTraversal::nextSibling(*list);
73 if (!nextSibling || !nextSibling->isHTMLElement()) 82 if (!nextSibling || !nextSibling->isHTMLElement())
74 return list.release(); 83 return list.release();
75 84
76 RefPtrWillBeRawPtr<HTMLElement> nextList = toHTMLElement(nextSibling); 85 RefPtrWillBeRawPtr<HTMLElement> nextList = toHTMLElement(nextSibling);
77 if (canMergeLists(list.get(), nextList.get())) { 86 if (canMergeLists(list.get(), nextList.get())) {
78 mergeIdenticalElements(list, nextList); 87 mergeIdenticalElements(list, nextList, editingState);
88 if (editingState->isAborted())
89 return nullptr;
79 return nextList.release(); 90 return nextList.release();
80 } 91 }
81 return list.release(); 92 return list.release();
82 } 93 }
83 94
84 bool InsertListCommand::selectionHasListOfType(const VisibleSelection& selection , const HTMLQualifiedName& listTag) 95 bool InsertListCommand::selectionHasListOfType(const VisibleSelection& selection , const HTMLQualifiedName& listTag)
85 { 96 {
86 VisiblePosition start = selection.visibleStart(); 97 VisiblePosition start = selection.visibleStart();
87 98
88 if (!enclosingList(start.deepEquivalent().anchorNode())) 99 if (!enclosingList(start.deepEquivalent().anchorNode()))
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 // out from |listElement|. 241 // out from |listElement|.
231 return false; 242 return false;
232 } 243 }
233 if (!listElement->parentNode()->hasEditableStyle()) { 244 if (!listElement->parentNode()->hasEditableStyle()) {
234 // Since parent of |listElement| is uneditable, we can not remov e 245 // Since parent of |listElement| is uneditable, we can not remov e
235 // |listElement| for switching list type neither unlistify. 246 // |listElement| for switching list type neither unlistify.
236 return false; 247 return false;
237 } 248 }
238 } 249 }
239 if (!listElement) { 250 if (!listElement) {
240 listElement = fixOrphanedListChild(listChildNode); 251 listElement = fixOrphanedListChild(listChildNode, editingState);
241 listElement = mergeWithNeighboringLists(listElement); 252 if (editingState->isAborted())
253 return false;
254 listElement = mergeWithNeighboringLists(listElement, editingState);
255 if (editingState->isAborted())
256 return false;
242 } 257 }
243 ASSERT(listElement->hasEditableStyle()); 258 ASSERT(listElement->hasEditableStyle());
244 ASSERT(listElement->parentNode()->hasEditableStyle()); 259 ASSERT(listElement->parentNode()->hasEditableStyle());
245 if (!listElement->hasTagName(listTag)) { 260 if (!listElement->hasTagName(listTag)) {
246 // |listChildNode| will be removed from the list and a list of type 261 // |listChildNode| will be removed from the list and a list of type
247 // |m_type| will be created. 262 // |m_type| will be created.
248 switchListType = true; 263 switchListType = true;
249 } 264 }
250 265
251 // If the list is of the desired type, and we are not removing the list, 266 // If the list is of the desired type, and we are not removing the list,
252 // then exit early. 267 // then exit early.
253 if (!switchListType && forceCreateList) 268 if (!switchListType && forceCreateList)
254 return true; 269 return true;
255 270
256 // If the entire list is selected, then convert the whole list. 271 // If the entire list is selected, then convert the whole list.
257 if (switchListType && isNodeVisiblyContainedWithin(*listElement, current Selection)) { 272 if (switchListType && isNodeVisiblyContainedWithin(*listElement, current Selection)) {
258 bool rangeStartIsInList = visiblePositionBeforeNode(*listElement).de epEquivalent() == createVisiblePosition(currentSelection.startPosition()).deepEq uivalent(); 273 bool rangeStartIsInList = visiblePositionBeforeNode(*listElement).de epEquivalent() == createVisiblePosition(currentSelection.startPosition()).deepEq uivalent();
259 bool rangeEndIsInList = visiblePositionAfterNode(*listElement).deepE quivalent() == createVisiblePosition(currentSelection.endPosition()).deepEquival ent(); 274 bool rangeEndIsInList = visiblePositionAfterNode(*listElement).deepE quivalent() == createVisiblePosition(currentSelection.endPosition()).deepEquival ent();
260 275
261 RefPtrWillBeRawPtr<HTMLElement> newList = createHTMLElement(document (), listTag); 276 RefPtrWillBeRawPtr<HTMLElement> newList = createHTMLElement(document (), listTag);
262 insertNodeBefore(newList, listElement); 277 insertNodeBefore(newList, listElement, editingState);
278 if (editingState->isAborted())
279 return false;
263 280
264 Node* firstChildInList = enclosingListChild(createVisiblePosition(fi rstPositionInNode(listElement.get())).deepEquivalent().anchorNode(), listElement .get()); 281 Node* firstChildInList = enclosingListChild(createVisiblePosition(fi rstPositionInNode(listElement.get())).deepEquivalent().anchorNode(), listElement .get());
265 Element* outerBlock = firstChildInList && isBlockFlowElement(*firstC hildInList) ? toElement(firstChildInList) : listElement.get(); 282 Element* outerBlock = firstChildInList && isBlockFlowElement(*firstC hildInList) ? toElement(firstChildInList) : listElement.get();
266 283
267 moveParagraphWithClones(createVisiblePosition(firstPositionInNode(li stElement.get())), createVisiblePosition(lastPositionInNode(listElement.get())), newList.get(), outerBlock); 284 moveParagraphWithClones(createVisiblePosition(firstPositionInNode(li stElement.get())), createVisiblePosition(lastPositionInNode(listElement.get())), newList.get(), outerBlock, editingState);
285 if (editingState->isAborted())
286 return false;
268 287
269 // Manually remove listNode because moveParagraphWithClones sometime s leaves it behind in the document. 288 // Manually remove listNode because moveParagraphWithClones sometime s leaves it behind in the document.
270 // See the bug 33668 and editing/execCommand/insert-list-orphaned-it em-with-nested-lists.html. 289 // See the bug 33668 and editing/execCommand/insert-list-orphaned-it em-with-nested-lists.html.
271 // FIXME: This might be a bug in moveParagraphWithClones or deleteSe lection. 290 // FIXME: This might be a bug in moveParagraphWithClones or deleteSe lection.
272 if (listElement && listElement->inDocument()) 291 if (listElement && listElement->inDocument()) {
273 removeNode(listElement); 292 removeNode(listElement, editingState);
293 if (editingState->isAborted())
294 return false;
295 }
274 296
275 newList = mergeWithNeighboringLists(newList); 297 newList = mergeWithNeighboringLists(newList, editingState);
298 if (editingState->isAborted())
299 return false;
276 300
277 // Restore the start and the end of current selection if they starte d inside listNode 301 // Restore the start and the end of current selection if they starte d inside listNode
278 // because moveParagraphWithClones could have removed them. 302 // because moveParagraphWithClones could have removed them.
279 if (rangeStartIsInList && newList) 303 if (rangeStartIsInList && newList)
280 currentSelection.setStart(newList, 0, IGNORE_EXCEPTION); 304 currentSelection.setStart(newList, 0, IGNORE_EXCEPTION);
281 if (rangeEndIsInList && newList) 305 if (rangeEndIsInList && newList)
282 currentSelection.setEnd(newList, lastOffsetInNode(newList.get()) , IGNORE_EXCEPTION); 306 currentSelection.setEnd(newList, lastOffsetInNode(newList.get()) , IGNORE_EXCEPTION);
283 307
284 setEndingSelection(createVisiblePosition(firstPositionInNode(newList .get()))); 308 setEndingSelection(createVisiblePosition(firstPositionInNode(newList .get())));
285 309
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 else 418 else
395 insertNodeAt(listItemElement, Position::beforeNode(nextList), editin gState); 419 insertNodeAt(listItemElement, Position::beforeNode(nextList), editin gState);
396 if (editingState->isAborted()) 420 if (editingState->isAborted())
397 return; 421 return;
398 422
399 moveParagraphOverPositionIntoEmptyListItem(start, listItemElement, editi ngState); 423 moveParagraphOverPositionIntoEmptyListItem(start, listItemElement, editi ngState);
400 if (editingState->isAborted()) 424 if (editingState->isAborted())
401 return; 425 return;
402 426
403 if (canMergeLists(previousList, nextList)) 427 if (canMergeLists(previousList, nextList))
404 mergeIdenticalElements(previousList, nextList); 428 mergeIdenticalElements(previousList, nextList, editingState);
405 429
406 return; 430 return;
407 } 431 }
408 432
409 // Create new list element. 433 // Create new list element.
410 434
411 // Inserting the list into an empty paragraph that isn't held open 435 // Inserting the list into an empty paragraph that isn't held open
412 // by a br or a '\n', will invalidate start and end. Insert 436 // by a br or a '\n', will invalidate start and end. Insert
413 // a placeholder and then recompute start and end. 437 // a placeholder and then recompute start and end.
414 Position startPos = start.deepEquivalent(); 438 Position startPos = start.deepEquivalent();
(...skipping 26 matching lines...) Expand all
441 // Update the start of content, so we don't try to move the list into itself . bug 19066 465 // Update the start of content, so we don't try to move the list into itself . bug 19066
442 // Layout is necessary since start's node's inline layoutObjects may have be en destroyed by the insertion 466 // Layout is necessary since start's node's inline layoutObjects may have be en destroyed by the insertion
443 // The end of the content may have changed after the insertion and layout so update it as well. 467 // The end of the content may have changed after the insertion and layout so update it as well.
444 if (insertionPos == startPos) 468 if (insertionPos == startPos)
445 moveParagraphOverPositionIntoEmptyListItem(originalStart, listItemElemen t, editingState); 469 moveParagraphOverPositionIntoEmptyListItem(originalStart, listItemElemen t, editingState);
446 else 470 else
447 moveParagraphOverPositionIntoEmptyListItem(createVisiblePosition(startPo s), listItemElement, editingState); 471 moveParagraphOverPositionIntoEmptyListItem(createVisiblePosition(startPo s), listItemElement, editingState);
448 if (editingState->isAborted()) 472 if (editingState->isAborted())
449 return; 473 return;
450 474
451 mergeWithNeighboringLists(listElement); 475 mergeWithNeighboringLists(listElement, editingState);
452 } 476 }
453 477
454 void InsertListCommand::moveParagraphOverPositionIntoEmptyListItem(const Visible Position& pos, PassRefPtrWillBeRawPtr<HTMLLIElement> listItemElement, EditingSta te* editingState) 478 void InsertListCommand::moveParagraphOverPositionIntoEmptyListItem(const Visible Position& pos, PassRefPtrWillBeRawPtr<HTMLLIElement> listItemElement, EditingSta te* editingState)
455 { 479 {
456 ASSERT(!listItemElement->hasChildren()); 480 ASSERT(!listItemElement->hasChildren());
457 const RefPtrWillBeRawPtr<HTMLBRElement> placeholder = HTMLBRElement::create( document()); 481 const RefPtrWillBeRawPtr<HTMLBRElement> placeholder = HTMLBRElement::create( document());
458 appendNode(placeholder, listItemElement, editingState); 482 appendNode(placeholder, listItemElement, editingState);
459 if (editingState->isAborted()) 483 if (editingState->isAborted())
460 return; 484 return;
461 // Inserting list element and list item list may change start of pargraph 485 // Inserting list element and list item list may change start of pargraph
462 // to move. We calculate start of paragraph again. 486 // to move. We calculate start of paragraph again.
463 document().updateLayoutIgnorePendingStylesheets(); 487 document().updateLayoutIgnorePendingStylesheets();
464 const VisiblePosition& start = startOfParagraph(pos, CanSkipOverEditingBound ary); 488 const VisiblePosition& start = startOfParagraph(pos, CanSkipOverEditingBound ary);
465 const VisiblePosition& end = endOfParagraph(pos, CanSkipOverEditingBoundary) ; 489 const VisiblePosition& end = endOfParagraph(pos, CanSkipOverEditingBoundary) ;
466 moveParagraph(start, end, createVisiblePosition(positionBeforeNode(placehold er.get())), editingState, true); 490 moveParagraph(start, end, createVisiblePosition(positionBeforeNode(placehold er.get())), editingState, true);
467 } 491 }
468 492
469 DEFINE_TRACE(InsertListCommand) 493 DEFINE_TRACE(InsertListCommand)
470 { 494 {
471 CompositeEditCommand::trace(visitor); 495 CompositeEditCommand::trace(visitor);
472 } 496 }
473 497
474 } // namespace blink 498 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698