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 1375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1386 n = NodeTraversal::previousPostOrder(*n, startBlock); | 1386 n = NodeTraversal::previousPostOrder(*n, startBlock); |
1387 } | 1387 } |
1388 } | 1388 } |
1389 | 1389 |
1390 if (type == PositionAnchorType::OffsetInAnchor) | 1390 if (type == PositionAnchorType::OffsetInAnchor) |
1391 return createVisiblePosition(Position(node, offset)); | 1391 return createVisiblePosition(Position(node, offset)); |
1392 | 1392 |
1393 return createVisiblePosition(Position(node, type)); | 1393 return createVisiblePosition(Position(node, type)); |
1394 } | 1394 } |
1395 | 1395 |
1396 VisiblePosition endOfParagraph(const VisiblePosition& c, EditingBoundaryCrossing
Rule boundaryCrossingRule) | 1396 template <typename Strategy> |
| 1397 static VisiblePositionTemplate<Strategy> endOfParagraphAlgorithm(const VisiblePo
sitionTemplate<Strategy>& c, EditingBoundaryCrossingRule boundaryCrossingRule) |
1397 { | 1398 { |
1398 if (c.isNull()) | 1399 if (c.isNull()) |
1399 return VisiblePosition(); | 1400 return VisiblePositionTemplate<Strategy>(); |
1400 | 1401 |
1401 Position p = c.deepEquivalent(); | 1402 const PositionAlgorithm<Strategy> p = c.deepEquivalent(); |
1402 Node* startNode = p.anchorNode(); | 1403 Node* startNode = p.anchorNode(); |
1403 | 1404 |
1404 if (isRenderedAsNonInlineTableImageOrHR(startNode)) | 1405 if (isRenderedAsNonInlineTableImageOrHR(startNode)) |
1405 return createVisiblePosition(positionAfterNode(startNode)); | 1406 return createVisiblePosition(PositionAlgorithm<Strategy>::afterNode(star
tNode)); |
1406 | 1407 |
1407 Element* startBlock = enclosingBlock(startNode); | 1408 Element* startBlock = enclosingBlock(PositionAlgorithm<Strategy>::firstPosit
ionInOrBeforeNode(startNode), CannotCrossEditingBoundary); |
1408 Element* stayInsideBlock = startBlock; | 1409 Element* stayInsideBlock = startBlock; |
1409 | 1410 |
1410 Node* node = startNode; | 1411 Node* node = startNode; |
1411 ContainerNode* highestRoot = highestEditableRoot(p); | 1412 ContainerNode* highestRoot = highestEditableRoot(p); |
1412 int offset = p.computeEditingOffset(); | 1413 int offset = p.computeEditingOffset(); |
1413 PositionAnchorType type = p.anchorType(); | 1414 PositionAnchorType type = p.anchorType(); |
1414 | 1415 |
1415 Node* n = startNode; | 1416 Node* n = startNode; |
1416 bool startNodeIsEditable = startNode->hasEditableStyle(); | 1417 bool startNodeIsEditable = startNode->hasEditableStyle(); |
1417 while (n) { | 1418 while (n) { |
1418 if (boundaryCrossingRule == CannotCrossEditingBoundary && !nodeIsUserSel
ectAll(n) && n->hasEditableStyle() != startNodeIsEditable) | 1419 if (boundaryCrossingRule == CannotCrossEditingBoundary && !nodeIsUserSel
ectAll(n) && n->hasEditableStyle() != startNodeIsEditable) |
1419 break; | 1420 break; |
1420 if (boundaryCrossingRule == CanSkipOverEditingBoundary) { | 1421 if (boundaryCrossingRule == CanSkipOverEditingBoundary) { |
1421 while (n && n->hasEditableStyle() != startNodeIsEditable) | 1422 while (n && n->hasEditableStyle() != startNodeIsEditable) |
1422 n = NodeTraversal::next(*n, stayInsideBlock); | 1423 n = Strategy::next(*n, stayInsideBlock); |
1423 if (!n || !n->isDescendantOf(highestRoot)) | 1424 if (!n || !n->isDescendantOf(highestRoot)) |
1424 break; | 1425 break; |
1425 } | 1426 } |
1426 | 1427 |
1427 LayoutObject* r = n->layoutObject(); | 1428 LayoutObject* r = n->layoutObject(); |
1428 if (!r) { | 1429 if (!r) { |
1429 n = NodeTraversal::next(*n, stayInsideBlock); | 1430 n = Strategy::next(*n, stayInsideBlock); |
1430 continue; | 1431 continue; |
1431 } | 1432 } |
1432 const ComputedStyle& style = r->styleRef(); | 1433 const ComputedStyle& style = r->styleRef(); |
1433 if (style.visibility() != VISIBLE) { | 1434 if (style.visibility() != VISIBLE) { |
1434 n = NodeTraversal::next(*n, stayInsideBlock); | 1435 n = Strategy::next(*n, stayInsideBlock); |
1435 continue; | 1436 continue; |
1436 } | 1437 } |
1437 | 1438 |
1438 if (r->isBR() || isEnclosingBlock(n)) | 1439 if (r->isBR() || isEnclosingBlock(n)) |
1439 break; | 1440 break; |
1440 | 1441 |
1441 // FIXME: We avoid returning a position where the layoutObject can't acc
ept the caret. | 1442 // FIXME: We avoid returning a position where the layoutObject can't acc
ept the caret. |
1442 if (r->isText() && toLayoutText(r)->resolvedTextLength()) { | 1443 if (r->isText() && toLayoutText(r)->resolvedTextLength()) { |
1443 ASSERT_WITH_SECURITY_IMPLICATION(n->isTextNode()); | 1444 ASSERT_WITH_SECURITY_IMPLICATION(n->isTextNode()); |
1444 int length = toLayoutText(r)->textLength(); | 1445 int length = toLayoutText(r)->textLength(); |
1445 type = PositionAnchorType::OffsetInAnchor; | 1446 type = PositionAnchorType::OffsetInAnchor; |
1446 if (style.preserveNewline()) { | 1447 if (style.preserveNewline()) { |
1447 LayoutText* text = toLayoutText(r); | 1448 LayoutText* text = toLayoutText(r); |
1448 int o = n == startNode ? offset : 0; | 1449 int o = n == startNode ? offset : 0; |
1449 for (int i = o; i < length; ++i) { | 1450 for (int i = o; i < length; ++i) { |
1450 if ((*text)[i] == '\n') | 1451 if ((*text)[i] == '\n') |
1451 return createVisiblePosition(Position(toText(n), i)); | 1452 return createVisiblePosition(PositionAlgorithm<Strategy>
(toText(n), i)); |
1452 } | 1453 } |
1453 } | 1454 } |
1454 node = n; | 1455 node = n; |
1455 offset = r->caretMaxOffset(); | 1456 offset = r->caretMaxOffset(); |
1456 n = NodeTraversal::next(*n, stayInsideBlock); | 1457 n = Strategy::next(*n, stayInsideBlock); |
1457 } else if (editingIgnoresContent(n) || isRenderedTableElement(n)) { | 1458 } else if (Strategy::editingIgnoresContent(n) || isRenderedTableElement(
n)) { |
1458 node = n; | 1459 node = n; |
1459 type = PositionAnchorType::AfterAnchor; | 1460 type = PositionAnchorType::AfterAnchor; |
1460 n = NodeTraversal::nextSkippingChildren(*n, stayInsideBlock); | 1461 n = Strategy::nextSkippingChildren(*n, stayInsideBlock); |
1461 } else { | 1462 } else { |
1462 n = NodeTraversal::next(*n, stayInsideBlock); | 1463 n = Strategy::next(*n, stayInsideBlock); |
1463 } | 1464 } |
1464 } | 1465 } |
1465 | 1466 |
1466 if (type == PositionAnchorType::OffsetInAnchor) | 1467 if (type == PositionAnchorType::OffsetInAnchor) |
1467 return createVisiblePosition(Position(node, offset)); | 1468 return createVisiblePosition(PositionAlgorithm<Strategy>(node, offset)); |
1468 | 1469 |
1469 return createVisiblePosition(Position(node, type)); | 1470 return createVisiblePosition(PositionAlgorithm<Strategy>(node, type)); |
| 1471 } |
| 1472 |
| 1473 VisiblePosition endOfParagraph(const VisiblePosition& c, EditingBoundaryCrossing
Rule boundaryCrossingRule) |
| 1474 { |
| 1475 return endOfParagraphAlgorithm<EditingStrategy>(c, boundaryCrossingRule); |
| 1476 } |
| 1477 |
| 1478 VisiblePositionInComposedTree endOfParagraph(const VisiblePositionInComposedTree
& c, EditingBoundaryCrossingRule boundaryCrossingRule) |
| 1479 { |
| 1480 return endOfParagraphAlgorithm<EditingInComposedTreeStrategy>(c, boundaryCro
ssingRule); |
1470 } | 1481 } |
1471 | 1482 |
1472 // FIXME: isStartOfParagraph(startOfNextParagraph(pos)) is not always true | 1483 // FIXME: isStartOfParagraph(startOfNextParagraph(pos)) is not always true |
1473 VisiblePosition startOfNextParagraph(const VisiblePosition& visiblePosition) | 1484 VisiblePosition startOfNextParagraph(const VisiblePosition& visiblePosition) |
1474 { | 1485 { |
1475 VisiblePosition paragraphEnd(endOfParagraph(visiblePosition, CanSkipOverEdit
ingBoundary)); | 1486 VisiblePosition paragraphEnd(endOfParagraph(visiblePosition, CanSkipOverEdit
ingBoundary)); |
1476 VisiblePosition afterParagraphEnd(nextPositionOf(paragraphEnd, CannotCrossEd
itingBoundary)); | 1487 VisiblePosition afterParagraphEnd(nextPositionOf(paragraphEnd, CannotCrossEd
itingBoundary)); |
1477 // The position after the last position in the last cell of a table | 1488 // The position after the last position in the last cell of a table |
1478 // is not the start of the next paragraph. | 1489 // is not the start of the next paragraph. |
1479 if (isFirstPositionAfterTable(afterParagraphEnd)) | 1490 if (isFirstPositionAfterTable(afterParagraphEnd)) |
(...skipping 1499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2979 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivale
nt()); | 2990 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivale
nt()); |
2980 case CanSkipOverEditingBoundary: | 2991 case CanSkipOverEditingBoundary: |
2981 return skipToStartOfEditingBoundary(prev, visiblePosition.deepEquivalent
()); | 2992 return skipToStartOfEditingBoundary(prev, visiblePosition.deepEquivalent
()); |
2982 } | 2993 } |
2983 | 2994 |
2984 ASSERT_NOT_REACHED(); | 2995 ASSERT_NOT_REACHED(); |
2985 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivalent()
); | 2996 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivalent()
); |
2986 } | 2997 } |
2987 | 2998 |
2988 } // namespace blink | 2999 } // namespace blink |
OLD | NEW |