OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2004 Apple Computer, 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 "VisiblePosition.h" | 30 #include "VisiblePosition.h" |
31 | 31 |
32 namespace WebCore { | 32 namespace WebCore { |
33 | 33 |
34 class Position; | 34 class Position; |
35 | 35 |
36 const EAffinity SEL_DEFAULT_AFFINITY = DOWNSTREAM; | 36 const EAffinity SEL_DEFAULT_AFFINITY = DOWNSTREAM; |
37 | 37 |
38 class Selection { | 38 class Selection { |
39 public: | 39 public: |
40 enum EState { NONE, CARET, RANGE }; | 40 enum SelectionType { NoSelection, CaretSelection, RangeSelection }; |
41 enum EDirection { FORWARD, BACKWARD, RIGHT, LEFT }; | |
42 | 41 |
43 Selection(); | 42 Selection(); |
44 | 43 |
45 Selection(const Position&, EAffinity); | 44 Selection(const Position&, EAffinity); |
46 Selection(const Position&, const Position&, EAffinity); | 45 Selection(const Position&, const Position&, EAffinity); |
47 | 46 |
48 Selection(const Range*, EAffinity = SEL_DEFAULT_AFFINITY); | 47 Selection(const Range*, EAffinity = SEL_DEFAULT_AFFINITY); |
49 | 48 |
50 Selection(const VisiblePosition&); | 49 Selection(const VisiblePosition&); |
51 Selection(const VisiblePosition&, const VisiblePosition&); | 50 Selection(const VisiblePosition&, const VisiblePosition&); |
52 | 51 |
53 static Selection selectionFromContentsOfNode(Node*); | 52 static Selection selectionFromContentsOfNode(Node*); |
54 | 53 |
55 EState state() const { return m_state; } | 54 SelectionType selectionType() const { return m_selectionType; } |
56 | 55 |
57 void setAffinity(EAffinity affinity) { m_affinity = affinity; } | 56 void setAffinity(EAffinity affinity) { m_affinity = affinity; } |
58 EAffinity affinity() const { return m_affinity; } | 57 EAffinity affinity() const { return m_affinity; } |
59 | 58 |
60 void setBase(const Position&); | 59 void setBase(const Position&); |
61 void setBase(const VisiblePosition&); | 60 void setBase(const VisiblePosition&); |
62 void setExtent(const Position&); | 61 void setExtent(const Position&); |
63 void setExtent(const VisiblePosition&); | 62 void setExtent(const VisiblePosition&); |
64 | 63 |
65 Position base() const { return m_base; } | 64 Position base() const { return m_base; } |
66 Position extent() const { return m_extent; } | 65 Position extent() const { return m_extent; } |
67 Position start() const { return m_start; } | 66 Position start() const { return m_start; } |
68 Position end() const { return m_end; } | 67 Position end() const { return m_end; } |
69 | 68 |
70 VisiblePosition visibleStart() const { return VisiblePosition(m_start, isRan
ge() ? DOWNSTREAM : affinity()); } | 69 VisiblePosition visibleStart() const { return VisiblePosition(m_start, isRan
ge() ? DOWNSTREAM : affinity()); } |
71 VisiblePosition visibleEnd() const { return VisiblePosition(m_end, isRange()
? UPSTREAM : affinity()); } | 70 VisiblePosition visibleEnd() const { return VisiblePosition(m_end, isRange()
? UPSTREAM : affinity()); } |
72 | 71 |
73 bool isNone() const { return state() == NONE; } | 72 bool isNone() const { return selectionType() == NoSelection; } |
74 bool isCaret() const { return state() == CARET; } | 73 bool isCaret() const { return selectionType() == CaretSelection; } |
75 bool isRange() const { return state() == RANGE; } | 74 bool isRange() const { return selectionType() == RangeSelection; } |
76 bool isCaretOrRange() const { return state() != NONE; } | 75 bool isCaretOrRange() const { return selectionType() != NoSelection; } |
77 | 76 |
78 bool isBaseFirst() const { return m_baseIsFirst; } | 77 bool isBaseFirst() const { return m_baseIsFirst; } |
79 | 78 |
80 void appendTrailingWhitespace(); | 79 void appendTrailingWhitespace(); |
81 | 80 |
82 bool expandUsingGranularity(TextGranularity granularity); | 81 bool expandUsingGranularity(TextGranularity granularity); |
83 TextGranularity granularity() const { return m_granularity; } | 82 TextGranularity granularity() const { return m_granularity; } |
84 | 83 |
85 PassRefPtr<Range> toRange() const; | 84 // We don't yet support multi-range selections, so we only ever have one ran
ge to return. |
| 85 PassRefPtr<Range> firstRange() const; |
| 86 |
| 87 // FIXME: Most callers probably don't want this function, but are using it |
| 88 // for historical reasons. toNormalizedRange contracts the range around |
| 89 // text, and moves the caret upstream before returning the range. |
| 90 PassRefPtr<Range> toNormalizedRange() const; |
86 | 91 |
87 Element* rootEditableElement() const; | 92 Element* rootEditableElement() const; |
88 bool isContentEditable() const; | 93 bool isContentEditable() const; |
89 bool isContentRichlyEditable() const; | 94 bool isContentRichlyEditable() const; |
90 Node* shadowTreeRootNode() const; | 95 Node* shadowTreeRootNode() const; |
91 | 96 |
92 void debugPosition() const; | 97 void debugPosition() const; |
93 | 98 |
94 #ifndef NDEBUG | 99 #ifndef NDEBUG |
95 void formatForDebugger(char* buffer, unsigned length) const; | 100 void formatForDebugger(char* buffer, unsigned length) const; |
96 void showTreeForThis() const; | 101 void showTreeForThis() const; |
97 #endif | 102 #endif |
98 | 103 |
99 void setWithoutValidation(const Position&, const Position&); | 104 void setWithoutValidation(const Position&, const Position&); |
100 | 105 |
101 private: | 106 private: |
102 void validate(); | 107 void validate(); |
103 void adjustForEditableContent(); | |
104 | 108 |
105 Position m_base; // base position for the selection | 109 // Support methods for validate() |
106 Position m_extent; // extent position for the selection | 110 void setBaseAndExtentToDeepEquivalents(); |
107 Position m_start; // start position for the selection | 111 void setStartAndEndFromBaseAndExtentRespectingGranularity(); |
108 Position m_end; // end position for the selection | 112 void adjustSelectionToAvoidCrossingEditingBoundaries(); |
| 113 void updateSelectionType(); |
109 | 114 |
110 EAffinity m_affinity; // the upstream/downstream affinity of the
caret | 115 Position m_base; // Where the first click happened |
111 TextGranularity m_granularity; // granularity of start/end selection | 116 Position m_extent; // Where the end click happened |
| 117 Position m_start; // Leftmost position when expanded to respect granularity |
| 118 Position m_end; // Rightmost position when expanded to respect granularit
y |
| 119 |
| 120 EAffinity m_affinity; // the upstream/downstream affinity of the c
aret |
| 121 TextGranularity m_granularity; // granularity of start/end selection |
112 | 122 |
113 // these are cached, can be recalculated by validate() | 123 // these are cached, can be recalculated by validate() |
114 EState m_state; // the state of the selection | 124 SelectionType m_selectionType; // None, Caret, Range |
115 bool m_baseIsFirst; // true if base is before the extent | 125 bool m_baseIsFirst; // true if base is before the extent |
116 }; | 126 }; |
117 | 127 |
118 inline bool operator==(const Selection& a, const Selection& b) | 128 inline bool operator==(const Selection& a, const Selection& b) |
119 { | 129 { |
120 return a.start() == b.start() && a.end() == b.end() && a.affinity() == b.aff
inity() && a.granularity() == b.granularity() && a.isBaseFirst() == b.isBaseFirs
t(); | 130 return a.start() == b.start() && a.end() == b.end() && a.affinity() == b.aff
inity() && a.granularity() == b.granularity() && a.isBaseFirst() == b.isBaseFirs
t(); |
121 } | 131 } |
122 | 132 |
123 inline bool operator!=(const Selection& a, const Selection& b) | 133 inline bool operator!=(const Selection& a, const Selection& b) |
124 { | 134 { |
125 return !(a == b); | 135 return !(a == b); |
126 } | 136 } |
127 | 137 |
128 } // namespace WebCore | 138 } // namespace WebCore |
129 | 139 |
130 #ifndef NDEBUG | 140 #ifndef NDEBUG |
131 // Outside the WebCore namespace for ease of invocation from gdb. | 141 // Outside the WebCore namespace for ease of invocation from gdb. |
132 void showTree(const WebCore::Selection&); | 142 void showTree(const WebCore::Selection&); |
133 void showTree(const WebCore::Selection*); | 143 void showTree(const WebCore::Selection*); |
134 #endif | 144 #endif |
135 | 145 |
136 #endif // Selection_h | 146 #endif // Selection_h |
137 | 147 |
OLD | NEW |