OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2005, 2006, 2009 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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 template <typename Strategy> | 62 template <typename Strategy> |
63 const TreeScope* PositionAlgorithm<Strategy>::commonAncestorTreeScope(const Posi
tionAlgorithm<Strategy>& a, const PositionAlgorithm<Strategy>& b) | 63 const TreeScope* PositionAlgorithm<Strategy>::commonAncestorTreeScope(const Posi
tionAlgorithm<Strategy>& a, const PositionAlgorithm<Strategy>& b) |
64 { | 64 { |
65 if (!a.computeContainerNode() || !b.computeContainerNode()) | 65 if (!a.computeContainerNode() || !b.computeContainerNode()) |
66 return nullptr; | 66 return nullptr; |
67 return a.computeContainerNode()->treeScope().commonAncestorTreeScope(b.compu
teContainerNode()->treeScope()); | 67 return a.computeContainerNode()->treeScope().commonAncestorTreeScope(b.compu
teContainerNode()->treeScope()); |
68 } | 68 } |
69 | 69 |
70 | 70 |
71 template <typename Strategy> | 71 template <typename Strategy> |
72 PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::createLegacyEditingPosi
tion(PassRefPtrWillBeRawPtr<Node> anchorNode, int offset) | 72 PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::editingPositionOf(PassR
efPtrWillBeRawPtr<Node> anchorNode, int offset) |
73 { | 73 { |
74 if (!anchorNode || anchorNode->isTextNode()) | 74 if (!anchorNode || anchorNode->isTextNode()) |
75 return PositionAlgorithm<Strategy>(anchorNode, offset); | 75 return PositionAlgorithm<Strategy>(anchorNode, offset); |
76 | 76 |
77 if (!Strategy::editingIgnoresContent(anchorNode.get())) | 77 if (!Strategy::editingIgnoresContent(anchorNode.get())) |
78 return PositionAlgorithm<Strategy>(anchorNode, offset); | 78 return PositionAlgorithm<Strategy>(anchorNode, offset); |
79 | 79 |
80 if (offset == 0) | 80 if (offset == 0) |
81 return PositionAlgorithm<Strategy>(anchorNode, PositionAnchorType::Befor
eAnchor); | 81 return PositionAlgorithm<Strategy>(anchorNode, PositionAnchorType::Befor
eAnchor); |
82 | 82 |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 return firstPositionInOrBeforeNode(child); | 376 return firstPositionInOrBeforeNode(child); |
377 | 377 |
378 // TODO(yosin) We should use |Strategy::lastOffsetForEditing()| instead of | 378 // TODO(yosin) We should use |Strategy::lastOffsetForEditing()| instead of |
379 // DOM tree version. | 379 // DOM tree version. |
380 if (!Strategy::hasChildren(*node) && offset < EditingStrategy::lastOffsetFor
Editing(node)) { | 380 if (!Strategy::hasChildren(*node) && offset < EditingStrategy::lastOffsetFor
Editing(node)) { |
381 // There are two reasons child might be 0: | 381 // There are two reasons child might be 0: |
382 // 1) The node is node like a text node that is not an element, and th
erefore has no children. | 382 // 1) The node is node like a text node that is not an element, and th
erefore has no children. |
383 // Going forward one character at a time is correct. | 383 // Going forward one character at a time is correct. |
384 // 2) The new offset is a bogus offset like (<br>, 1), and there is no
child. | 384 // 2) The new offset is a bogus offset like (<br>, 1), and there is no
child. |
385 // Going from 0 to 1 is correct. | 385 // Going from 0 to 1 is correct. |
386 return createLegacyEditingPosition(node, (moveType == Character) ? unche
ckedNextOffset(node, offset) : offset + 1); | 386 return editingPositionOf(node, (moveType == Character) ? uncheckedNextOf
fset(node, offset) : offset + 1); |
387 } | 387 } |
388 | 388 |
389 if (ContainerNode* parent = Strategy::parent(*node)) | 389 if (ContainerNode* parent = Strategy::parent(*node)) |
390 return createLegacyEditingPosition(parent, Strategy::index(*node) + 1); | 390 return editingPositionOf(parent, Strategy::index(*node) + 1); |
391 return PositionAlgorithm<Strategy>(*this); | 391 return PositionAlgorithm<Strategy>(*this); |
392 } | 392 } |
393 | 393 |
394 template <typename Strategy> | 394 template <typename Strategy> |
395 int PositionAlgorithm<Strategy>::uncheckedPreviousOffset(const Node* n, int curr
ent) | 395 int PositionAlgorithm<Strategy>::uncheckedPreviousOffset(const Node* n, int curr
ent) |
396 { | 396 { |
397 return n->layoutObject() ? n->layoutObject()->previousOffset(current) : curr
ent - 1; | 397 return n->layoutObject() ? n->layoutObject()->previousOffset(current) : curr
ent - 1; |
398 } | 398 } |
399 | 399 |
400 template <typename Strategy> | 400 template <typename Strategy> |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 { | 569 { |
570 TRACE_EVENT0("blink", "Position::upstream"); | 570 TRACE_EVENT0("blink", "Position::upstream"); |
571 | 571 |
572 Node* startNode = anchorNode(); | 572 Node* startNode = anchorNode(); |
573 if (!startNode) | 573 if (!startNode) |
574 return PositionAlgorithm<Strategy>(); | 574 return PositionAlgorithm<Strategy>(); |
575 | 575 |
576 // iterate backward from there, looking for a qualified position | 576 // iterate backward from there, looking for a qualified position |
577 Node* boundary = enclosingVisualBoundary<Strategy>(startNode); | 577 Node* boundary = enclosingVisualBoundary<Strategy>(startNode); |
578 // FIXME: PositionIterator should respect Before and After positions. | 578 // FIXME: PositionIterator should respect Before and After positions. |
579 PositionIteratorAlgorithm<Strategy> lastVisible(isAfterAnchor() ? createLega
cyEditingPosition(m_anchorNode.get(), Strategy::caretMaxOffset(*m_anchorNode)) :
PositionAlgorithm<Strategy>(*this)); | 579 PositionIteratorAlgorithm<Strategy> lastVisible(isAfterAnchor() ? editingPos
itionOf(m_anchorNode.get(), Strategy::caretMaxOffset(*m_anchorNode)) : PositionA
lgorithm<Strategy>(*this)); |
580 PositionIteratorAlgorithm<Strategy> currentPos = lastVisible; | 580 PositionIteratorAlgorithm<Strategy> currentPos = lastVisible; |
581 bool startEditable = startNode->hasEditableStyle(); | 581 bool startEditable = startNode->hasEditableStyle(); |
582 Node* lastNode = startNode; | 582 Node* lastNode = startNode; |
583 bool boundaryCrossed = false; | 583 bool boundaryCrossed = false; |
584 for (; !currentPos.atStart(); currentPos.decrement()) { | 584 for (; !currentPos.atStart(); currentPos.decrement()) { |
585 Node* currentNode = currentPos.node(); | 585 Node* currentNode = currentPos.node(); |
586 // Don't check for an editability change if we haven't moved to a differ
ent node, | 586 // Don't check for an editability change if we haven't moved to a differ
ent node, |
587 // to avoid the expense of computing hasEditableStyle(). | 587 // to avoid the expense of computing hasEditableStyle(). |
588 if (currentNode != lastNode) { | 588 if (currentNode != lastNode) { |
589 // Don't change editability. | 589 // Don't change editability. |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 { | 693 { |
694 TRACE_EVENT0("blink", "Position::downstream"); | 694 TRACE_EVENT0("blink", "Position::downstream"); |
695 | 695 |
696 Node* startNode = anchorNode(); | 696 Node* startNode = anchorNode(); |
697 if (!startNode) | 697 if (!startNode) |
698 return PositionAlgorithm<Strategy>(); | 698 return PositionAlgorithm<Strategy>(); |
699 | 699 |
700 // iterate forward from there, looking for a qualified position | 700 // iterate forward from there, looking for a qualified position |
701 Node* boundary = enclosingVisualBoundary<Strategy>(startNode); | 701 Node* boundary = enclosingVisualBoundary<Strategy>(startNode); |
702 // FIXME: PositionIterator should respect Before and After positions. | 702 // FIXME: PositionIterator should respect Before and After positions. |
703 PositionIteratorAlgorithm<Strategy> lastVisible(isAfterAnchor() ? createLega
cyEditingPosition(m_anchorNode.get(), Strategy::caretMaxOffset(*m_anchorNode)) :
PositionAlgorithm<Strategy>(*this)); | 703 PositionIteratorAlgorithm<Strategy> lastVisible(isAfterAnchor() ? editingPos
itionOf(m_anchorNode.get(), Strategy::caretMaxOffset(*m_anchorNode)) : PositionA
lgorithm<Strategy>(*this)); |
704 PositionIteratorAlgorithm<Strategy> currentPos = lastVisible; | 704 PositionIteratorAlgorithm<Strategy> currentPos = lastVisible; |
705 bool startEditable = startNode->hasEditableStyle(); | 705 bool startEditable = startNode->hasEditableStyle(); |
706 Node* lastNode = startNode; | 706 Node* lastNode = startNode; |
707 bool boundaryCrossed = false; | 707 bool boundaryCrossed = false; |
708 for (; !currentPos.atEnd(); currentPos.increment()) { | 708 for (; !currentPos.atEnd(); currentPos.increment()) { |
709 Node* currentNode = currentPos.node(); | 709 Node* currentNode = currentPos.node(); |
710 // Don't check for an editability change if we haven't moved to a differ
ent node, | 710 // Don't check for an editability change if we haven't moved to a differ
ent node, |
711 // to avoid the expense of computing hasEditableStyle(). | 711 // to avoid the expense of computing hasEditableStyle(). |
712 if (currentNode != lastNode) { | 712 if (currentNode != lastNode) { |
713 // Don't change editability. | 713 // Don't change editability. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 break; | 745 break; |
746 } | 746 } |
747 | 747 |
748 // track last visible streamer position | 748 // track last visible streamer position |
749 if (isStreamer<Strategy>(currentPos)) | 749 if (isStreamer<Strategy>(currentPos)) |
750 lastVisible = currentPos; | 750 lastVisible = currentPos; |
751 | 751 |
752 // Return position before tables and nodes which have content that can b
e ignored. | 752 // Return position before tables and nodes which have content that can b
e ignored. |
753 if (Strategy::editingIgnoresContent(currentNode) || isRenderedHTMLTableE
lement(currentNode)) { | 753 if (Strategy::editingIgnoresContent(currentNode) || isRenderedHTMLTableE
lement(currentNode)) { |
754 if (currentPos.offsetInLeafNode() <= layoutObject->caretMinOffset()) | 754 if (currentPos.offsetInLeafNode() <= layoutObject->caretMinOffset()) |
755 return createLegacyEditingPosition(currentNode, layoutObject->ca
retMinOffset()); | 755 return editingPositionOf(currentNode, layoutObject->caretMinOffs
et()); |
756 continue; | 756 continue; |
757 } | 757 } |
758 | 758 |
759 // return current position if it is in laid out text | 759 // return current position if it is in laid out text |
760 if (layoutObject->isText() && toLayoutText(layoutObject)->firstTextBox()
) { | 760 if (layoutObject->isText() && toLayoutText(layoutObject)->firstTextBox()
) { |
761 if (currentNode != startNode) { | 761 if (currentNode != startNode) { |
762 ASSERT(currentPos.atStartOfNode()); | 762 ASSERT(currentPos.atStartOfNode()); |
763 return PositionAlgorithm<Strategy>(currentNode, layoutObject->ca
retMinOffset()); | 763 return PositionAlgorithm<Strategy>(currentNode, layoutObject->ca
retMinOffset()); |
764 } | 764 } |
765 | 765 |
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1361 | 1361 |
1362 void showTree(const blink::Position* pos) | 1362 void showTree(const blink::Position* pos) |
1363 { | 1363 { |
1364 if (pos) | 1364 if (pos) |
1365 pos->showTreeForThis(); | 1365 pos->showTreeForThis(); |
1366 else | 1366 else |
1367 fprintf(stderr, "Cannot showTree for (nil)\n"); | 1367 fprintf(stderr, "Cannot showTree for (nil)\n"); |
1368 } | 1368 } |
1369 | 1369 |
1370 #endif | 1370 #endif |
OLD | NEW |