OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2006, 2008 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 class RenderObject; | 44 class RenderObject; |
45 class Text; | 45 class Text; |
46 | 46 |
47 enum PositionMoveType { | 47 enum PositionMoveType { |
48 CodePoint, // Move by a single code point. | 48 CodePoint, // Move by a single code point. |
49 Character, // Move to the next Unicode character break. | 49 Character, // Move to the next Unicode character break. |
50 BackwardDeletion // Subject to platform conventions. | 50 BackwardDeletion // Subject to platform conventions. |
51 }; | 51 }; |
52 | 52 |
53 class Position { | 53 class Position { |
| 54 DISALLOW_ALLOCATION(); |
54 public: | 55 public: |
55 enum AnchorType { | 56 enum AnchorType { |
56 PositionIsOffsetInAnchor, | 57 PositionIsOffsetInAnchor, |
57 PositionIsBeforeAnchor, | 58 PositionIsBeforeAnchor, |
58 PositionIsAfterAnchor, | 59 PositionIsAfterAnchor, |
59 PositionIsBeforeChildren, | 60 PositionIsBeforeChildren, |
60 PositionIsAfterChildren, | 61 PositionIsAfterChildren, |
61 }; | 62 }; |
62 | 63 |
63 Position() | 64 Position() |
64 : m_offset(0) | 65 : m_offset(0) |
65 , m_anchorType(PositionIsOffsetInAnchor) | 66 , m_anchorType(PositionIsOffsetInAnchor) |
66 , m_isLegacyEditingPosition(false) | 67 , m_isLegacyEditingPosition(false) |
67 { | 68 { |
68 } | 69 } |
69 | 70 |
70 // For creating legacy editing positions: (Anchor type will be determined fr
om editingIgnoresContent(node)) | 71 // For creating legacy editing positions: (Anchor type will be determined fr
om editingIgnoresContent(node)) |
71 class LegacyEditingOffset { | 72 class LegacyEditingOffset { |
72 public: | 73 public: |
73 int value() const { return m_offset; } | 74 int value() const { return m_offset; } |
74 | 75 |
75 private: | 76 private: |
76 explicit LegacyEditingOffset(int offset) : m_offset(offset) { } | 77 explicit LegacyEditingOffset(int offset) : m_offset(offset) { } |
77 | 78 |
78 friend Position createLegacyEditingPosition(PassRefPtr<Node>, int offset
); | 79 friend Position createLegacyEditingPosition(PassRefPtrWillBeRawPtr<Node>
, int offset); |
79 | 80 |
80 int m_offset; | 81 int m_offset; |
81 }; | 82 }; |
82 Position(PassRefPtr<Node> anchorNode, LegacyEditingOffset); | 83 Position(PassRefPtrWillBeRawPtr<Node> anchorNode, LegacyEditingOffset); |
83 | 84 |
84 // For creating before/after positions: | 85 // For creating before/after positions: |
85 Position(PassRefPtr<Node> anchorNode, AnchorType); | 86 Position(PassRefPtrWillBeRawPtr<Node> anchorNode, AnchorType); |
86 Position(PassRefPtrWillBeRawPtr<Text> textNode, unsigned offset); | 87 Position(PassRefPtrWillBeRawPtr<Text> textNode, unsigned offset); |
87 | 88 |
88 // For creating offset positions: | 89 // For creating offset positions: |
89 // FIXME: This constructor should eventually go away. See bug 63040. | 90 // FIXME: This constructor should eventually go away. See bug 63040. |
90 Position(PassRefPtr<Node> anchorNode, int offset, AnchorType); | 91 Position(PassRefPtrWillBeRawPtr<Node> anchorNode, int offset, AnchorType); |
91 | 92 |
92 AnchorType anchorType() const { return static_cast<AnchorType>(m_anchorType)
; } | 93 AnchorType anchorType() const { return static_cast<AnchorType>(m_anchorType)
; } |
93 | 94 |
94 void clear() { m_anchorNode.clear(); m_offset = 0; m_anchorType = PositionIs
OffsetInAnchor; m_isLegacyEditingPosition = false; } | 95 void clear() { m_anchorNode.clear(); m_offset = 0; m_anchorType = PositionIs
OffsetInAnchor; m_isLegacyEditingPosition = false; } |
95 | 96 |
96 // These are always DOM compliant values. Editing positions like [img, 0] (
aka [img, before]) | 97 // These are always DOM compliant values. Editing positions like [img, 0] (
aka [img, before]) |
97 // will return img->parentNode() and img->nodeIndex() from these functions. | 98 // will return img->parentNode() and img->nodeIndex() from these functions. |
98 Node* containerNode() const; // NULL for a before/after position anchored to
a node with no parent | 99 Node* containerNode() const; // NULL for a before/after position anchored to
a node with no parent |
99 Text* containerText() const; | 100 Text* containerText() const; |
100 | 101 |
(...skipping 29 matching lines...) Expand all Loading... |
130 Document* document() const { return m_anchorNode ? &m_anchorNode->document()
: 0; } | 131 Document* document() const { return m_anchorNode ? &m_anchorNode->document()
: 0; } |
131 bool inDocument() const { return m_anchorNode && m_anchorNode->inDocument();
} | 132 bool inDocument() const { return m_anchorNode && m_anchorNode->inDocument();
} |
132 Element* rootEditableElement() const | 133 Element* rootEditableElement() const |
133 { | 134 { |
134 Node* container = containerNode(); | 135 Node* container = containerNode(); |
135 return container ? container->rootEditableElement() : 0; | 136 return container ? container->rootEditableElement() : 0; |
136 } | 137 } |
137 | 138 |
138 // These should only be used for PositionIsOffsetInAnchor positions, unless | 139 // These should only be used for PositionIsOffsetInAnchor positions, unless |
139 // the position is a legacy editing position. | 140 // the position is a legacy editing position. |
140 void moveToPosition(PassRefPtr<Node> anchorNode, int offset); | 141 void moveToPosition(PassRefPtrWillBeRawPtr<Node> anchorNode, int offset); |
141 void moveToOffset(int offset); | 142 void moveToOffset(int offset); |
142 | 143 |
143 bool isNull() const { return !m_anchorNode; } | 144 bool isNull() const { return !m_anchorNode; } |
144 bool isNotNull() const { return m_anchorNode; } | 145 bool isNotNull() const { return m_anchorNode; } |
145 bool isOrphan() const { return m_anchorNode && !m_anchorNode->inDocument();
} | 146 bool isOrphan() const { return m_anchorNode && !m_anchorNode->inDocument();
} |
146 | 147 |
147 Element* element() const; | 148 Element* element() const; |
148 PassRefPtrWillBeRawPtr<CSSComputedStyleDeclaration> computedStyle() const; | 149 PassRefPtrWillBeRawPtr<CSSComputedStyleDeclaration> computedStyle() const; |
149 | 150 |
150 // Move up or down the DOM by one position. | 151 // Move up or down the DOM by one position. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 static ContainerNode* findParent(const Node*); | 197 static ContainerNode* findParent(const Node*); |
197 | 198 |
198 void debugPosition(const char* msg = "") const; | 199 void debugPosition(const char* msg = "") const; |
199 | 200 |
200 #ifndef NDEBUG | 201 #ifndef NDEBUG |
201 void formatForDebugger(char* buffer, unsigned length) const; | 202 void formatForDebugger(char* buffer, unsigned length) const; |
202 void showAnchorTypeAndOffset() const; | 203 void showAnchorTypeAndOffset() const; |
203 void showTreeForThis() const; | 204 void showTreeForThis() const; |
204 #endif | 205 #endif |
205 | 206 |
| 207 void trace(Visitor*); |
| 208 |
206 private: | 209 private: |
207 int offsetForPositionAfterAnchor() const; | 210 int offsetForPositionAfterAnchor() const; |
208 | 211 |
209 int renderedOffset() const; | 212 int renderedOffset() const; |
210 | 213 |
211 Position previousCharacterPosition(EAffinity) const; | 214 Position previousCharacterPosition(EAffinity) const; |
212 | 215 |
213 static AnchorType anchorTypeForLegacyEditingPosition(Node* anchorNode, int o
ffset); | 216 static AnchorType anchorTypeForLegacyEditingPosition(Node* anchorNode, int o
ffset); |
214 | 217 |
215 RefPtr<Node> m_anchorNode; | 218 RefPtrWillBeMember<Node> m_anchorNode; |
216 // m_offset can be the offset inside m_anchorNode, or if editingIgnoresConte
nt(m_anchorNode) | 219 // m_offset can be the offset inside m_anchorNode, or if editingIgnoresConte
nt(m_anchorNode) |
217 // returns true, then other places in editing will treat m_offset == 0 as "b
efore the anchor" | 220 // returns true, then other places in editing will treat m_offset == 0 as "b
efore the anchor" |
218 // and m_offset > 0 as "after the anchor node". See parentAnchoredEquivalen
t for more info. | 221 // and m_offset > 0 as "after the anchor node". See parentAnchoredEquivalen
t for more info. |
219 int m_offset; | 222 int m_offset; |
220 unsigned m_anchorType : 3; | 223 unsigned m_anchorType : 3; |
221 bool m_isLegacyEditingPosition : 1; | 224 bool m_isLegacyEditingPosition : 1; |
222 }; | 225 }; |
223 | 226 |
224 inline Position createLegacyEditingPosition(PassRefPtr<Node> node, int offset) | 227 inline Position createLegacyEditingPosition(PassRefPtrWillBeRawPtr<Node> node, i
nt offset) |
225 { | 228 { |
226 return Position(node, Position::LegacyEditingOffset(offset)); | 229 return Position(node, Position::LegacyEditingOffset(offset)); |
227 } | 230 } |
228 | 231 |
229 inline bool operator==(const Position& a, const Position& b) | 232 inline bool operator==(const Position& a, const Position& b) |
230 { | 233 { |
231 // FIXME: In <div><img></div> [div, 0] != [img, 0] even though most of the | 234 // FIXME: In <div><img></div> [div, 0] != [img, 0] even though most of the |
232 // editing code will treat them as identical. | 235 // editing code will treat them as identical. |
233 return a.anchorNode() == b.anchorNode() && a.deprecatedEditingOffset() == b.
deprecatedEditingOffset() && a.anchorType() == b.anchorType(); | 236 return a.anchorNode() == b.anchorNode() && a.deprecatedEditingOffset() == b.
deprecatedEditingOffset() && a.anchorType() == b.anchorType(); |
234 } | 237 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 | 312 |
310 int currentOffset = 0; | 313 int currentOffset = 0; |
311 for (Node* node = anchorNode->firstChild(); node && currentOffset < offset;
node = node->nextSibling()) | 314 for (Node* node = anchorNode->firstChild(); node && currentOffset < offset;
node = node->nextSibling()) |
312 currentOffset++; | 315 currentOffset++; |
313 | 316 |
314 | 317 |
315 return offset < currentOffset; | 318 return offset < currentOffset; |
316 } | 319 } |
317 | 320 |
318 class PositionWithAffinity { | 321 class PositionWithAffinity { |
| 322 DISALLOW_ALLOCATION(); |
319 public: | 323 public: |
320 PositionWithAffinity() | 324 PositionWithAffinity() |
321 : m_affinity(DOWNSTREAM) | 325 : m_affinity(DOWNSTREAM) |
322 { | 326 { |
323 } | 327 } |
324 | 328 |
325 PositionWithAffinity(const Position& position, EAffinity affinity = DOWNSTRE
AM) | 329 PositionWithAffinity(const Position& position, EAffinity affinity = DOWNSTRE
AM) |
326 : m_position(position) | 330 : m_position(position) |
327 , m_affinity(affinity) | 331 , m_affinity(affinity) |
328 { | 332 { |
329 } | 333 } |
330 | 334 |
331 EAffinity affinity() const { return m_affinity; } | 335 EAffinity affinity() const { return m_affinity; } |
332 const Position& position() const { return m_position; } | 336 const Position& position() const { return m_position; } |
333 | 337 |
| 338 void trace(Visitor* visitor) |
| 339 { |
| 340 visitor->trace(m_position); |
| 341 } |
| 342 |
334 private: | 343 private: |
335 Position m_position; | 344 Position m_position; |
336 EAffinity m_affinity; | 345 EAffinity m_affinity; |
337 }; | 346 }; |
338 | 347 |
339 } // namespace WebCore | 348 } // namespace WebCore |
340 | 349 |
341 #ifndef NDEBUG | 350 #ifndef NDEBUG |
342 // Outside the WebCore namespace for ease of invocation from gdb. | 351 // Outside the WebCore namespace for ease of invocation from gdb. |
343 void showTree(const WebCore::Position&); | 352 void showTree(const WebCore::Position&); |
344 void showTree(const WebCore::Position*); | 353 void showTree(const WebCore::Position*); |
345 #endif | 354 #endif |
346 | 355 |
347 #endif // Position_h | 356 #endif // Position_h |
OLD | NEW |