| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. |
| 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 1540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1551 if (!prevousNodeIterator || !prevousNodeIterator->isDescendantOf(hig
hestRoot)) | 1551 if (!prevousNodeIterator || !prevousNodeIterator->isDescendantOf(hig
hestRoot)) |
| 1552 break; | 1552 break; |
| 1553 } | 1553 } |
| 1554 | 1554 |
| 1555 const LayoutItem layoutItem = LayoutItem(prevousNodeIterator->layoutObje
ct()); | 1555 const LayoutItem layoutItem = LayoutItem(prevousNodeIterator->layoutObje
ct()); |
| 1556 if (layoutItem.isNull()) { | 1556 if (layoutItem.isNull()) { |
| 1557 prevousNodeIterator = Strategy::previousPostOrder(*prevousNodeIterat
or, startBlock); | 1557 prevousNodeIterator = Strategy::previousPostOrder(*prevousNodeIterat
or, startBlock); |
| 1558 continue; | 1558 continue; |
| 1559 } | 1559 } |
| 1560 const ComputedStyle& style = layoutItem.styleRef(); | 1560 const ComputedStyle& style = layoutItem.styleRef(); |
| 1561 if (style.visibility() != VISIBLE) { | 1561 if (style.visibility() != EVisibility::Visible) { |
| 1562 prevousNodeIterator = Strategy::previousPostOrder(*prevousNodeIterat
or, startBlock); | 1562 prevousNodeIterator = Strategy::previousPostOrder(*prevousNodeIterat
or, startBlock); |
| 1563 continue; | 1563 continue; |
| 1564 } | 1564 } |
| 1565 | 1565 |
| 1566 if (layoutItem.isBR() || isEnclosingBlock(prevousNodeIterator)) | 1566 if (layoutItem.isBR() || isEnclosingBlock(prevousNodeIterator)) |
| 1567 break; | 1567 break; |
| 1568 | 1568 |
| 1569 if (layoutItem.isText() && toLayoutText(prevousNodeIterator->layoutObjec
t())->resolvedTextLength()) { | 1569 if (layoutItem.isText() && toLayoutText(prevousNodeIterator->layoutObjec
t())->resolvedTextLength()) { |
| 1570 SECURITY_DCHECK(prevousNodeIterator->isTextNode()); | 1570 SECURITY_DCHECK(prevousNodeIterator->isTextNode()); |
| 1571 if (style.preserveNewline()) { | 1571 if (style.preserveNewline()) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1642 if (!nextNodeItreator || !nextNodeItreator->isDescendantOf(highestRo
ot)) | 1642 if (!nextNodeItreator || !nextNodeItreator->isDescendantOf(highestRo
ot)) |
| 1643 break; | 1643 break; |
| 1644 } | 1644 } |
| 1645 | 1645 |
| 1646 LayoutObject* const layoutObject = nextNodeItreator->layoutObject(); | 1646 LayoutObject* const layoutObject = nextNodeItreator->layoutObject(); |
| 1647 if (!layoutObject) { | 1647 if (!layoutObject) { |
| 1648 nextNodeItreator = Strategy::next(*nextNodeItreator, startBlock); | 1648 nextNodeItreator = Strategy::next(*nextNodeItreator, startBlock); |
| 1649 continue; | 1649 continue; |
| 1650 } | 1650 } |
| 1651 const ComputedStyle& style = layoutObject->styleRef(); | 1651 const ComputedStyle& style = layoutObject->styleRef(); |
| 1652 if (style.visibility() != VISIBLE) { | 1652 if (style.visibility() != EVisibility::Visible) { |
| 1653 nextNodeItreator = Strategy::next(*nextNodeItreator, startBlock); | 1653 nextNodeItreator = Strategy::next(*nextNodeItreator, startBlock); |
| 1654 continue; | 1654 continue; |
| 1655 } | 1655 } |
| 1656 | 1656 |
| 1657 if (layoutObject->isBR() || isEnclosingBlock(nextNodeItreator)) | 1657 if (layoutObject->isBR() || isEnclosingBlock(nextNodeItreator)) |
| 1658 break; | 1658 break; |
| 1659 | 1659 |
| 1660 // FIXME: We avoid returning a position where the layoutObject can't acc
ept the caret. | 1660 // FIXME: We avoid returning a position where the layoutObject can't acc
ept the caret. |
| 1661 if (layoutObject->isText() && toLayoutText(layoutObject)->resolvedTextLe
ngth()) { | 1661 if (layoutObject->isText() && toLayoutText(layoutObject)->resolvedTextLe
ngth()) { |
| 1662 SECURITY_DCHECK(nextNodeItreator->isTextNode()); | 1662 SECURITY_DCHECK(nextNodeItreator->isTextNode()); |
| (...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2450 lastNode = currentNode; | 2450 lastNode = currentNode; |
| 2451 } | 2451 } |
| 2452 | 2452 |
| 2453 // If we've moved to a position that is visually distinct, return the la
st saved position. There | 2453 // If we've moved to a position that is visually distinct, return the la
st saved position. There |
| 2454 // is code below that terminates early if we're *about* to move to a vis
ually distinct position. | 2454 // is code below that terminates early if we're *about* to move to a vis
ually distinct position. |
| 2455 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentNode !
= boundary) | 2455 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentNode !
= boundary) |
| 2456 return lastVisible.deprecatedComputePosition(); | 2456 return lastVisible.deprecatedComputePosition(); |
| 2457 | 2457 |
| 2458 // skip position in non-laid out or invisible node | 2458 // skip position in non-laid out or invisible node |
| 2459 LayoutObject* layoutObject = associatedLayoutObjectOf(*currentNode, curr
entPos.offsetInLeafNode()); | 2459 LayoutObject* layoutObject = associatedLayoutObjectOf(*currentNode, curr
entPos.offsetInLeafNode()); |
| 2460 if (!layoutObject || layoutObject->style()->visibility() != VISIBLE) | 2460 if (!layoutObject || layoutObject->style()->visibility() != EVisibility:
:Visible) |
| 2461 continue; | 2461 continue; |
| 2462 | 2462 |
| 2463 if (rule == CanCrossEditingBoundary && boundaryCrossed) { | 2463 if (rule == CanCrossEditingBoundary && boundaryCrossed) { |
| 2464 lastVisible = currentPos; | 2464 lastVisible = currentPos; |
| 2465 break; | 2465 break; |
| 2466 } | 2466 } |
| 2467 | 2467 |
| 2468 // track last visible streamer position | 2468 // track last visible streamer position |
| 2469 if (isStreamer<Strategy>(currentPos)) | 2469 if (isStreamer<Strategy>(currentPos)) |
| 2470 lastVisible = currentPos; | 2470 lastVisible = currentPos; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2498 DCHECK_GE(currentPos.offsetInLeafNode(), static_cast<int>(textStartO
ffset)); | 2498 DCHECK_GE(currentPos.offsetInLeafNode(), static_cast<int>(textStartO
ffset)); |
| 2499 const unsigned textOffset = currentPos.offsetInLeafNode() - textStar
tOffset; | 2499 const unsigned textOffset = currentPos.offsetInLeafNode() - textStar
tOffset; |
| 2500 InlineTextBox* lastTextBox = textLayoutObject->lastTextBox(); | 2500 InlineTextBox* lastTextBox = textLayoutObject->lastTextBox(); |
| 2501 for (InlineTextBox* box = textLayoutObject->firstTextBox(); box; box
= box->nextTextBox()) { | 2501 for (InlineTextBox* box = textLayoutObject->firstTextBox(); box; box
= box->nextTextBox()) { |
| 2502 if (textOffset == box->start()) { | 2502 if (textOffset == box->start()) { |
| 2503 if (textLayoutObject->isTextFragment() && toLayoutTextFragme
nt(layoutObject)->isRemainingTextLayoutObject()) { | 2503 if (textLayoutObject->isTextFragment() && toLayoutTextFragme
nt(layoutObject)->isRemainingTextLayoutObject()) { |
| 2504 // |currentPos| is at start of remaining text of | 2504 // |currentPos| is at start of remaining text of |
| 2505 // |Text| node with :first-letter. | 2505 // |Text| node with :first-letter. |
| 2506 DCHECK_GE(currentPos.offsetInLeafNode(), 1); | 2506 DCHECK_GE(currentPos.offsetInLeafNode(), 1); |
| 2507 LayoutObject* firstLetterLayoutObject = toLayoutTextFrag
ment(layoutObject)->firstLetterPseudoElement()->layoutObject(); | 2507 LayoutObject* firstLetterLayoutObject = toLayoutTextFrag
ment(layoutObject)->firstLetterPseudoElement()->layoutObject(); |
| 2508 if (firstLetterLayoutObject && firstLetterLayoutObject->
style()->visibility() == VISIBLE) | 2508 if (firstLetterLayoutObject && firstLetterLayoutObject->
style()->visibility() == EVisibility::Visible) |
| 2509 return currentPos.computePosition(); | 2509 return currentPos.computePosition(); |
| 2510 } | 2510 } |
| 2511 continue; | 2511 continue; |
| 2512 } | 2512 } |
| 2513 if (textOffset <= box->start() + box->len()) { | 2513 if (textOffset <= box->start() + box->len()) { |
| 2514 if (textOffset > box->start()) | 2514 if (textOffset > box->start()) |
| 2515 return currentPos.computePosition(); | 2515 return currentPos.computePosition(); |
| 2516 continue; | 2516 continue; |
| 2517 } | 2517 } |
| 2518 | 2518 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2601 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentNode !
= boundary) | 2601 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentNode !
= boundary) |
| 2602 return lastVisible.deprecatedComputePosition(); | 2602 return lastVisible.deprecatedComputePosition(); |
| 2603 // Do not move past a visually disinct position. | 2603 // Do not move past a visually disinct position. |
| 2604 // Note: The first position after the last in a node whose ends are visu
ally distinct | 2604 // Note: The first position after the last in a node whose ends are visu
ally distinct |
| 2605 // positions will be [boundary->parentNode(), originalBlock->nodeIndex()
+ 1]. | 2605 // positions will be [boundary->parentNode(), originalBlock->nodeIndex()
+ 1]. |
| 2606 if (boundary && Strategy::parent(*boundary) == currentNode) | 2606 if (boundary && Strategy::parent(*boundary) == currentNode) |
| 2607 return lastVisible.deprecatedComputePosition(); | 2607 return lastVisible.deprecatedComputePosition(); |
| 2608 | 2608 |
| 2609 // skip position in non-laid out or invisible node | 2609 // skip position in non-laid out or invisible node |
| 2610 LayoutObject* layoutObject = associatedLayoutObjectOf(*currentNode, curr
entPos.offsetInLeafNode()); | 2610 LayoutObject* layoutObject = associatedLayoutObjectOf(*currentNode, curr
entPos.offsetInLeafNode()); |
| 2611 if (!layoutObject || layoutObject->style()->visibility() != VISIBLE) | 2611 if (!layoutObject || layoutObject->style()->visibility() != EVisibility:
:Visible) |
| 2612 continue; | 2612 continue; |
| 2613 | 2613 |
| 2614 if (rule == CanCrossEditingBoundary && boundaryCrossed) { | 2614 if (rule == CanCrossEditingBoundary && boundaryCrossed) { |
| 2615 lastVisible = currentPos; | 2615 lastVisible = currentPos; |
| 2616 break; | 2616 break; |
| 2617 } | 2617 } |
| 2618 | 2618 |
| 2619 // track last visible streamer position | 2619 // track last visible streamer position |
| 2620 if (isStreamer<Strategy>(currentPos)) | 2620 if (isStreamer<Strategy>(currentPos)) |
| 2621 lastVisible = currentPos; | 2621 lastVisible = currentPos; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2719 static bool isVisuallyEquivalentCandidateAlgorithm(const PositionTemplate<Strate
gy>& position) | 2719 static bool isVisuallyEquivalentCandidateAlgorithm(const PositionTemplate<Strate
gy>& position) |
| 2720 { | 2720 { |
| 2721 Node* const anchorNode = position.anchorNode(); | 2721 Node* const anchorNode = position.anchorNode(); |
| 2722 if (!anchorNode) | 2722 if (!anchorNode) |
| 2723 return false; | 2723 return false; |
| 2724 | 2724 |
| 2725 LayoutObject* layoutObject = anchorNode->layoutObject(); | 2725 LayoutObject* layoutObject = anchorNode->layoutObject(); |
| 2726 if (!layoutObject) | 2726 if (!layoutObject) |
| 2727 return false; | 2727 return false; |
| 2728 | 2728 |
| 2729 if (layoutObject->style()->visibility() != VISIBLE) | 2729 if (layoutObject->style()->visibility() != EVisibility::Visible) |
| 2730 return false; | 2730 return false; |
| 2731 | 2731 |
| 2732 if (layoutObject->isBR()) { | 2732 if (layoutObject->isBR()) { |
| 2733 // TODO(leviw) The condition should be | 2733 // TODO(leviw) The condition should be |
| 2734 // m_anchorType == PositionAnchorType::BeforeAnchor, but for now we | 2734 // m_anchorType == PositionAnchorType::BeforeAnchor, but for now we |
| 2735 // still need to support legacy positions. | 2735 // still need to support legacy positions. |
| 2736 if (position.isAfterAnchor()) | 2736 if (position.isAfterAnchor()) |
| 2737 return false; | 2737 return false; |
| 2738 if (position.computeEditingOffset()) | 2738 if (position.computeEditingOffset()) |
| 2739 return false; | 2739 return false; |
| (...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3320 { | 3320 { |
| 3321 return previousPositionOfAlgorithm<EditingStrategy>(visiblePosition, rule); | 3321 return previousPositionOfAlgorithm<EditingStrategy>(visiblePosition, rule); |
| 3322 } | 3322 } |
| 3323 | 3323 |
| 3324 VisiblePositionInFlatTree previousPositionOf(const VisiblePositionInFlatTree& vi
siblePosition, EditingBoundaryCrossingRule rule) | 3324 VisiblePositionInFlatTree previousPositionOf(const VisiblePositionInFlatTree& vi
siblePosition, EditingBoundaryCrossingRule rule) |
| 3325 { | 3325 { |
| 3326 return previousPositionOfAlgorithm<EditingInFlatTreeStrategy>(visiblePositio
n, rule); | 3326 return previousPositionOfAlgorithm<EditingInFlatTreeStrategy>(visiblePositio
n, rule); |
| 3327 } | 3327 } |
| 3328 | 3328 |
| 3329 } // namespace blink | 3329 } // namespace blink |
| OLD | NEW |