| 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 | 48 |
| 49 PassRefPtr<HTMLElement> InsertListCommand::insertList(Document& document, Type t
ype) | 49 PassRefPtr<HTMLElement> InsertListCommand::insertList(Document& document, Type t
ype) |
| 50 { | 50 { |
| 51 RefPtr<InsertListCommand> insertCommand = create(document, type); | 51 RefPtr<InsertListCommand> insertCommand = create(document, type); |
| 52 insertCommand->apply(); | 52 insertCommand->apply(); |
| 53 return insertCommand->m_listElement; | 53 return insertCommand->m_listElement; |
| 54 } | 54 } |
| 55 | 55 |
| 56 HTMLElement* InsertListCommand::fixOrphanedListChild(Node* node) | 56 HTMLElement* InsertListCommand::fixOrphanedListChild(Node* node) |
| 57 { | 57 { |
| 58 RefPtr<HTMLElement> listElement = createUnorderedListElement(&document()); | 58 RefPtr<HTMLElement> listElement = createUnorderedListElement(document()); |
| 59 insertNodeBefore(listElement, node); | 59 insertNodeBefore(listElement, node); |
| 60 removeNode(node); | 60 removeNode(node); |
| 61 appendNode(node, listElement); | 61 appendNode(node, listElement); |
| 62 m_listElement = listElement; | 62 m_listElement = listElement; |
| 63 return listElement.get(); | 63 return listElement.get(); |
| 64 } | 64 } |
| 65 | 65 |
| 66 PassRefPtr<HTMLElement> InsertListCommand::mergeWithNeighboringLists(PassRefPtr<
HTMLElement> passedList) | 66 PassRefPtr<HTMLElement> InsertListCommand::mergeWithNeighboringLists(PassRefPtr<
HTMLElement> passedList) |
| 67 { | 67 { |
| 68 RefPtr<HTMLElement> list = passedList; | 68 RefPtr<HTMLElement> list = passedList; |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 | 208 |
| 209 // If the list is of the desired type, and we are not removing the list,
then exit early. | 209 // If the list is of the desired type, and we are not removing the list,
then exit early. |
| 210 if (!switchListType && forceCreateList) | 210 if (!switchListType && forceCreateList) |
| 211 return; | 211 return; |
| 212 | 212 |
| 213 // If the entire list is selected, then convert the whole list. | 213 // If the entire list is selected, then convert the whole list. |
| 214 if (switchListType && isNodeVisiblyContainedWithin(listNode.get(), curre
ntSelection)) { | 214 if (switchListType && isNodeVisiblyContainedWithin(listNode.get(), curre
ntSelection)) { |
| 215 bool rangeStartIsInList = visiblePositionBeforeNode(listNode.get())
== currentSelection->startPosition(); | 215 bool rangeStartIsInList = visiblePositionBeforeNode(listNode.get())
== currentSelection->startPosition(); |
| 216 bool rangeEndIsInList = visiblePositionAfterNode(listNode.get()) ==
currentSelection->endPosition(); | 216 bool rangeEndIsInList = visiblePositionAfterNode(listNode.get()) ==
currentSelection->endPosition(); |
| 217 | 217 |
| 218 RefPtr<HTMLElement> newList = createHTMLElement(&document(), listTag
); | 218 RefPtr<HTMLElement> newList = createHTMLElement(document(), listTag)
; |
| 219 insertNodeBefore(newList, listNode); | 219 insertNodeBefore(newList, listNode); |
| 220 | 220 |
| 221 Node* firstChildInList = enclosingListChild(VisiblePosition(firstPos
itionInNode(listNode.get())).deepEquivalent().deprecatedNode(), listNode.get()); | 221 Node* firstChildInList = enclosingListChild(VisiblePosition(firstPos
itionInNode(listNode.get())).deepEquivalent().deprecatedNode(), listNode.get()); |
| 222 Node* outerBlock = firstChildInList->isBlockFlowElement() ? firstChi
ldInList : listNode.get(); | 222 Node* outerBlock = firstChildInList->isBlockFlowElement() ? firstChi
ldInList : listNode.get(); |
| 223 | 223 |
| 224 moveParagraphWithClones(firstPositionInNode(listNode.get()), lastPos
itionInNode(listNode.get()), newList.get(), outerBlock); | 224 moveParagraphWithClones(firstPositionInNode(listNode.get()), lastPos
itionInNode(listNode.get()), newList.get(), outerBlock); |
| 225 | 225 |
| 226 // Manually remove listNode because moveParagraphWithClones sometime
s leaves it behind in the document. | 226 // Manually remove listNode because moveParagraphWithClones sometime
s leaves it behind in the document. |
| 227 // See the bug 33668 and editing/execCommand/insert-list-orphaned-it
em-with-nested-lists.html. | 227 // See the bug 33668 and editing/execCommand/insert-list-orphaned-it
em-with-nested-lists.html. |
| 228 // FIXME: This might be a bug in moveParagraphWithClones or deleteSe
lection. | 228 // FIXME: This might be a bug in moveParagraphWithClones or deleteSe
lection. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 // A paragraph is visually a list item minus a list marker. The paragra
ph will be moved. | 265 // A paragraph is visually a list item minus a list marker. The paragra
ph will be moved. |
| 266 start = startOfParagraph(originalStart, CanSkipOverEditingBoundary); | 266 start = startOfParagraph(originalStart, CanSkipOverEditingBoundary); |
| 267 end = endOfParagraph(start, CanSkipOverEditingBoundary); | 267 end = endOfParagraph(start, CanSkipOverEditingBoundary); |
| 268 nextListChild = enclosingListChild(end.next().deepEquivalent().deprecate
dNode(), listNode); | 268 nextListChild = enclosingListChild(end.next().deepEquivalent().deprecate
dNode(), listNode); |
| 269 ASSERT(nextListChild != listChildNode); | 269 ASSERT(nextListChild != listChildNode); |
| 270 previousListChild = enclosingListChild(start.previous().deepEquivalent()
.deprecatedNode(), listNode); | 270 previousListChild = enclosingListChild(start.previous().deepEquivalent()
.deprecatedNode(), listNode); |
| 271 ASSERT(previousListChild != listChildNode); | 271 ASSERT(previousListChild != listChildNode); |
| 272 } | 272 } |
| 273 // When removing a list, we must always create a placeholder to act as a poi
nt of insertion | 273 // When removing a list, we must always create a placeholder to act as a poi
nt of insertion |
| 274 // for the list content being removed. | 274 // for the list content being removed. |
| 275 RefPtr<Element> placeholder = createBreakElement(&document()); | 275 RefPtr<Element> placeholder = createBreakElement(document()); |
| 276 RefPtr<Element> nodeToInsert = placeholder; | 276 RefPtr<Element> nodeToInsert = placeholder; |
| 277 // If the content of the list item will be moved into another list, put it i
n a list item | 277 // If the content of the list item will be moved into another list, put it i
n a list item |
| 278 // so that we don't create an orphaned list child. | 278 // so that we don't create an orphaned list child. |
| 279 if (enclosingList(listNode)) { | 279 if (enclosingList(listNode)) { |
| 280 nodeToInsert = createListItemElement(&document()); | 280 nodeToInsert = createListItemElement(document()); |
| 281 appendNode(placeholder, nodeToInsert); | 281 appendNode(placeholder, nodeToInsert); |
| 282 } | 282 } |
| 283 | 283 |
| 284 if (nextListChild && previousListChild) { | 284 if (nextListChild && previousListChild) { |
| 285 // We want to pull listChildNode out of listNode, and place it before ne
xtListChild | 285 // We want to pull listChildNode out of listNode, and place it before ne
xtListChild |
| 286 // and after previousListChild, so we split listNode and insert it betwe
en the two lists. | 286 // and after previousListChild, so we split listNode and insert it betwe
en the two lists. |
| 287 // But to split listNode, we must first split ancestors of listChildNode
between it and listNode, | 287 // But to split listNode, we must first split ancestors of listChildNode
between it and listNode, |
| 288 // if any exist. | 288 // if any exist. |
| 289 // FIXME: We appear to split at nextListChild as opposed to listChildNod
e so that when we remove | 289 // FIXME: We appear to split at nextListChild as opposed to listChildNod
e so that when we remove |
| 290 // listChildNode below in moveParagraphs, previousListChild will be remo
ved along with it if it is | 290 // listChildNode below in moveParagraphs, previousListChild will be remo
ved along with it if it is |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 | 327 |
| 328 PassRefPtr<HTMLElement> InsertListCommand::listifyParagraph(const VisiblePositio
n& originalStart, const QualifiedName& listTag) | 328 PassRefPtr<HTMLElement> InsertListCommand::listifyParagraph(const VisiblePositio
n& originalStart, const QualifiedName& listTag) |
| 329 { | 329 { |
| 330 VisiblePosition start = startOfParagraph(originalStart, CanSkipOverEditingBo
undary); | 330 VisiblePosition start = startOfParagraph(originalStart, CanSkipOverEditingBo
undary); |
| 331 VisiblePosition end = endOfParagraph(start, CanSkipOverEditingBoundary); | 331 VisiblePosition end = endOfParagraph(start, CanSkipOverEditingBoundary); |
| 332 | 332 |
| 333 if (start.isNull() || end.isNull()) | 333 if (start.isNull() || end.isNull()) |
| 334 return 0; | 334 return 0; |
| 335 | 335 |
| 336 // Check for adjoining lists. | 336 // Check for adjoining lists. |
| 337 RefPtr<HTMLElement> listItemElement = createListItemElement(&document()); | 337 RefPtr<HTMLElement> listItemElement = createListItemElement(document()); |
| 338 RefPtr<HTMLElement> placeholder = createBreakElement(&document()); | 338 RefPtr<HTMLElement> placeholder = createBreakElement(document()); |
| 339 appendNode(placeholder, listItemElement); | 339 appendNode(placeholder, listItemElement); |
| 340 | 340 |
| 341 // Place list item into adjoining lists. | 341 // Place list item into adjoining lists. |
| 342 Element* previousList = adjacentEnclosingList(start.deepEquivalent(), start.
previous(CannotCrossEditingBoundary), listTag); | 342 Element* previousList = adjacentEnclosingList(start.deepEquivalent(), start.
previous(CannotCrossEditingBoundary), listTag); |
| 343 Element* nextList = adjacentEnclosingList(start.deepEquivalent(), end.next(C
annotCrossEditingBoundary), listTag); | 343 Element* nextList = adjacentEnclosingList(start.deepEquivalent(), end.next(C
annotCrossEditingBoundary), listTag); |
| 344 RefPtr<HTMLElement> listElement; | 344 RefPtr<HTMLElement> listElement; |
| 345 if (previousList) | 345 if (previousList) |
| 346 appendNode(listItemElement, previousList); | 346 appendNode(listItemElement, previousList); |
| 347 else if (nextList) | 347 else if (nextList) |
| 348 insertNodeAt(listItemElement, positionBeforeNode(nextList)); | 348 insertNodeAt(listItemElement, positionBeforeNode(nextList)); |
| 349 else { | 349 else { |
| 350 // Create the list. | 350 // Create the list. |
| 351 listElement = createHTMLElement(&document(), listTag); | 351 listElement = createHTMLElement(document(), listTag); |
| 352 appendNode(listItemElement, listElement); | 352 appendNode(listItemElement, listElement); |
| 353 | 353 |
| 354 if (start == end && isBlock(start.deepEquivalent().deprecatedNode())) { | 354 if (start == end && isBlock(start.deepEquivalent().deprecatedNode())) { |
| 355 // Inserting the list into an empty paragraph that isn't held open | 355 // Inserting the list into an empty paragraph that isn't held open |
| 356 // by a br or a '\n', will invalidate start and end. Insert | 356 // by a br or a '\n', will invalidate start and end. Insert |
| 357 // a placeholder and then recompute start and end. | 357 // a placeholder and then recompute start and end. |
| 358 RefPtr<Node> placeholder = insertBlockPlaceholder(start.deepEquivale
nt()); | 358 RefPtr<Node> placeholder = insertBlockPlaceholder(start.deepEquivale
nt()); |
| 359 start = positionBeforeNode(placeholder.get()); | 359 start = positionBeforeNode(placeholder.get()); |
| 360 end = start; | 360 end = start; |
| 361 } | 361 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 389 if (listElement) | 389 if (listElement) |
| 390 return mergeWithNeighboringLists(listElement); | 390 return mergeWithNeighboringLists(listElement); |
| 391 | 391 |
| 392 if (canMergeLists(previousList, nextList)) | 392 if (canMergeLists(previousList, nextList)) |
| 393 mergeIdenticalElements(previousList, nextList); | 393 mergeIdenticalElements(previousList, nextList); |
| 394 | 394 |
| 395 return listElement; | 395 return listElement; |
| 396 } | 396 } |
| 397 | 397 |
| 398 } | 398 } |
| OLD | NEW |