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 19 matching lines...) Expand all Loading... |
30 #include "HTMLNames.h" | 30 #include "HTMLNames.h" |
31 #include "core/css/CSSComputedStyleDeclaration.h" | 31 #include "core/css/CSSComputedStyleDeclaration.h" |
32 #include "core/dom/PositionIterator.h" | 32 #include "core/dom/PositionIterator.h" |
33 #include "core/dom/Text.h" | 33 #include "core/dom/Text.h" |
34 #include "core/editing/TextIterator.h" | 34 #include "core/editing/TextIterator.h" |
35 #include "core/editing/VisiblePosition.h" | 35 #include "core/editing/VisiblePosition.h" |
36 #include "core/editing/VisibleUnits.h" | 36 #include "core/editing/VisibleUnits.h" |
37 #include "core/editing/htmlediting.h" | 37 #include "core/editing/htmlediting.h" |
38 #include "core/frame/LocalFrame.h" | 38 #include "core/frame/LocalFrame.h" |
39 #include "core/frame/Settings.h" | 39 #include "core/frame/Settings.h" |
40 #include "platform/Logging.h" | 40 #include "core/html/HTMLTableElement.h" |
41 #include "core/rendering/InlineIterator.h" | 41 #include "core/rendering/InlineIterator.h" |
42 #include "core/rendering/InlineTextBox.h" | 42 #include "core/rendering/InlineTextBox.h" |
43 #include "core/rendering/RenderBlock.h" | 43 #include "core/rendering/RenderBlock.h" |
44 #include "core/rendering/RenderInline.h" | 44 #include "core/rendering/RenderInline.h" |
45 #include "core/rendering/RenderText.h" | 45 #include "core/rendering/RenderText.h" |
| 46 #include "platform/Logging.h" |
46 #include "wtf/text/CString.h" | 47 #include "wtf/text/CString.h" |
47 #include "wtf/unicode/CharacterNames.h" | 48 #include "wtf/unicode/CharacterNames.h" |
48 | 49 |
49 namespace WebCore { | 50 namespace WebCore { |
50 | 51 |
51 using namespace HTMLNames; | 52 using namespace HTMLNames; |
52 | 53 |
53 static Node* nextRenderedEditable(Node* node) | 54 static Node* nextRenderedEditable(Node* node) |
54 { | 55 { |
55 while ((node = node->nextLeafNode())) { | 56 while ((node = node->nextLeafNode())) { |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 // FIXME: Share code with isCandidate, if possible. | 538 // FIXME: Share code with isCandidate, if possible. |
538 static bool endsOfNodeAreVisuallyDistinctPositions(Node* node) | 539 static bool endsOfNodeAreVisuallyDistinctPositions(Node* node) |
539 { | 540 { |
540 if (!node || !node->renderer()) | 541 if (!node || !node->renderer()) |
541 return false; | 542 return false; |
542 | 543 |
543 if (!node->renderer()->isInline()) | 544 if (!node->renderer()->isInline()) |
544 return true; | 545 return true; |
545 | 546 |
546 // Don't include inline tables. | 547 // Don't include inline tables. |
547 if (node->hasTagName(tableTag)) | 548 if (isHTMLTableElement(*node)) |
548 return false; | 549 return false; |
549 | 550 |
550 // A Marquee elements are moving so we should assume their ends are always | 551 // A Marquee elements are moving so we should assume their ends are always |
551 // visibily distinct. | 552 // visibily distinct. |
552 if (node->hasTagName(marqueeTag)) | 553 if (isHTMLMarqueeElement(*node)) |
553 return true; | 554 return true; |
554 | 555 |
555 // There is a VisiblePosition inside an empty inline-block container. | 556 // There is a VisiblePosition inside an empty inline-block container. |
556 return node->renderer()->isReplaced() && canHaveChildrenForEditing(node) &&
toRenderBox(node->renderer())->height() != 0 && !node->firstChild(); | 557 return node->renderer()->isReplaced() && canHaveChildrenForEditing(node) &&
toRenderBox(node->renderer())->height() != 0 && !node->firstChild(); |
557 } | 558 } |
558 | 559 |
559 static Node* enclosingVisualBoundary(Node* node) | 560 static Node* enclosingVisualBoundary(Node* node) |
560 { | 561 { |
561 while (node && !endsOfNodeAreVisuallyDistinctPositions(node)) | 562 while (node && !endsOfNodeAreVisuallyDistinctPositions(node)) |
562 node = node->parentNode(); | 563 node = node->parentNode(); |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
732 if (rule == CannotCrossEditingBoundary) | 733 if (rule == CannotCrossEditingBoundary) |
733 break; | 734 break; |
734 boundaryCrossed = true; | 735 boundaryCrossed = true; |
735 } | 736 } |
736 | 737 |
737 lastNode = currentNode; | 738 lastNode = currentNode; |
738 } | 739 } |
739 | 740 |
740 // stop before going above the body, up into the head | 741 // stop before going above the body, up into the head |
741 // return the last visible streamer position | 742 // return the last visible streamer position |
742 if (currentNode->hasTagName(bodyTag) && currentPos.atEndOfNode()) | 743 if (isHTMLBodyElement(*currentNode) && currentPos.atEndOfNode()) |
743 break; | 744 break; |
744 | 745 |
745 // Do not move to a visually distinct position. | 746 // Do not move to a visually distinct position. |
746 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentNode !
= boundary) | 747 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentNode !
= boundary) |
747 return lastVisible; | 748 return lastVisible; |
748 // Do not move past a visually disinct position. | 749 // Do not move past a visually disinct position. |
749 // Note: The first position after the last in a node whose ends are visu
ally distinct | 750 // Note: The first position after the last in a node whose ends are visu
ally distinct |
750 // positions will be [boundary->parentNode(), originalBlock->nodeIndex()
+ 1]. | 751 // positions will be [boundary->parentNode(), originalBlock->nodeIndex()
+ 1]. |
751 if (boundary && boundary->parentNode() == currentNode) | 752 if (boundary && boundary->parentNode() == currentNode) |
752 return lastVisible; | 753 return lastVisible; |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
888 if (renderer->isBR()) | 889 if (renderer->isBR()) |
889 // FIXME: The condition should be m_anchorType == PositionIsBeforeAnchor
, but for now we still need to support legacy positions. | 890 // FIXME: The condition should be m_anchorType == PositionIsBeforeAnchor
, but for now we still need to support legacy positions. |
890 return !m_offset && m_anchorType != PositionIsAfterAnchor && !nodeIsUser
SelectNone(deprecatedNode()->parentNode()); | 891 return !m_offset && m_anchorType != PositionIsAfterAnchor && !nodeIsUser
SelectNone(deprecatedNode()->parentNode()); |
891 | 892 |
892 if (renderer->isText()) | 893 if (renderer->isText()) |
893 return !nodeIsUserSelectNone(deprecatedNode()) && inRenderedText(); | 894 return !nodeIsUserSelectNone(deprecatedNode()) && inRenderedText(); |
894 | 895 |
895 if (isRenderedTableElement(deprecatedNode()) || editingIgnoresContent(deprec
atedNode())) | 896 if (isRenderedTableElement(deprecatedNode()) || editingIgnoresContent(deprec
atedNode())) |
896 return (atFirstEditingPositionForNode() || atLastEditingPositionForNode(
)) && !nodeIsUserSelectNone(deprecatedNode()->parentNode()); | 897 return (atFirstEditingPositionForNode() || atLastEditingPositionForNode(
)) && !nodeIsUserSelectNone(deprecatedNode()->parentNode()); |
897 | 898 |
898 if (m_anchorNode->hasTagName(htmlTag)) | 899 if (isHTMLHtmlElement(*m_anchorNode)) |
899 return false; | 900 return false; |
900 | 901 |
901 if (renderer->isRenderBlockFlow()) { | 902 if (renderer->isRenderBlockFlow()) { |
902 if (toRenderBlock(renderer)->logicalHeight() || m_anchorNode->hasTagName
(bodyTag)) { | 903 if (toRenderBlock(renderer)->logicalHeight() || isHTMLBodyElement(*m_anc
horNode)) { |
903 if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer
)) | 904 if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer
)) |
904 return atFirstEditingPositionForNode() && !Position::nodeIsUserS
electNone(deprecatedNode()); | 905 return atFirstEditingPositionForNode() && !Position::nodeIsUserS
electNone(deprecatedNode()); |
905 return m_anchorNode->rendererIsEditable() && !Position::nodeIsUserSe
lectNone(deprecatedNode()) && atEditingBoundary(); | 906 return m_anchorNode->rendererIsEditable() && !Position::nodeIsUserSe
lectNone(deprecatedNode()) && atEditingBoundary(); |
906 } | 907 } |
907 } else { | 908 } else { |
908 LocalFrame* frame = m_anchorNode->document().frame(); | 909 LocalFrame* frame = m_anchorNode->document().frame(); |
909 bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsi
ngEnabled(); | 910 bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsi
ngEnabled(); |
910 return (caretBrowsing || m_anchorNode->rendererIsEditable()) && !Positio
n::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary(); | 911 return (caretBrowsing || m_anchorNode->rendererIsEditable()) && !Positio
n::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary(); |
911 } | 912 } |
912 | 913 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
973 | 974 |
974 RenderObject* posRenderer = pos.deprecatedNode()->renderer(); | 975 RenderObject* posRenderer = pos.deprecatedNode()->renderer(); |
975 if (!posRenderer) | 976 if (!posRenderer) |
976 return false; | 977 return false; |
977 | 978 |
978 if (renderer->style()->visibility() != VISIBLE || | 979 if (renderer->style()->visibility() != VISIBLE || |
979 posRenderer->style()->visibility() != VISIBLE) | 980 posRenderer->style()->visibility() != VISIBLE) |
980 return false; | 981 return false; |
981 | 982 |
982 if (deprecatedNode() == pos.deprecatedNode()) { | 983 if (deprecatedNode() == pos.deprecatedNode()) { |
983 if (deprecatedNode()->hasTagName(brTag)) | 984 if (isHTMLBRElement(*deprecatedNode())) |
984 return false; | 985 return false; |
985 | 986 |
986 if (m_offset == pos.deprecatedEditingOffset()) | 987 if (m_offset == pos.deprecatedEditingOffset()) |
987 return false; | 988 return false; |
988 | 989 |
989 if (!deprecatedNode()->isTextNode() && !pos.deprecatedNode()->isTextNode
()) { | 990 if (!deprecatedNode()->isTextNode() && !pos.deprecatedNode()->isTextNode
()) { |
990 if (m_offset != pos.deprecatedEditingOffset()) | 991 if (m_offset != pos.deprecatedEditingOffset()) |
991 return true; | 992 return true; |
992 } | 993 } |
993 } | 994 } |
994 | 995 |
995 if (deprecatedNode()->hasTagName(brTag) && pos.isCandidate()) | 996 if (isHTMLBRElement(*deprecatedNode()) && pos.isCandidate()) |
996 return true; | 997 return true; |
997 | 998 |
998 if (pos.deprecatedNode()->hasTagName(brTag) && isCandidate()) | 999 if (isHTMLBRElement(*pos.deprecatedNode()) && isCandidate()) |
999 return true; | 1000 return true; |
1000 | 1001 |
1001 if (deprecatedNode()->enclosingBlockFlowElement() != pos.deprecatedNode()->e
nclosingBlockFlowElement()) | 1002 if (deprecatedNode()->enclosingBlockFlowElement() != pos.deprecatedNode()->e
nclosingBlockFlowElement()) |
1002 return true; | 1003 return true; |
1003 | 1004 |
1004 if (deprecatedNode()->isTextNode() && !inRenderedText()) | 1005 if (deprecatedNode()->isTextNode() && !inRenderedText()) |
1005 return false; | 1006 return false; |
1006 | 1007 |
1007 if (pos.deprecatedNode()->isTextNode() && !pos.inRenderedText()) | 1008 if (pos.deprecatedNode()->isTextNode() && !pos.inRenderedText()) |
1008 return false; | 1009 return false; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1048 return true; | 1049 return true; |
1049 } | 1050 } |
1050 | 1051 |
1051 // This assumes that it starts in editable content. | 1052 // This assumes that it starts in editable content. |
1052 Position Position::leadingWhitespacePosition(EAffinity affinity, bool considerNo
nCollapsibleWhitespace) const | 1053 Position Position::leadingWhitespacePosition(EAffinity affinity, bool considerNo
nCollapsibleWhitespace) const |
1053 { | 1054 { |
1054 ASSERT(isEditablePosition(*this, ContentIsEditable, DoNotUpdateStyle)); | 1055 ASSERT(isEditablePosition(*this, ContentIsEditable, DoNotUpdateStyle)); |
1055 if (isNull()) | 1056 if (isNull()) |
1056 return Position(); | 1057 return Position(); |
1057 | 1058 |
1058 if (upstream().deprecatedNode()->hasTagName(brTag)) | 1059 if (isHTMLBRElement(*upstream().deprecatedNode())) |
1059 return Position(); | 1060 return Position(); |
1060 | 1061 |
1061 Position prev = previousCharacterPosition(affinity); | 1062 Position prev = previousCharacterPosition(affinity); |
1062 if (prev != *this && prev.deprecatedNode()->inSameContainingBlockFlowElement
(deprecatedNode()) && prev.deprecatedNode()->isTextNode()) { | 1063 if (prev != *this && prev.deprecatedNode()->inSameContainingBlockFlowElement
(deprecatedNode()) && prev.deprecatedNode()->isTextNode()) { |
1063 String string = toText(prev.deprecatedNode())->data(); | 1064 String string = toText(prev.deprecatedNode())->data(); |
1064 UChar c = string[prev.deprecatedEditingOffset()]; | 1065 UChar c = string[prev.deprecatedEditingOffset()]; |
1065 if (considerNonCollapsibleWhitespace ? (isSpaceOrNewline(c) || c == noBr
eakSpace) : isCollapsibleWhitespace(c)) | 1066 if (considerNonCollapsibleWhitespace ? (isSpaceOrNewline(c) || c == noBr
eakSpace) : isCollapsibleWhitespace(c)) |
1066 if (isEditablePosition(prev)) | 1067 if (isEditablePosition(prev)) |
1067 return prev; | 1068 return prev; |
1068 } | 1069 } |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1387 pos.showTreeForThis(); | 1388 pos.showTreeForThis(); |
1388 } | 1389 } |
1389 | 1390 |
1390 void showTree(const WebCore::Position* pos) | 1391 void showTree(const WebCore::Position* pos) |
1391 { | 1392 { |
1392 if (pos) | 1393 if (pos) |
1393 pos->showTreeForThis(); | 1394 pos->showTreeForThis(); |
1394 } | 1395 } |
1395 | 1396 |
1396 #endif | 1397 #endif |
OLD | NEW |