Remove unnecessary null check in FrameSelection::nodeWillBeRemoved()
[WebKit-https.git] / Source / WebCore / dom / RangeBoundaryPoint.h
1 /*
2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef RangeBoundaryPoint_h
27 #define RangeBoundaryPoint_h
28
29 #include "Node.h"
30 #include "Position.h"
31
32 namespace WebCore {
33
34 class RangeBoundaryPoint {
35 public:
36     explicit RangeBoundaryPoint(PassRefPtr<Node> container);
37
38     explicit RangeBoundaryPoint(const RangeBoundaryPoint&);
39
40     const Position toPosition() const;
41
42     Node* container() const;
43     int offset() const;
44     Node* childBefore() const;
45
46     void clear();
47
48     void set(PassRefPtr<Node> container, int offset, Node* childBefore);
49     void setOffset(int offset);
50
51     void setToBeforeChild(Node&);
52     void setToStartOfNode(PassRefPtr<Node>);
53     void setToEndOfNode(PassRefPtr<Node>);
54
55     void childBeforeWillBeRemoved();
56     void invalidateOffset() const;
57     void ensureOffsetIsValid() const;
58
59 private:
60     static const int invalidOffset = -1;
61
62     RefPtr<Node> m_containerNode;
63     mutable int m_offsetInContainer;
64     RefPtr<Node> m_childBeforeBoundary;
65 };
66
67 inline RangeBoundaryPoint::RangeBoundaryPoint(PassRefPtr<Node> container)
68     : m_containerNode(container)
69     , m_offsetInContainer(0)
70     , m_childBeforeBoundary(0)
71 {
72     ASSERT(m_containerNode);
73 }
74
75 inline RangeBoundaryPoint::RangeBoundaryPoint(const RangeBoundaryPoint& other)
76     : m_containerNode(other.container())
77     , m_offsetInContainer(other.offset())
78     , m_childBeforeBoundary(other.childBefore())
79 {
80 }
81
82 inline Node* RangeBoundaryPoint::container() const
83 {
84     return m_containerNode.get();
85 }
86
87 inline Node* RangeBoundaryPoint::childBefore() const
88 {
89     return m_childBeforeBoundary.get();
90 }
91
92 inline void RangeBoundaryPoint::ensureOffsetIsValid() const
93 {
94     if (m_offsetInContainer >= 0)
95         return;
96
97     ASSERT(m_childBeforeBoundary);
98     m_offsetInContainer = m_childBeforeBoundary->computeNodeIndex() + 1;
99 }
100
101 inline const Position RangeBoundaryPoint::toPosition() const
102 {
103     ensureOffsetIsValid();
104     return createLegacyEditingPosition(m_containerNode.get(), m_offsetInContainer);
105 }
106
107 inline int RangeBoundaryPoint::offset() const
108 {
109     ensureOffsetIsValid();
110     return m_offsetInContainer;
111 }
112
113 inline void RangeBoundaryPoint::clear()
114 {
115     m_containerNode.clear();
116     m_offsetInContainer = 0;
117     m_childBeforeBoundary = 0;
118 }
119
120 inline void RangeBoundaryPoint::set(PassRefPtr<Node> container, int offset, Node* childBefore)
121 {
122     ASSERT(container);
123     ASSERT(offset >= 0);
124     ASSERT(childBefore == (offset ? container->traverseToChildAt(offset - 1) : 0));
125     m_containerNode = container;
126     m_offsetInContainer = offset;
127     m_childBeforeBoundary = childBefore;
128 }
129
130 inline void RangeBoundaryPoint::setOffset(int offset)
131 {
132     ASSERT(m_containerNode);
133     ASSERT(m_containerNode->offsetInCharacters());
134     ASSERT(m_offsetInContainer >= 0);
135     ASSERT(!m_childBeforeBoundary);
136     m_offsetInContainer = offset;
137 }
138
139 inline void RangeBoundaryPoint::setToBeforeChild(Node& child)
140 {
141     ASSERT(child.parentNode());
142     m_childBeforeBoundary = child.previousSibling();
143     m_containerNode = child.parentNode();
144     m_offsetInContainer = m_childBeforeBoundary ? invalidOffset : 0;
145 }
146
147 inline void RangeBoundaryPoint::setToStartOfNode(PassRefPtr<Node> container)
148 {
149     ASSERT(container);
150     m_containerNode = container;
151     m_offsetInContainer = 0;
152     m_childBeforeBoundary = 0;
153 }
154
155 inline void RangeBoundaryPoint::setToEndOfNode(PassRefPtr<Node> container)
156 {
157     ASSERT(container);
158     m_containerNode = container;
159     if (m_containerNode->offsetInCharacters()) {
160         m_offsetInContainer = m_containerNode->maxCharacterOffset();
161         m_childBeforeBoundary = 0;
162     } else {
163         m_childBeforeBoundary = m_containerNode->lastChild();
164         m_offsetInContainer = m_childBeforeBoundary ? invalidOffset : 0;
165     }
166 }
167
168 inline void RangeBoundaryPoint::childBeforeWillBeRemoved()
169 {
170     ASSERT(m_offsetInContainer);
171     m_childBeforeBoundary = m_childBeforeBoundary->previousSibling();
172     if (!m_childBeforeBoundary)
173         m_offsetInContainer = 0;
174     else if (m_offsetInContainer > 0)
175         --m_offsetInContainer;
176 }
177
178 inline void RangeBoundaryPoint::invalidateOffset() const
179 {
180     m_offsetInContainer = invalidOffset;
181 }
182
183 inline bool operator==(const RangeBoundaryPoint& a, const RangeBoundaryPoint& b)
184 {
185     if (a.container() != b.container())
186         return false;
187     if (a.childBefore() || b.childBefore()) {
188         if (a.childBefore() != b.childBefore())
189             return false;
190     } else {
191         if (a.offset() != b.offset())
192             return false;
193     }
194     return true;
195 }
196
197 }
198
199 #endif