1 /*
2  * Copyright (C) 2004 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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 THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_VISIBLE_UNITS_H_
27 #define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_VISIBLE_UNITS_H_
28 
29 #include "third_party/blink/renderer/core/core_export.h"
30 #include "third_party/blink/renderer/core/editing/editing_boundary.h"
31 #include "third_party/blink/renderer/core/editing/forward.h"
32 #include "third_party/blink/renderer/platform/geometry/layout_rect.h"
33 #include "third_party/blink/renderer/platform/text/text_direction.h"
34 #include "third_party/blink/renderer/platform/wtf/text/unicode.h"
35 
36 namespace blink {
37 
38 class LayoutObject;
39 class Node;
40 class IntPoint;
41 class IntRect;
42 class LocalFrame;
43 
44 // |WordSide| is used as a parameter of |StartOfWord()| and |EndOfWord()|
45 // to control a returning position when they are called for a position before
46 // word boundary.
47 enum WordSide {
48   kNextWordIfOnBoundary = false,
49   kPreviousWordIfOnBoundary = true
50 };
51 
52 enum class PlatformWordBehavior { kWordSkipSpaces, kWordDontSkipSpaces };
53 
54 // offset functions on Node
55 CORE_EXPORT int CaretMinOffset(const Node*);
56 CORE_EXPORT int CaretMaxOffset(const Node*);
57 
58 // Position
59 // mostForward/BackwardCaretPosition are used for moving back and forth between
60 // visually equivalent candidates.
61 // For example, for the text node "foo     bar" where whitespace is
62 // collapsible, there are two candidates that map to the VisiblePosition
63 // between 'b' and the space, after first space and before last space.
64 //
65 // mostBackwardCaretPosition returns the left candidate and also returs
66 // [boundary, 0] for any of the positions from [boundary, 0] to the first
67 // candidate in boundary, where
68 // endsOfNodeAreVisuallyDistinctPositions(boundary) is true.
69 //
70 // mostForwardCaretPosition() returns the right one and also returns the
71 // last position in the last atomic node in boundary for all of the positions
72 // in boundary after the last candidate, where
73 // endsOfNodeAreVisuallyDistinctPositions(boundary).
74 CORE_EXPORT Position MostBackwardCaretPosition(
75     const Position&,
76     EditingBoundaryCrossingRule = kCannotCrossEditingBoundary);
77 CORE_EXPORT PositionInFlatTree MostBackwardCaretPosition(
78     const PositionInFlatTree&,
79     EditingBoundaryCrossingRule = kCannotCrossEditingBoundary);
80 CORE_EXPORT Position MostForwardCaretPosition(
81     const Position&,
82     EditingBoundaryCrossingRule = kCannotCrossEditingBoundary);
83 CORE_EXPORT PositionInFlatTree MostForwardCaretPosition(
84     const PositionInFlatTree&,
85     EditingBoundaryCrossingRule = kCannotCrossEditingBoundary);
86 
87 CORE_EXPORT bool IsVisuallyEquivalentCandidate(const Position&);
88 CORE_EXPORT bool IsVisuallyEquivalentCandidate(const PositionInFlatTree&);
89 
90 // Whether or not [node, 0] and [node, lastOffsetForEditing(node)] are their own
91 // VisiblePositions.
92 // If true, adjacent candidates are visually distinct.
93 CORE_EXPORT bool EndsOfNodeAreVisuallyDistinctPositions(const Node*);
94 
95 CORE_EXPORT Position CanonicalPositionOf(const Position&);
96 CORE_EXPORT PositionInFlatTree CanonicalPositionOf(const PositionInFlatTree&);
97 
98 CORE_EXPORT UChar32 CharacterAfter(const VisiblePosition&);
99 CORE_EXPORT UChar32 CharacterAfter(const VisiblePositionInFlatTree&);
100 CORE_EXPORT UChar32 CharacterBefore(const VisiblePosition&);
101 CORE_EXPORT UChar32 CharacterBefore(const VisiblePositionInFlatTree&);
102 
103 CORE_EXPORT VisiblePosition
104 NextPositionOf(const VisiblePosition&,
105                EditingBoundaryCrossingRule = kCanCrossEditingBoundary);
106 CORE_EXPORT VisiblePositionInFlatTree
107 NextPositionOf(const VisiblePositionInFlatTree&,
108                EditingBoundaryCrossingRule = kCanCrossEditingBoundary);
109 CORE_EXPORT VisiblePosition
110 PreviousPositionOf(const VisiblePosition&,
111                    EditingBoundaryCrossingRule = kCanCrossEditingBoundary);
112 CORE_EXPORT VisiblePositionInFlatTree
113 PreviousPositionOf(const VisiblePositionInFlatTree&,
114                    EditingBoundaryCrossingRule = kCanCrossEditingBoundary);
115 
116 // words
117 // TODO(yoichio): Replace |startOfWord| to |startOfWordPosition| because
118 // returned Position should be canonicalized with |previousBoundary()| by
119 // TextItetator.
120 CORE_EXPORT Position StartOfWordPosition(const Position&,
121                                          WordSide = kNextWordIfOnBoundary);
122 CORE_EXPORT VisiblePosition StartOfWord(const VisiblePosition&,
123                                         WordSide = kNextWordIfOnBoundary);
124 CORE_EXPORT PositionInFlatTree
125 StartOfWordPosition(const PositionInFlatTree&,
126                     WordSide = kNextWordIfOnBoundary);
127 CORE_EXPORT VisiblePositionInFlatTree
128 StartOfWord(const VisiblePositionInFlatTree&, WordSide = kNextWordIfOnBoundary);
129 CORE_EXPORT VisiblePosition EndOfWord(const VisiblePosition&,
130                                       WordSide = kNextWordIfOnBoundary);
131 CORE_EXPORT Position EndOfWordPosition(const Position&,
132                                        WordSide = kNextWordIfOnBoundary);
133 CORE_EXPORT PositionInFlatTree
134 EndOfWordPosition(const PositionInFlatTree&, WordSide = kNextWordIfOnBoundary);
135 CORE_EXPORT VisiblePositionInFlatTree
136 EndOfWord(const VisiblePositionInFlatTree&, WordSide = kNextWordIfOnBoundary);
137 CORE_EXPORT PositionWithAffinity PreviousWordPosition(const Position&);
138 CORE_EXPORT PositionWithAffinity NextWordPosition(
139     const Position&,
140     PlatformWordBehavior = PlatformWordBehavior::kWordDontSkipSpaces);
141 
142 // sentences
143 CORE_EXPORT Position StartOfSentencePosition(const Position&);
144 CORE_EXPORT PositionInFlatTree
145 StartOfSentencePosition(const PositionInFlatTree&);
146 CORE_EXPORT VisiblePosition StartOfSentence(const VisiblePosition&);
147 CORE_EXPORT VisiblePositionInFlatTree
148 StartOfSentence(const VisiblePositionInFlatTree&);
149 CORE_EXPORT PositionWithAffinity EndOfSentence(const Position&);
150 CORE_EXPORT PositionInFlatTreeWithAffinity
151 EndOfSentence(const PositionInFlatTree&);
152 CORE_EXPORT VisiblePosition EndOfSentence(const VisiblePosition&);
153 CORE_EXPORT VisiblePositionInFlatTree
154 EndOfSentence(const VisiblePositionInFlatTree&);
155 VisiblePosition PreviousSentencePosition(const VisiblePosition&);
156 VisiblePosition NextSentencePosition(const VisiblePosition&);
157 EphemeralRange ExpandEndToSentenceBoundary(const EphemeralRange&);
158 EphemeralRange ExpandRangeToSentenceBoundary(const EphemeralRange&);
159 
160 // lines
161 // TODO(yosin) Return values of |VisiblePosition| version of |startOfLine()|
162 // with shadow tree isn't defined well. We should not use it for shadow tree.
163 CORE_EXPORT VisiblePosition StartOfLine(const VisiblePosition&);
164 CORE_EXPORT VisiblePositionInFlatTree
165 StartOfLine(const VisiblePositionInFlatTree&);
166 // TODO(yosin) Return values of |VisiblePosition| version of |endOfLine()| with
167 // shadow tree isn't defined well. We should not use it for shadow tree.
168 CORE_EXPORT VisiblePosition EndOfLine(const VisiblePosition&);
169 CORE_EXPORT VisiblePositionInFlatTree
170 EndOfLine(const VisiblePositionInFlatTree&);
171 CORE_EXPORT bool InSameLine(const VisiblePosition&, const VisiblePosition&);
172 CORE_EXPORT bool InSameLine(const VisiblePositionInFlatTree&,
173                             const VisiblePositionInFlatTree&);
174 CORE_EXPORT bool InSameLine(const PositionWithAffinity&,
175                             const PositionWithAffinity&);
176 CORE_EXPORT bool InSameLine(const PositionInFlatTreeWithAffinity&,
177                             const PositionInFlatTreeWithAffinity&);
178 CORE_EXPORT bool IsStartOfLine(const VisiblePosition&);
179 CORE_EXPORT bool IsStartOfLine(const VisiblePositionInFlatTree&);
180 CORE_EXPORT bool IsEndOfLine(const VisiblePosition&);
181 CORE_EXPORT bool IsEndOfLine(const VisiblePositionInFlatTree&);
182 // TODO(yosin) Return values of |VisiblePosition| version of
183 // |logicalStartOfLine()| with shadow tree isn't defined well. We should not use
184 // it for shadow tree.
185 CORE_EXPORT VisiblePosition LogicalStartOfLine(const VisiblePosition&);
186 CORE_EXPORT VisiblePositionInFlatTree
187 LogicalStartOfLine(const VisiblePositionInFlatTree&);
188 // TODO(yosin) Return values of |VisiblePosition| version of
189 // |logicalEndOfLine()| with shadow tree isn't defined well. We should not use
190 // it for shadow tree.
191 CORE_EXPORT VisiblePosition LogicalEndOfLine(const VisiblePosition&);
192 CORE_EXPORT VisiblePositionInFlatTree
193 LogicalEndOfLine(const VisiblePositionInFlatTree&);
194 CORE_EXPORT bool IsLogicalEndOfLine(const VisiblePosition&);
195 CORE_EXPORT bool IsLogicalEndOfLine(const VisiblePositionInFlatTree&);
196 
197 // paragraphs (perhaps a misnomer, can be divided by line break elements)
198 // TODO(yosin) Since return value of |startOfParagraph()| with |VisiblePosition|
199 // isn't defined well on flat tree, we should not use it for a position in
200 // flat tree.
201 CORE_EXPORT VisiblePosition
202 StartOfParagraph(const VisiblePosition&,
203                  EditingBoundaryCrossingRule = kCannotCrossEditingBoundary);
204 CORE_EXPORT VisiblePositionInFlatTree
205 StartOfParagraph(const VisiblePositionInFlatTree&,
206                  EditingBoundaryCrossingRule = kCannotCrossEditingBoundary);
207 CORE_EXPORT VisiblePosition
208 EndOfParagraph(const VisiblePosition&,
209                EditingBoundaryCrossingRule = kCannotCrossEditingBoundary);
210 CORE_EXPORT VisiblePositionInFlatTree
211 EndOfParagraph(const VisiblePositionInFlatTree&,
212                EditingBoundaryCrossingRule = kCannotCrossEditingBoundary);
213 VisiblePosition StartOfNextParagraph(const VisiblePosition&);
214 CORE_EXPORT bool IsStartOfParagraph(
215     const VisiblePosition&,
216     EditingBoundaryCrossingRule = kCannotCrossEditingBoundary);
217 CORE_EXPORT bool IsStartOfParagraph(const VisiblePositionInFlatTree&);
218 CORE_EXPORT bool IsEndOfParagraph(
219     const VisiblePosition&,
220     EditingBoundaryCrossingRule = kCannotCrossEditingBoundary);
221 CORE_EXPORT bool IsEndOfParagraph(const VisiblePositionInFlatTree&);
222 bool InSameParagraph(const VisiblePosition&,
223                      const VisiblePosition&,
224                      EditingBoundaryCrossingRule = kCannotCrossEditingBoundary);
225 EphemeralRange ExpandToParagraphBoundary(const EphemeralRange&);
226 
227 // document
228 CORE_EXPORT VisiblePosition StartOfDocument(const VisiblePosition&);
229 CORE_EXPORT VisiblePositionInFlatTree
230 StartOfDocument(const VisiblePositionInFlatTree&);
231 CORE_EXPORT VisiblePosition EndOfDocument(const VisiblePosition&);
232 CORE_EXPORT VisiblePositionInFlatTree
233 EndOfDocument(const VisiblePositionInFlatTree&);
234 bool IsStartOfDocument(const VisiblePosition&);
235 bool IsEndOfDocument(const VisiblePosition&);
236 
237 // editable content
238 VisiblePosition StartOfEditableContent(const VisiblePosition&);
239 VisiblePosition EndOfEditableContent(const VisiblePosition&);
240 CORE_EXPORT bool IsEndOfEditableOrNonEditableContent(const VisiblePosition&);
241 CORE_EXPORT bool IsEndOfEditableOrNonEditableContent(
242     const VisiblePositionInFlatTree&);
243 
244 bool HasRenderedNonAnonymousDescendantsWithHeight(const LayoutObject*);
245 
246 // TODO(editing-dev): We should move this functions to somewhere else.
247 // Returns a hit-tested PositionWithAffinity for the given point in
248 // contents-space coordinates.
249 CORE_EXPORT PositionWithAffinity
250 PositionForContentsPointRespectingEditingBoundary(const IntPoint&, LocalFrame*);
251 
252 CORE_EXPORT bool RendersInDifferentPosition(const Position&, const Position&);
253 
254 CORE_EXPORT Position SkipWhitespace(const Position&);
255 CORE_EXPORT PositionInFlatTree SkipWhitespace(const PositionInFlatTree&);
256 
257 CORE_EXPORT IntRect ComputeTextRect(const EphemeralRange&);
258 IntRect ComputeTextRect(const EphemeralRangeInFlatTree&);
259 FloatRect ComputeTextFloatRect(const EphemeralRange&);
260 
261 // |FirstRectForRange| requires up-to-date layout.
262 IntRect FirstRectForRange(const EphemeralRange&);
263 
264 CORE_EXPORT PositionWithAffinity
265 AdjustForwardPositionToAvoidCrossingEditingBoundaries(
266     const PositionWithAffinity&,
267     const Position&);
268 
269 PositionInFlatTreeWithAffinity
270 AdjustForwardPositionToAvoidCrossingEditingBoundaries(
271     const PositionInFlatTreeWithAffinity&,
272     const PositionInFlatTree&);
273 
274 PositionWithAffinity AdjustBackwardPositionToAvoidCrossingEditingBoundaries(
275     const PositionWithAffinity&,
276     const Position&);
277 
278 PositionInFlatTreeWithAffinity
279 AdjustBackwardPositionToAvoidCrossingEditingBoundaries(
280     const PositionInFlatTreeWithAffinity&,
281     const PositionInFlatTree&);
282 
283 VisiblePosition AdjustForwardPositionToAvoidCrossingEditingBoundaries(
284     const VisiblePosition&,
285     const Position&);
286 
287 VisiblePositionInFlatTree AdjustForwardPositionToAvoidCrossingEditingBoundaries(
288     const VisiblePositionInFlatTree&,
289     const PositionInFlatTree&);
290 
291 // Export below functions only for |SelectionModifier|.
292 VisiblePosition AdjustBackwardPositionToAvoidCrossingEditingBoundaries(
293     const VisiblePosition&,
294     const Position&);
295 
296 VisiblePositionInFlatTree
297 AdjustBackwardPositionToAvoidCrossingEditingBoundaries(
298     const VisiblePositionInFlatTree&,
299     const PositionInFlatTree&);
300 
301 }  // namespace blink
302 
303 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_VISIBLE_UNITS_H_
304