| 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 |