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 |