Replace WTF::move with WTFMove
[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 { 0 };
64     RefPtr<Node> m_childBeforeBoundary;
65 };
66
67 inline RangeBoundaryPoint::RangeBoundaryPoint(PassRefPtr<Node> container)
68     : m_containerNode(container)
69 {
70     ASSERT(m_containerNode);
71 }
72
73 inline RangeBoundaryPoint::RangeBoundaryPoint(const RangeBoundaryPoint& other)
74     : m_containerNode(other.container())
75     , m_offsetInContainer(other.offset())
76     , m_childBeforeBoundary(other.childBefore())
77 {
78 }
79
80 inline Node* RangeBoundaryPoint::container() const
81 {
82     return m_containerNode.get();
83 }
84
85 inline Node* RangeBoundaryPoint::childBefore() const
86 {
87     return m_childBeforeBoundary.get();
88 }
89
90 inline void RangeBoundaryPoint::ensureOffsetIsValid() const
91 {
92     if (m_offsetInContainer >= 0)
93         return;
94
95     ASSERT(m_childBeforeBoundary);
96     m_offsetInContainer = m_childBeforeBoundary->computeNodeIndex() + 1;
97 }
98
99 inline const Position RangeBoundaryPoint::toPosition() const
100 {
101     ensureOffsetIsValid();
102     return createLegacyEditingPosition(m_containerNode.get(), m_offsetInContainer);
103 }
104
105 inline int RangeBoundaryPoint::offset() const
106 {
107     ensureOffsetIsValid();
108     return m_offsetInContainer;
109 }
110
111 inline void RangeBoundaryPoint::clear()
112 {
113     m_containerNode = nullptr;
114     m_offsetInContainer = 0;
115     m_childBeforeBoundary = nullptr;
116 }
117
118 inline void RangeBoundaryPoint::set(PassRefPtr<Node> container, int offset, Node* childBefore)
119 {
120     ASSERT(container);
121     ASSERT(offset >= 0);
122     ASSERT(childBefore == (offset ? container->traverseToChildAt(offset - 1) : 0));
123     m_containerNode = container;
124     m_offsetInContainer = offset;
125     m_childBeforeBoundary = childBefore;
126 }
127
128 inline void RangeBoundaryPoint::setOffset(int offset)
129 {
130     ASSERT(m_containerNode);
131     ASSERT(m_containerNode->offsetInCharacters());
132     ASSERT(m_offsetInContainer >= 0);
133     ASSERT(!m_childBeforeBoundary);
134     m_offsetInContainer = offset;
135 }
136
137 inline void RangeBoundaryPoint::setToBeforeChild(Node& child)
138 {
139     ASSERT(child.parentNode());
140     m_childBeforeBoundary = child.previousSibling();
141     m_containerNode = child.parentNode();
142     m_offsetInContainer = m_childBeforeBoundary ? invalidOffset : 0;
143 }
144
145 inline void RangeBoundaryPoint::setToStartOfNode(PassRefPtr<Node> container)
146 {
147     ASSERT(container);
148     m_containerNode = container;
149     m_offsetInContainer = 0;
150     m_childBeforeBoundary = nullptr;
151 }
152
153 inline void RangeBoundaryPoint::setToEndOfNode(PassRefPtr<Node> container)
154 {
155     ASSERT(container);
156     m_containerNode = container;
157     if (m_containerNode->offsetInCharacters()) {
158         m_offsetInContainer = m_containerNode->maxCharacterOffset();
159         m_childBeforeBoundary = nullptr;
160     } else {
161         m_childBeforeBoundary = m_containerNode->lastChild();
162         m_offsetInContainer = m_childBeforeBoundary ? invalidOffset : 0;
163     }
164 }
165
166 inline void RangeBoundaryPoint::childBeforeWillBeRemoved()
167 {
168     ASSERT(m_offsetInContainer);
169     m_childBeforeBoundary = m_childBeforeBoundary->previousSibling();
170     if (!m_childBeforeBoundary)
171         m_offsetInContainer = 0;
172     else if (m_offsetInContainer > 0)
173         --m_offsetInContainer;
174 }
175
176 inline void RangeBoundaryPoint::invalidateOffset() const
177 {
178     m_offsetInContainer = invalidOffset;
179 }
180
181 inline bool operator==(const RangeBoundaryPoint& a, const RangeBoundaryPoint& b)
182 {
183     if (a.container() != b.container())
184         return false;
185     if (a.childBefore() || b.childBefore()) {
186         if (a.childBefore() != b.childBefore())
187             return false;
188     } else {
189         if (a.offset() != b.offset())
190             return false;
191     }
192     return true;
193 }
194
195 }
196
197 #endif