OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2007, 2008 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 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 | 387 |
388 for (; node && node != pastLastNodeToMove; node = node->nextSibling()) | 388 for (; node && node != pastLastNodeToMove; node = node->nextSibling()) |
389 nodesToRemove.append(node); | 389 nodesToRemove.append(node); |
390 | 390 |
391 for (unsigned i = 0; i < nodesToRemove.size(); i++) { | 391 for (unsigned i = 0; i < nodesToRemove.size(); i++) { |
392 removeNode(nodesToRemove[i]); | 392 removeNode(nodesToRemove[i]); |
393 appendNode(nodesToRemove[i], newParent); | 393 appendNode(nodesToRemove[i], newParent); |
394 } | 394 } |
395 } | 395 } |
396 | 396 |
397 void CompositeEditCommand::updatePositionForNodeRemovalPreservingChildren(Positi
on& position, Node* node) | 397 void CompositeEditCommand::updatePositionForNodeRemovalPreservingChildren(Positi
on& position, Node& node) |
398 { | 398 { |
399 int offset = (position.anchorType() == Position::PositionIsOffsetInAnchor) ?
position.offsetInContainerNode() : 0; | 399 int offset = (position.anchorType() == Position::PositionIsOffsetInAnchor) ?
position.offsetInContainerNode() : 0; |
400 updatePositionForNodeRemoval(position, node); | 400 updatePositionForNodeRemoval(position, node); |
401 if (offset) | 401 if (offset) |
402 position.moveToOffset(offset); | 402 position.moveToOffset(offset); |
403 } | 403 } |
404 | 404 |
405 HTMLElement* CompositeEditCommand::replaceElementWithSpanPreservingChildrenAndAt
tributes(PassRefPtr<HTMLElement> node) | 405 HTMLElement* CompositeEditCommand::replaceElementWithSpanPreservingChildrenAndAt
tributes(PassRefPtr<HTMLElement> node) |
406 { | 406 { |
407 // It would also be possible to implement all of ReplaceNodeWithSpanCommand | 407 // It would also be possible to implement all of ReplaceNodeWithSpanCommand |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 return pos; | 512 return pos; |
513 | 513 |
514 switch (pos.anchorType()) { | 514 switch (pos.anchorType()) { |
515 case Position::PositionIsBeforeChildren: | 515 case Position::PositionIsBeforeChildren: |
516 case Position::PositionIsAfterChildren: | 516 case Position::PositionIsAfterChildren: |
517 ASSERT_NOT_REACHED(); | 517 ASSERT_NOT_REACHED(); |
518 return pos; | 518 return pos; |
519 case Position::PositionIsOffsetInAnchor: | 519 case Position::PositionIsOffsetInAnchor: |
520 break; | 520 break; |
521 case Position::PositionIsBeforeAnchor: | 521 case Position::PositionIsBeforeAnchor: |
522 return positionInParentBeforeNode(pos.anchorNode()); | 522 return positionInParentBeforeNode(*pos.anchorNode()); |
523 case Position::PositionIsAfterAnchor: | 523 case Position::PositionIsAfterAnchor: |
524 return positionInParentAfterNode(pos.anchorNode()); | 524 return positionInParentAfterNode(*pos.anchorNode()); |
525 } | 525 } |
526 | 526 |
527 Node* tabSpan = tabSpanNode(pos.containerNode()); | 527 Node* tabSpan = tabSpanNode(pos.containerNode()); |
| 528 ASSERT(tabSpan); |
528 | 529 |
529 if (pos.offsetInContainerNode() <= caretMinOffset(pos.containerNode())) | 530 if (pos.offsetInContainerNode() <= caretMinOffset(pos.containerNode())) |
530 return positionInParentBeforeNode(tabSpan); | 531 return positionInParentBeforeNode(*tabSpan); |
531 | 532 |
532 if (pos.offsetInContainerNode() >= caretMaxOffset(pos.containerNode())) | 533 if (pos.offsetInContainerNode() >= caretMaxOffset(pos.containerNode())) |
533 return positionInParentAfterNode(tabSpan); | 534 return positionInParentAfterNode(*tabSpan); |
534 | 535 |
535 splitTextNodeContainingElement(toText(pos.containerNode()), pos.offsetInCont
ainerNode()); | 536 splitTextNodeContainingElement(toText(pos.containerNode()), pos.offsetInCont
ainerNode()); |
536 return positionInParentBeforeNode(tabSpan); | 537 return positionInParentBeforeNode(*tabSpan); |
537 } | 538 } |
538 | 539 |
539 void CompositeEditCommand::insertNodeAtTabSpanPosition(PassRefPtr<Node> node, co
nst Position& pos) | 540 void CompositeEditCommand::insertNodeAtTabSpanPosition(PassRefPtr<Node> node, co
nst Position& pos) |
540 { | 541 { |
541 // insert node before, after, or at split of tab span | 542 // insert node before, after, or at split of tab span |
542 insertNodeAt(node, positionOutsideTabSpan(pos)); | 543 insertNodeAt(node, positionOutsideTabSpan(pos)); |
543 } | 544 } |
544 | 545 |
545 void CompositeEditCommand::deleteSelection(bool smartDelete, bool mergeBlocksAft
erDelete, bool expandForSpecialElements, bool sanitizeMarkup) | 546 void CompositeEditCommand::deleteSelection(bool smartDelete, bool mergeBlocksAft
erDelete, bool expandForSpecialElements, bool sanitizeMarkup) |
546 { | 547 { |
(...skipping 717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 // FIXME: Can't we do something better when the immediate parent wasn't a li
st node? | 1265 // FIXME: Can't we do something better when the immediate parent wasn't a li
st node? |
1265 if (!listNode | 1266 if (!listNode |
1266 || (!listNode->hasTagName(ulTag) && !listNode->hasTagName(olTag)) | 1267 || (!listNode->hasTagName(ulTag) && !listNode->hasTagName(olTag)) |
1267 || !listNode->rendererIsEditable() | 1268 || !listNode->rendererIsEditable() |
1268 || listNode == emptyListItem->rootEditableElement()) | 1269 || listNode == emptyListItem->rootEditableElement()) |
1269 return false; | 1270 return false; |
1270 | 1271 |
1271 RefPtr<Element> newBlock = nullptr; | 1272 RefPtr<Element> newBlock = nullptr; |
1272 if (ContainerNode* blockEnclosingList = listNode->parentNode()) { | 1273 if (ContainerNode* blockEnclosingList = listNode->parentNode()) { |
1273 if (blockEnclosingList->hasTagName(liTag)) { // listNode is inside anoth
er list item | 1274 if (blockEnclosingList->hasTagName(liTag)) { // listNode is inside anoth
er list item |
1274 if (visiblePositionAfterNode(blockEnclosingList) == visiblePositionA
fterNode(listNode.get())) { | 1275 if (visiblePositionAfterNode(*blockEnclosingList) == visiblePosition
AfterNode(*listNode)) { |
1275 // If listNode appears at the end of the outer list item, then m
ove listNode outside of this list item | 1276 // If listNode appears at the end of the outer list item, then m
ove listNode outside of this list item |
1276 // e.g. <ul><li>hello <ul><li><br></li></ul> </li></ul> should b
ecome <ul><li>hello</li> <ul><li><br></li></ul> </ul> after this section | 1277 // e.g. <ul><li>hello <ul><li><br></li></ul> </li></ul> should b
ecome <ul><li>hello</li> <ul><li><br></li></ul> </ul> after this section |
1277 // If listNode does NOT appear at the end, then we should consid
er it as a regular paragraph. | 1278 // If listNode does NOT appear at the end, then we should consid
er it as a regular paragraph. |
1278 // e.g. <ul><li> <ul><li><br></li></ul> hello</li></ul> should b
ecome <ul><li> <div><br></div> hello</li></ul> at the end | 1279 // e.g. <ul><li> <ul><li><br></li></ul> hello</li></ul> should b
ecome <ul><li> <div><br></div> hello</li></ul> at the end |
1279 splitElement(toElement(blockEnclosingList), listNode); | 1280 splitElement(toElement(blockEnclosingList), listNode); |
1280 removeNodePreservingChildren(listNode->parentNode()); | 1281 removeNodePreservingChildren(listNode->parentNode()); |
1281 newBlock = createListItemElement(document()); | 1282 newBlock = createListItemElement(document()); |
1282 } | 1283 } |
1283 // If listNode does NOT appear at the end of the outer list item, th
en behave as if in a regular paragraph. | 1284 // If listNode does NOT appear at the end of the outer list item, th
en behave as if in a regular paragraph. |
1284 } else if (blockEnclosingList->hasTagName(olTag) || blockEnclosingList->
hasTagName(ulTag)) { | 1285 } else if (blockEnclosingList->hasTagName(olTag) || blockEnclosingList->
hasTagName(ulTag)) { |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1401 enclosingAnchor = enclosingAnchorElement(original); | 1402 enclosingAnchor = enclosingAnchorElement(original); |
1402 if (!enclosingAnchor) | 1403 if (!enclosingAnchor) |
1403 return original; | 1404 return original; |
1404 } | 1405 } |
1405 // Don't insert outside an anchor if doing so would skip over a line
break. It would | 1406 // Don't insert outside an anchor if doing so would skip over a line
break. It would |
1406 // probably be safe to move the line break so that we could still av
oid the anchor here. | 1407 // probably be safe to move the line break so that we could still av
oid the anchor here. |
1407 Position downstream(visiblePos.deepEquivalent().downstream()); | 1408 Position downstream(visiblePos.deepEquivalent().downstream()); |
1408 if (lineBreakExistsAtVisiblePosition(visiblePos) && downstream.depre
catedNode()->isDescendantOf(enclosingAnchor)) | 1409 if (lineBreakExistsAtVisiblePosition(visiblePos) && downstream.depre
catedNode()->isDescendantOf(enclosingAnchor)) |
1409 return original; | 1410 return original; |
1410 | 1411 |
1411 result = positionInParentAfterNode(enclosingAnchor); | 1412 result = positionInParentAfterNode(*enclosingAnchor); |
1412 } | 1413 } |
1413 // If visually just before an anchor, insert *outside* the anchor unless
it's the first | 1414 // If visually just before an anchor, insert *outside* the anchor unless
it's the first |
1414 // VisiblePosition in a paragraph, to match NSTextView. | 1415 // VisiblePosition in a paragraph, to match NSTextView. |
1415 if (visiblePos == firstInAnchor) { | 1416 if (visiblePos == firstInAnchor) { |
1416 // Make sure anchors are pushed down before avoiding them so that we
don't | 1417 // Make sure anchors are pushed down before avoiding them so that we
don't |
1417 // also avoid structural elements like lists and blocks (5142012). | 1418 // also avoid structural elements like lists and blocks (5142012). |
1418 if (original.deprecatedNode() != enclosingAnchor && original.depreca
tedNode()->parentNode() != enclosingAnchor) { | 1419 if (original.deprecatedNode() != enclosingAnchor && original.depreca
tedNode()->parentNode() != enclosingAnchor) { |
1419 pushAnchorElementDown(enclosingAnchor); | 1420 pushAnchorElementDown(enclosingAnchor); |
1420 enclosingAnchor = enclosingAnchorElement(original); | 1421 enclosingAnchor = enclosingAnchorElement(original); |
1421 } | 1422 } |
1422 if (!enclosingAnchor) | 1423 if (!enclosingAnchor) |
1423 return original; | 1424 return original; |
1424 | 1425 |
1425 result = positionInParentBeforeNode(enclosingAnchor); | 1426 result = positionInParentBeforeNode(*enclosingAnchor); |
1426 } | 1427 } |
1427 } | 1428 } |
1428 | 1429 |
1429 if (result.isNull() || !editableRootForPosition(result)) | 1430 if (result.isNull() || !editableRootForPosition(result)) |
1430 result = original; | 1431 result = original; |
1431 | 1432 |
1432 return result; | 1433 return result; |
1433 } | 1434 } |
1434 | 1435 |
1435 // Splits the tree parent by parent until we reach the specified ancestor. We us
e VisiblePositions | 1436 // Splits the tree parent by parent until we reach the specified ancestor. We us
e VisiblePositions |
(...skipping 22 matching lines...) Expand all Loading... |
1458 return node.release(); | 1459 return node.release(); |
1459 } | 1460 } |
1460 | 1461 |
1461 PassRefPtr<Element> createBlockPlaceholderElement(Document& document) | 1462 PassRefPtr<Element> createBlockPlaceholderElement(Document& document) |
1462 { | 1463 { |
1463 RefPtr<Element> breakNode = document.createElement(brTag, false); | 1464 RefPtr<Element> breakNode = document.createElement(brTag, false); |
1464 return breakNode.release(); | 1465 return breakNode.release(); |
1465 } | 1466 } |
1466 | 1467 |
1467 } // namespace WebCore | 1468 } // namespace WebCore |
OLD | NEW |