isEditablePosition and related functions shouldn't move position out of table
[WebKit-https.git] / Source / WebCore / dom / Position.cpp
1 /*
2  * Copyright (C) 2004, 2005, 2006, 2009, 2013 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 #include "config.h"
27 #include "Position.h"
28
29 #include "CSSComputedStyleDeclaration.h"
30 #include "HTMLNames.h"
31 #include "HTMLTableElement.h"
32 #include "InlineElementBox.h"
33 #include "InlineIterator.h"
34 #include "InlineTextBox.h"
35 #include "Logging.h"
36 #include "PositionIterator.h"
37 #include "RenderBlock.h"
38 #include "RenderFlexibleBox.h"
39 #include "RenderGrid.h"
40 #include "RenderInline.h"
41 #include "RenderIterator.h"
42 #include "RenderLineBreak.h"
43 #include "RenderText.h"
44 #include "RuntimeEnabledFeatures.h"
45 #include "Text.h"
46 #include "TextIterator.h"
47 #include "VisiblePosition.h"
48 #include "VisibleUnits.h"
49 #include "htmlediting.h"
50 #include <stdio.h>
51 #include <wtf/text/CString.h>
52 #include <wtf/unicode/CharacterNames.h>
53
54 namespace WebCore {
55
56 using namespace HTMLNames;
57
58 static bool hasInlineBoxWrapper(RenderObject& renderer)
59 {
60     if (is<RenderBox>(renderer) && downcast<RenderBox>(renderer).inlineBoxWrapper())
61         return true;
62     if (is<RenderText>(renderer) && downcast<RenderText>(renderer).firstTextBox())
63         return true;
64     if (is<RenderLineBreak>(renderer) && downcast<RenderLineBreak>(renderer).inlineBoxWrapper())
65         return true;
66     return false;
67 }
68
69 static Node* nextRenderedEditable(Node* node)
70 {
71     while ((node = nextLeafNode(node))) {
72         RenderObject* renderer = node->renderer();
73         if (!renderer || !node->hasEditableStyle())
74             continue;
75         if (hasInlineBoxWrapper(*renderer))
76             return node;
77     }
78     return 0;
79 }
80
81 static Node* previousRenderedEditable(Node* node)
82 {
83     while ((node = previousLeafNode(node))) {
84         RenderObject* renderer = node->renderer();
85         if (!renderer || !node->hasEditableStyle())
86             continue;
87         if (hasInlineBoxWrapper(*renderer))
88             return node;
89     }
90     return 0;
91 }
92
93 Position::Position(PassRefPtr<Node> anchorNode, LegacyEditingOffset offset)
94     : m_anchorNode(anchorNode)
95     , m_offset(offset.value())
96     , m_anchorType(anchorTypeForLegacyEditingPosition(m_anchorNode.get(), m_offset))
97     , m_isLegacyEditingPosition(true)
98 {
99     ASSERT(!m_anchorNode || !m_anchorNode->isShadowRoot() || m_anchorNode == containerNode());
100     ASSERT(!m_anchorNode || !m_anchorNode->isPseudoElement());
101 }
102
103 Position::Position(PassRefPtr<Node> anchorNode, AnchorType anchorType)
104     : m_anchorNode(anchorNode)
105     , m_offset(0)
106     , m_anchorType(anchorType)
107     , m_isLegacyEditingPosition(false)
108 {
109     ASSERT(!m_anchorNode || !m_anchorNode->isShadowRoot() || m_anchorNode == containerNode());
110     ASSERT(!m_anchorNode || !m_anchorNode->isPseudoElement());
111     ASSERT(anchorType != PositionIsOffsetInAnchor);
112     ASSERT(!((anchorType == PositionIsBeforeChildren || anchorType == PositionIsAfterChildren)
113         && (m_anchorNode->isTextNode() || editingIgnoresContent(m_anchorNode.get()))));
114 }
115
116 Position::Position(PassRefPtr<Node> anchorNode, int offset, AnchorType anchorType)
117     : m_anchorNode(anchorNode)
118     , m_offset(offset)
119     , m_anchorType(anchorType)
120     , m_isLegacyEditingPosition(false)
121 {
122     ASSERT(!m_anchorNode || !editingIgnoresContent(m_anchorNode.get()) || !m_anchorNode->isShadowRoot());
123     ASSERT(!m_anchorNode || !m_anchorNode->isPseudoElement());
124     ASSERT(anchorType == PositionIsOffsetInAnchor);
125 }
126
127 Position::Position(PassRefPtr<Text> textNode, unsigned offset)
128     : m_anchorNode(textNode)
129     , m_offset(static_cast<int>(offset))
130     , m_anchorType(PositionIsOffsetInAnchor)
131     , m_isLegacyEditingPosition(false)
132 {
133     ASSERT(m_anchorNode);
134 }
135
136 void Position::moveToPosition(PassRefPtr<Node> node, int offset)
137 {
138     ASSERT(!editingIgnoresContent(node.get()));
139     ASSERT(anchorType() == PositionIsOffsetInAnchor || m_isLegacyEditingPosition);
140     m_anchorNode = node;
141     m_offset = offset;
142     if (m_isLegacyEditingPosition)
143         m_anchorType = anchorTypeForLegacyEditingPosition(m_anchorNode.get(), m_offset);
144 }
145 void Position::moveToOffset(int offset)
146 {
147     ASSERT(anchorType() == PositionIsOffsetInAnchor || m_isLegacyEditingPosition);
148     m_offset = offset;
149     if (m_isLegacyEditingPosition)
150         m_anchorType = anchorTypeForLegacyEditingPosition(m_anchorNode.get(), m_offset);
151 }
152
153 Node* Position::containerNode() const
154 {
155     if (!m_anchorNode)
156         return nullptr;
157
158     switch (anchorType()) {
159     case PositionIsBeforeChildren:
160     case PositionIsAfterChildren:
161     case PositionIsOffsetInAnchor:
162         return m_anchorNode.get();
163     case PositionIsBeforeAnchor:
164     case PositionIsAfterAnchor:
165         return findParent(m_anchorNode.get());
166     }
167     ASSERT_NOT_REACHED();
168     return nullptr;
169 }
170
171 Text* Position::containerText() const
172 {
173     switch (anchorType()) {
174     case PositionIsOffsetInAnchor:
175         return m_anchorNode && is<Text>(*m_anchorNode) ? downcast<Text>(m_anchorNode.get()) : nullptr;
176     case PositionIsBeforeAnchor:
177     case PositionIsAfterAnchor:
178         return nullptr;
179     case PositionIsBeforeChildren:
180     case PositionIsAfterChildren:
181         ASSERT(!m_anchorNode || !is<Text>(*m_anchorNode));
182         return nullptr;
183     }
184     ASSERT_NOT_REACHED();
185     return nullptr;
186 }
187
188 int Position::computeOffsetInContainerNode() const
189 {
190     if (!m_anchorNode)
191         return 0;
192
193     switch (anchorType()) {
194     case PositionIsBeforeChildren:
195         return 0;
196     case PositionIsAfterChildren:
197         return lastOffsetInNode(m_anchorNode.get());
198     case PositionIsOffsetInAnchor:
199         return minOffsetForNode(m_anchorNode.get(), m_offset);
200     case PositionIsBeforeAnchor:
201         return m_anchorNode->computeNodeIndex();
202     case PositionIsAfterAnchor:
203         return m_anchorNode->computeNodeIndex() + 1;
204     }
205     ASSERT_NOT_REACHED();
206     return 0;
207 }
208
209 int Position::offsetForPositionAfterAnchor() const
210 {
211     ASSERT(m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAfterChildren);
212     ASSERT(!m_isLegacyEditingPosition);
213     return lastOffsetForEditing(m_anchorNode.get());
214 }
215
216 // Neighbor-anchored positions are invalid DOM positions, so they need to be
217 // fixed up before handing them off to the Range object.
218 Position Position::parentAnchoredEquivalent() const
219 {
220     if (!m_anchorNode)
221         return Position();
222     
223     // FIXME: This should only be necessary for legacy positions, but is also needed for positions before and after Tables
224     if (m_offset <= 0 && (m_anchorType != PositionIsAfterAnchor && m_anchorType != PositionIsAfterChildren)) {
225         if (findParent(m_anchorNode.get()) && (editingIgnoresContent(m_anchorNode.get()) || isRenderedTable(m_anchorNode.get())))
226             return positionInParentBeforeNode(m_anchorNode.get());
227         return Position(m_anchorNode.get(), 0, PositionIsOffsetInAnchor);
228     }
229
230     if (!m_anchorNode->offsetInCharacters()
231         && (m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAfterChildren || static_cast<unsigned>(m_offset) == m_anchorNode->countChildNodes())
232         && (editingIgnoresContent(m_anchorNode.get()) || isRenderedTable(m_anchorNode.get()))
233         && containerNode()) {
234         return positionInParentAfterNode(m_anchorNode.get());
235     }
236
237     return Position(containerNode(), computeOffsetInContainerNode(), PositionIsOffsetInAnchor);
238 }
239
240 Node* Position::computeNodeBeforePosition() const
241 {
242     if (!m_anchorNode)
243         return 0;
244
245     switch (anchorType()) {
246     case PositionIsBeforeChildren:
247         return 0;
248     case PositionIsAfterChildren:
249         return m_anchorNode->lastChild();
250     case PositionIsOffsetInAnchor:
251         return m_offset ? m_anchorNode->traverseToChildAt(m_offset - 1) : nullptr;
252     case PositionIsBeforeAnchor:
253         return m_anchorNode->previousSibling();
254     case PositionIsAfterAnchor:
255         return m_anchorNode.get();
256     }
257     ASSERT_NOT_REACHED();
258     return 0;
259 }
260
261 Node* Position::computeNodeAfterPosition() const
262 {
263     if (!m_anchorNode)
264         return 0;
265
266     switch (anchorType()) {
267     case PositionIsBeforeChildren:
268         return m_anchorNode->firstChild();
269     case PositionIsAfterChildren:
270         return 0;
271     case PositionIsOffsetInAnchor:
272         return m_anchorNode->traverseToChildAt(m_offset);
273     case PositionIsBeforeAnchor:
274         return m_anchorNode.get();
275     case PositionIsAfterAnchor:
276         return m_anchorNode->nextSibling();
277     }
278     ASSERT_NOT_REACHED();
279     return 0;
280 }
281
282 Position::AnchorType Position::anchorTypeForLegacyEditingPosition(Node* anchorNode, int offset)
283 {
284     if (anchorNode && editingIgnoresContent(anchorNode)) {
285         if (offset == 0)
286             return Position::PositionIsBeforeAnchor;
287         return Position::PositionIsAfterAnchor;
288     }
289     return Position::PositionIsOffsetInAnchor;
290 }
291
292 // FIXME: This method is confusing (does it return anchorNode() or containerNode()?) and should be renamed or removed
293 Element* Position::element() const
294 {
295     Node* node = anchorNode();
296     while (node && !is<Element>(*node))
297         node = node->parentNode();
298     return downcast<Element>(node);
299 }
300
301 Position Position::previous(PositionMoveType moveType) const
302 {
303     Node* node = deprecatedNode();
304     if (!node)
305         return *this;
306
307     int offset = deprecatedEditingOffset();
308     // FIXME: Negative offsets shouldn't be allowed. We should catch this earlier.
309     ASSERT(offset >= 0);
310
311     if (anchorType() == PositionIsBeforeAnchor) {
312         node = containerNode();
313         offset = computeOffsetInContainerNode();
314     }
315
316     if (offset > 0) {
317         if (Node* child = node->traverseToChildAt(offset - 1))
318             return lastPositionInOrAfterNode(child);
319
320         // There are two reasons child might be 0:
321         //   1) The node is node like a text node that is not an element, and therefore has no children.
322         //      Going backward one character at a time is correct.
323         //   2) The old offset was a bogus offset like (<br>, 1), and there is no child.
324         //      Going from 1 to 0 is correct.
325         switch (moveType) {
326         case CodePoint:
327             return createLegacyEditingPosition(node, offset - 1);
328         case Character:
329             return createLegacyEditingPosition(node, uncheckedPreviousOffset(node, offset));
330         case BackwardDeletion:
331             return createLegacyEditingPosition(node, uncheckedPreviousOffsetForBackwardDeletion(node, offset));
332         }
333     }
334
335     ContainerNode* parent = findParent(node);
336     if (!parent)
337         return *this;
338
339     if (positionBeforeOrAfterNodeIsCandidate(node))
340         return positionBeforeNode(node);
341
342     Node* previousSibling = node->previousSibling();
343     if (previousSibling && positionBeforeOrAfterNodeIsCandidate(previousSibling))
344         return positionAfterNode(previousSibling);
345
346     return createLegacyEditingPosition(parent, node->computeNodeIndex());
347 }
348
349 Position Position::next(PositionMoveType moveType) const
350 {
351     ASSERT(moveType != BackwardDeletion);
352
353     Node* node = deprecatedNode();
354     if (!node)
355         return *this;
356
357     int offset = deprecatedEditingOffset();
358     // FIXME: Negative offsets shouldn't be allowed. We should catch this earlier.
359     ASSERT(offset >= 0);
360
361     if (anchorType() == PositionIsAfterAnchor) {
362         node = containerNode();
363         offset = computeOffsetInContainerNode();
364     }
365
366     Node* child = node->traverseToChildAt(offset);
367     if (child || (!node->hasChildNodes() && offset < lastOffsetForEditing(node))) {
368         if (child)
369             return firstPositionInOrBeforeNode(child);
370
371         // There are two reasons child might be 0:
372         //   1) The node is node like a text node that is not an element, and therefore has no children.
373         //      Going forward one character at a time is correct.
374         //   2) The new offset is a bogus offset like (<br>, 1), and there is no child.
375         //      Going from 0 to 1 is correct.
376         return createLegacyEditingPosition(node, (moveType == Character) ? uncheckedNextOffset(node, offset) : offset + 1);
377     }
378
379     ContainerNode* parent = findParent(node);
380     if (!parent)
381         return *this;
382
383     if (isRenderedTable(node) || editingIgnoresContent(node))
384         return positionAfterNode(node);
385
386     Node* nextSibling = node->nextSibling();
387     if (nextSibling && positionBeforeOrAfterNodeIsCandidate(nextSibling))
388         return positionBeforeNode(nextSibling);
389
390     return createLegacyEditingPosition(parent, node->computeNodeIndex() + 1);
391 }
392
393 int Position::uncheckedPreviousOffset(const Node* n, int current)
394 {
395     return n->renderer() ? n->renderer()->previousOffset(current) : current - 1;
396 }
397
398 int Position::uncheckedPreviousOffsetForBackwardDeletion(const Node* n, int current)
399 {
400     return n->renderer() ? n->renderer()->previousOffsetForBackwardDeletion(current) : current - 1;
401 }
402
403 int Position::uncheckedNextOffset(const Node* n, int current)
404 {
405     return n->renderer() ? n->renderer()->nextOffset(current) : current + 1;
406 }
407
408 bool Position::atFirstEditingPositionForNode() const
409 {
410     if (isNull())
411         return true;
412     // FIXME: Position before anchor shouldn't be considered as at the first editing position for node
413     // since that position resides outside of the node.
414     switch (m_anchorType) {
415     case PositionIsOffsetInAnchor:
416         return m_offset <= 0;
417     case PositionIsBeforeChildren:
418     case PositionIsBeforeAnchor:
419         return true;
420     case PositionIsAfterChildren:
421     case PositionIsAfterAnchor:
422         return !lastOffsetForEditing(deprecatedNode());
423     }
424     ASSERT_NOT_REACHED();
425     return false;
426 }
427
428 bool Position::atLastEditingPositionForNode() const
429 {
430     if (isNull())
431         return true;
432     // FIXME: Position after anchor shouldn't be considered as at the first editing position for node
433     // since that position resides outside of the node.
434     return m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAfterChildren || m_offset >= lastOffsetForEditing(deprecatedNode());
435 }
436
437 // A position is considered at editing boundary if one of the following is true:
438 // 1. It is the first position in the node and the next visually equivalent position
439 //    is non editable.
440 // 2. It is the last position in the node and the previous visually equivalent position
441 //    is non editable.
442 // 3. It is an editable position and both the next and previous visually equivalent
443 //    positions are both non editable.
444 bool Position::atEditingBoundary() const
445 {
446     Position nextPosition = downstream(CanCrossEditingBoundary);
447     if (atFirstEditingPositionForNode() && nextPosition.isNotNull() && !nextPosition.deprecatedNode()->hasEditableStyle())
448         return true;
449         
450     Position prevPosition = upstream(CanCrossEditingBoundary);
451     if (atLastEditingPositionForNode() && prevPosition.isNotNull() && !prevPosition.deprecatedNode()->hasEditableStyle())
452         return true;
453         
454     return nextPosition.isNotNull() && !nextPosition.deprecatedNode()->hasEditableStyle()
455         && prevPosition.isNotNull() && !prevPosition.deprecatedNode()->hasEditableStyle();
456 }
457
458 Node* Position::parentEditingBoundary() const
459 {
460     if (!m_anchorNode)
461         return 0;
462
463     Node* documentElement = m_anchorNode->document().documentElement();
464     if (!documentElement)
465         return 0;
466
467     Node* boundary = m_anchorNode.get();
468     while (boundary != documentElement && boundary->nonShadowBoundaryParentNode() && m_anchorNode->hasEditableStyle() == boundary->parentNode()->hasEditableStyle())
469         boundary = boundary->nonShadowBoundaryParentNode();
470     
471     return boundary;
472 }
473
474
475 bool Position::atStartOfTree() const
476 {
477     if (isNull())
478         return true;
479     return !findParent(containerNode()) && atFirstEditingPositionForNode();
480 }
481
482 bool Position::atEndOfTree() const
483 {
484     if (isNull())
485         return true;
486     return !findParent(containerNode()) && atLastEditingPositionForNode();
487 }
488
489 // return first preceding DOM position rendered at a different location, or "this"
490 Position Position::previousCharacterPosition(EAffinity affinity) const
491 {
492     if (isNull())
493         return Position();
494
495     Node* fromRootEditableElement = deprecatedNode()->rootEditableElement();
496
497     bool atStartOfLine = isStartOfLine(VisiblePosition(*this, affinity));
498     bool rendered = isCandidate();
499     
500     Position currentPos = *this;
501     while (!currentPos.atStartOfTree()) {
502         currentPos = currentPos.previous();
503
504         if (currentPos.deprecatedNode()->rootEditableElement() != fromRootEditableElement)
505             return *this;
506
507         if (atStartOfLine || !rendered) {
508             if (currentPos.isCandidate())
509                 return currentPos;
510         } else if (rendersInDifferentPosition(currentPos))
511             return currentPos;
512     }
513     
514     return *this;
515 }
516
517 // return first following position rendered at a different location, or "this"
518 Position Position::nextCharacterPosition(EAffinity affinity) const
519 {
520     if (isNull())
521         return Position();
522
523     Node* fromRootEditableElement = deprecatedNode()->rootEditableElement();
524
525     bool atEndOfLine = isEndOfLine(VisiblePosition(*this, affinity));
526     bool rendered = isCandidate();
527     
528     Position currentPos = *this;
529     while (!currentPos.atEndOfTree()) {
530         currentPos = currentPos.next();
531
532         if (currentPos.deprecatedNode()->rootEditableElement() != fromRootEditableElement)
533             return *this;
534
535         if (atEndOfLine || !rendered) {
536             if (currentPos.isCandidate())
537                 return currentPos;
538         } else if (rendersInDifferentPosition(currentPos))
539             return currentPos;
540     }
541     
542     return *this;
543 }
544
545 // Whether or not [node, 0] and [node, lastOffsetForEditing(node)] are their own VisiblePositions.
546 // If true, adjacent candidates are visually distinct.
547 // FIXME: Disregard nodes with renderers that have no height, as we do in isCandidate.
548 // FIXME: Share code with isCandidate, if possible.
549 static bool endsOfNodeAreVisuallyDistinctPositions(Node* node)
550 {
551     if (!node || !node->renderer())
552         return false;
553         
554     if (!node->renderer()->isInline())
555         return true;
556         
557     // Don't include inline tables.
558     if (is<HTMLTableElement>(*node))
559         return false;
560     
561     // There is a VisiblePosition inside an empty inline-block container.
562     return node->renderer()->isReplaced() && canHaveChildrenForEditing(node) && downcast<RenderBox>(*node->renderer()).height() && !node->firstChild();
563 }
564
565 static Node* enclosingVisualBoundary(Node* node)
566 {
567     while (node && !endsOfNodeAreVisuallyDistinctPositions(node))
568         node = node->parentNode();
569         
570     return node;
571 }
572
573 // upstream() and downstream() want to return positions that are either in a
574 // text node or at just before a non-text node.  This method checks for that.
575 static bool isStreamer(const PositionIterator& pos)
576 {
577     if (!pos.node())
578         return true;
579         
580     if (isAtomicNode(pos.node()))
581         return true;
582         
583     return pos.atStartOfNode();
584 }
585
586 // This function and downstream() are used for moving back and forth between visually equivalent candidates.
587 // For example, for the text node "foo     bar" where whitespace is collapsible, there are two candidates 
588 // that map to the VisiblePosition between 'b' and the space.  This function will return the left candidate 
589 // and downstream() will return the right one.
590 // Also, upstream() will return [boundary, 0] for any of the positions from [boundary, 0] to the first candidate
591 // in boundary, where endsOfNodeAreVisuallyDistinctPositions(boundary) is true.
592 Position Position::upstream(EditingBoundaryCrossingRule rule) const
593 {
594     Node* startNode = deprecatedNode();
595     if (!startNode)
596         return Position();
597     
598     // iterate backward from there, looking for a qualified position
599     Node* boundary = enclosingVisualBoundary(startNode);
600     // FIXME: PositionIterator should respect Before and After positions.
601     PositionIterator lastVisible = m_anchorType == PositionIsAfterAnchor ? createLegacyEditingPosition(m_anchorNode.get(), caretMaxOffset(m_anchorNode.get())) : *this;
602     PositionIterator currentPos = lastVisible;
603     bool startEditable = startNode->hasEditableStyle();
604     Node* lastNode = startNode;
605     bool boundaryCrossed = false;
606     for (; !currentPos.atStart(); currentPos.decrement()) {
607         Node* currentNode = currentPos.node();
608         
609         // Don't check for an editability change if we haven't moved to a different node,
610         // to avoid the expense of computing hasEditableStyle().
611         if (currentNode != lastNode) {
612             // Don't change editability.
613             bool currentEditable = currentNode->hasEditableStyle();
614             if (startEditable != currentEditable) {
615                 if (rule == CannotCrossEditingBoundary)
616                     break;
617                 boundaryCrossed = true;
618             }
619             lastNode = currentNode;
620         }
621
622         // If we've moved to a position that is visually distinct, return the last saved position. There 
623         // is code below that terminates early if we're *about* to move to a visually distinct position.
624         if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentNode != boundary)
625             return lastVisible;
626
627         // skip position in unrendered or invisible node
628         RenderObject* renderer = currentNode->renderer();
629         if (!renderer || renderer->style().visibility() != VISIBLE)
630             continue;
631                  
632         if (rule == CanCrossEditingBoundary && boundaryCrossed) {
633             lastVisible = currentPos;
634             break;
635         }
636         
637         // track last visible streamer position
638         if (isStreamer(currentPos))
639             lastVisible = currentPos;
640         
641         // Don't move past a position that is visually distinct.  We could rely on code above to terminate and 
642         // return lastVisible on the next iteration, but we terminate early to avoid doing a computeNodeIndex() call.
643         if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentPos.atStartOfNode())
644             return lastVisible;
645
646         // Return position after tables and nodes which have content that can be ignored.
647         if (editingIgnoresContent(currentNode) || isRenderedTable(currentNode)) {
648             if (currentPos.atEndOfNode())
649                 return positionAfterNode(currentNode);
650             continue;
651         }
652
653         // return current position if it is in rendered text
654         if (is<RenderText>(*renderer)) {
655             auto& textRenderer = downcast<RenderText>(*renderer);
656             textRenderer.ensureLineBoxes();
657
658             if (!textRenderer.firstTextBox())
659                 continue;
660             if (currentNode != startNode) {
661                 // This assertion fires in layout tests in the case-transform.html test because
662                 // of a mix-up between offsets in the text in the DOM tree with text in the
663                 // render tree which can have a different length due to case transformation.
664                 // Until we resolve that, disable this so we can run the layout tests!
665                 //ASSERT(currentOffset >= renderer->caretMaxOffset());
666                 return createLegacyEditingPosition(currentNode, renderer->caretMaxOffset());
667             }
668
669             unsigned textOffset = currentPos.offsetInLeafNode();
670             auto lastTextBox = textRenderer.lastTextBox();
671             for (auto box = textRenderer.firstTextBox(); box; box = box->nextTextBox()) {
672                 if (textOffset <= box->start() + box->len()) {
673                     if (textOffset > box->start())
674                         return currentPos;
675                     continue;
676                 }
677
678                 if (box == lastTextBox || textOffset != box->start() + box->len() + 1)
679                     continue;
680
681                 // The text continues on the next line only if the last text box is not on this line and
682                 // none of the boxes on this line have a larger start offset.
683
684                 bool continuesOnNextLine = true;
685                 InlineBox* otherBox = box;
686                 while (continuesOnNextLine) {
687                     otherBox = otherBox->nextLeafChild();
688                     if (!otherBox)
689                         break;
690                     if (otherBox == lastTextBox || (&otherBox->renderer() == &textRenderer && downcast<InlineTextBox>(*otherBox).start() > textOffset))
691                         continuesOnNextLine = false;
692                 }
693
694                 otherBox = box;
695                 while (continuesOnNextLine) {
696                     otherBox = otherBox->prevLeafChild();
697                     if (!otherBox)
698                         break;
699                     if (otherBox == lastTextBox || (&otherBox->renderer() == &textRenderer && downcast<InlineTextBox>(*otherBox).start() > textOffset))
700                         continuesOnNextLine = false;
701                 }
702
703                 if (continuesOnNextLine)
704                     return currentPos;
705             }
706         }
707     }
708
709     return lastVisible;
710 }
711
712 // This function and upstream() are used for moving back and forth between visually equivalent candidates.
713 // For example, for the text node "foo     bar" where whitespace is collapsible, there are two candidates 
714 // that map to the VisiblePosition between 'b' and the space.  This function will return the right candidate 
715 // and upstream() will return the left one.
716 // Also, downstream() will return the last position in the last atomic node in boundary for all of the positions
717 // in boundary after the last candidate, where endsOfNodeAreVisuallyDistinctPositions(boundary).
718 // FIXME: This function should never be called when the line box tree is dirty. See https://bugs.webkit.org/show_bug.cgi?id=97264
719 Position Position::downstream(EditingBoundaryCrossingRule rule) const
720 {
721     Node* startNode = deprecatedNode();
722     if (!startNode)
723         return Position();
724
725     // iterate forward from there, looking for a qualified position
726     Node* boundary = enclosingVisualBoundary(startNode);
727     // FIXME: PositionIterator should respect Before and After positions.
728     PositionIterator lastVisible = m_anchorType == PositionIsAfterAnchor ? createLegacyEditingPosition(m_anchorNode.get(), caretMaxOffset(m_anchorNode.get())) : *this;
729     PositionIterator currentPos = lastVisible;
730     bool startEditable = startNode->hasEditableStyle();
731     Node* lastNode = startNode;
732     bool boundaryCrossed = false;
733     for (; !currentPos.atEnd(); currentPos.increment()) {   
734         Node* currentNode = currentPos.node();
735         
736         // Don't check for an editability change if we haven't moved to a different node,
737         // to avoid the expense of computing hasEditableStyle().
738         if (currentNode != lastNode) {
739             // Don't change editability.
740             bool currentEditable = currentNode->hasEditableStyle();
741             if (startEditable != currentEditable) {
742                 if (rule == CannotCrossEditingBoundary)
743                     break;
744                 boundaryCrossed = true;
745             }
746                 
747             lastNode = currentNode;
748         }
749
750         // stop before going above the body, up into the head
751         // return the last visible streamer position
752         if (currentNode->hasTagName(bodyTag) && currentPos.atEndOfNode())
753             break;
754             
755         // Do not move to a visually distinct position.
756         if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentNode != boundary)
757             return lastVisible;
758         // Do not move past a visually disinct position.
759         // Note: The first position after the last in a node whose ends are visually distinct
760         // positions will be [boundary->parentNode(), originalBlock->computeNodeIndex() + 1].
761         if (boundary && boundary->parentNode() == currentNode)
762             return lastVisible;
763
764         // skip position in unrendered or invisible node
765         RenderObject* renderer = currentNode->renderer();
766         if (!renderer || renderer->style().visibility() != VISIBLE)
767             continue;
768             
769         if (rule == CanCrossEditingBoundary && boundaryCrossed) {
770             lastVisible = currentPos;
771             break;
772         }
773         
774         // track last visible streamer position
775         if (isStreamer(currentPos))
776             lastVisible = currentPos;
777
778         // Return position before tables and nodes which have content that can be ignored.
779         if (editingIgnoresContent(currentNode) || isRenderedTable(currentNode)) {
780             if (currentPos.offsetInLeafNode() <= renderer->caretMinOffset())
781                 return positionBeforeNode(currentNode);
782             continue;
783         }
784
785         // return current position if it is in rendered text
786         if (is<RenderText>(*renderer)) {
787             auto& textRenderer = downcast<RenderText>(*renderer);
788             textRenderer.ensureLineBoxes();
789
790             if (!textRenderer.firstTextBox())
791                 continue;
792             if (currentNode != startNode) {
793                 ASSERT(currentPos.atStartOfNode());
794                 return createLegacyEditingPosition(currentNode, renderer->caretMinOffset());
795             }
796
797             unsigned textOffset = currentPos.offsetInLeafNode();
798             auto lastTextBox = textRenderer.lastTextBox();
799             for (auto box = textRenderer.firstTextBox(); box; box = box->nextTextBox()) {
800                 if (textOffset <= box->end()) {
801                     if (textOffset >= box->start())
802                         return currentPos;
803                     continue;
804                 }
805
806                 if (box == lastTextBox || textOffset != box->start() + box->len())
807                     continue;
808
809                 // The text continues on the next line only if the last text box is not on this line and
810                 // none of the boxes on this line have a larger start offset.
811
812                 bool continuesOnNextLine = true;
813                 InlineBox* otherBox = box;
814                 while (continuesOnNextLine) {
815                     otherBox = otherBox->nextLeafChild();
816                     if (!otherBox)
817                         break;
818                     if (otherBox == lastTextBox || (&otherBox->renderer() == &textRenderer && downcast<InlineTextBox>(*otherBox).start() >= textOffset))
819                         continuesOnNextLine = false;
820                 }
821
822                 otherBox = box;
823                 while (continuesOnNextLine) {
824                     otherBox = otherBox->prevLeafChild();
825                     if (!otherBox)
826                         break;
827                     if (otherBox == lastTextBox || (&otherBox->renderer() == &textRenderer && downcast<InlineTextBox>(*otherBox).start() >= textOffset))
828                         continuesOnNextLine = false;
829                 }
830
831                 if (continuesOnNextLine)
832                     return currentPos;
833             }
834         }
835     }
836     
837     return lastVisible;
838 }
839
840 unsigned Position::positionCountBetweenPositions(const Position& a, const Position& b)
841 {
842     if (a.isNull() || b.isNull())
843         return UINT_MAX;
844     
845     Position endPos;
846     Position pos;
847     if (a > b) {
848         endPos = a;
849         pos = b;
850     } else if (a < b) {
851         endPos = b;
852         pos = a;
853     } else
854         return 0;
855     
856     unsigned posCount = 0;
857     while (!pos.atEndOfTree() && pos != endPos) {
858         pos = pos.next();
859         ++posCount;
860     }
861     return posCount;
862 }
863
864 static int boundingBoxLogicalHeight(RenderObject *o, const IntRect &rect)
865 {
866     return o->style().isHorizontalWritingMode() ? rect.height() : rect.width();
867 }
868
869 bool Position::hasRenderedNonAnonymousDescendantsWithHeight(const RenderElement& renderer)
870 {
871     RenderObject* stop = renderer.nextInPreOrderAfterChildren();
872     for (RenderObject* o = renderer.firstChild(); o && o != stop; o = o->nextInPreOrder()) {
873         if (!o->nonPseudoNode())
874             continue;
875         if (is<RenderText>(*o)) {
876             if (boundingBoxLogicalHeight(o, downcast<RenderText>(*o).linesBoundingBox()))
877                 return true;
878             continue;
879         }
880         if (is<RenderLineBreak>(*o)) {
881             if (boundingBoxLogicalHeight(o, downcast<RenderLineBreak>(*o).linesBoundingBox()))
882                 return true;
883             continue;
884         }
885         if (is<RenderBox>(*o)) {
886             if (downcast<RenderBox>(*o).pixelSnappedLogicalHeight())
887                 return true;
888             continue;
889         }
890         if (is<RenderInline>(*o)) {
891             const RenderInline& renderInline = downcast<RenderInline>(*o);
892             if (isEmptyInline(renderInline) && boundingBoxLogicalHeight(o, renderInline.linesBoundingBox()))
893                 return true;
894             continue;
895         }
896     }
897     return false;
898 }
899
900 bool Position::nodeIsUserSelectNone(Node* node)
901 {
902     return node && node->renderer() && node->renderer()->style().userSelect() == SELECT_NONE;
903 }
904
905 ContainerNode* Position::findParent(const Node* node)
906 {
907     return node->nonShadowBoundaryParentNode();
908 }
909
910 #if ENABLE(USERSELECT_ALL)
911 bool Position::nodeIsUserSelectAll(const Node* node)
912 {
913     return node && node->renderer() && node->renderer()->style().userSelect() == SELECT_ALL;
914 }
915
916 Node* Position::rootUserSelectAllForNode(Node* node)
917 {
918     if (!node || !nodeIsUserSelectAll(node))
919         return 0;
920     Node* parent = node->parentNode();
921     if (!parent)
922         return node;
923
924     Node* candidateRoot = node;
925     while (parent) {
926         if (!parent->renderer()) {
927             parent = parent->parentNode();
928             continue;
929         }
930         if (!nodeIsUserSelectAll(parent))
931             break;
932         candidateRoot = parent;
933         parent = candidateRoot->parentNode();
934     }
935     return candidateRoot;
936 }
937 #endif
938
939 bool Position::isCandidate() const
940 {
941     if (isNull())
942         return false;
943
944     RenderObject* renderer = deprecatedNode()->renderer();
945     if (!renderer)
946         return false;
947
948     if (renderer->style().visibility() != VISIBLE)
949         return false;
950
951     if (renderer->isBR())
952         // FIXME: The condition should be m_anchorType == PositionIsBeforeAnchor, but for now we still need to support legacy positions.
953         return !m_offset && m_anchorType != PositionIsAfterAnchor && !nodeIsUserSelectNone(deprecatedNode()->parentNode());
954
955     if (is<RenderText>(*renderer))
956         return !nodeIsUserSelectNone(deprecatedNode()) && downcast<RenderText>(*renderer).containsCaretOffset(m_offset);
957
958     if (positionBeforeOrAfterNodeIsCandidate(deprecatedNode())) {
959         return ((atFirstEditingPositionForNode() && m_anchorType == PositionIsBeforeAnchor)
960             || (atLastEditingPositionForNode() && m_anchorType == PositionIsAfterAnchor))
961             && !nodeIsUserSelectNone(deprecatedNode()->parentNode());
962     }
963
964     if (m_anchorNode->hasTagName(htmlTag))
965         return false;
966
967     if (is<RenderBlockFlow>(*renderer)
968 #if ENABLE(CSS_GRID_LAYOUT)
969         || is<RenderGrid>(*renderer)
970 #endif
971         || is<RenderFlexibleBox>(*renderer)) {
972         RenderBlock& block = downcast<RenderBlock>(*renderer);
973         if (block.logicalHeight() || m_anchorNode->hasTagName(bodyTag)) {
974             if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(block))
975                 return atFirstEditingPositionForNode() && !Position::nodeIsUserSelectNone(deprecatedNode());
976             return m_anchorNode->hasEditableStyle() && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
977         }
978         return false;
979     }
980
981     return m_anchorNode->hasEditableStyle() && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
982 }
983
984 bool Position::isRenderedCharacter() const
985 {
986     if (!is<Text>(deprecatedNode()))
987         return false;
988
989     RenderText* renderer = downcast<Text>(*deprecatedNode()).renderer();
990     if (!renderer)
991         return false;
992
993     return renderer->containsRenderedCharacterOffset(m_offset);
994 }
995
996 static bool inSameEnclosingBlockFlowElement(Node* a, Node* b)
997 {
998     return a && b && deprecatedEnclosingBlockFlowElement(a) == deprecatedEnclosingBlockFlowElement(b);
999 }
1000
1001 bool Position::rendersInDifferentPosition(const Position &pos) const
1002 {
1003     if (isNull() || pos.isNull())
1004         return false;
1005
1006     RenderObject* renderer = deprecatedNode()->renderer();
1007     if (!renderer)
1008         return false;
1009     
1010     RenderObject* posRenderer = pos.deprecatedNode()->renderer();
1011     if (!posRenderer)
1012         return false;
1013
1014     if (renderer->style().visibility() != VISIBLE ||
1015         posRenderer->style().visibility() != VISIBLE)
1016         return false;
1017     
1018     if (deprecatedNode() == pos.deprecatedNode()) {
1019         if (deprecatedNode()->hasTagName(brTag))
1020             return false;
1021
1022         if (m_offset == pos.deprecatedEditingOffset())
1023             return false;
1024             
1025         if (!deprecatedNode()->isTextNode() && !pos.deprecatedNode()->isTextNode()) {
1026             if (m_offset != pos.deprecatedEditingOffset())
1027                 return true;
1028         }
1029     }
1030     
1031     if (deprecatedNode()->hasTagName(brTag) && pos.isCandidate())
1032         return true;
1033                 
1034     if (pos.deprecatedNode()->hasTagName(brTag) && isCandidate())
1035         return true;
1036                 
1037     if (!inSameEnclosingBlockFlowElement(deprecatedNode(), pos.deprecatedNode()))
1038         return true;
1039
1040     if (is<RenderText>(*renderer) && !downcast<RenderText>(*renderer).containsCaretOffset(m_offset))
1041         return false;
1042
1043     if (is<RenderText>(*posRenderer) && !downcast<RenderText>(*posRenderer).containsCaretOffset(pos.m_offset))
1044         return false;
1045
1046     int thisRenderedOffset = is<RenderText>(*renderer) ? downcast<RenderText>(*renderer).countRenderedCharacterOffsetsUntil(m_offset) : m_offset;
1047     int posRenderedOffset = is<RenderText>(*posRenderer) ? downcast<RenderText>(*posRenderer).countRenderedCharacterOffsetsUntil(pos.m_offset) : pos.m_offset;
1048
1049     if (renderer == posRenderer && thisRenderedOffset == posRenderedOffset)
1050         return false;
1051
1052     int ignoredCaretOffset;
1053     InlineBox* b1;
1054     getInlineBoxAndOffset(DOWNSTREAM, b1, ignoredCaretOffset);
1055     InlineBox* b2;
1056     pos.getInlineBoxAndOffset(DOWNSTREAM, b2, ignoredCaretOffset);
1057
1058     LOG(Editing, "renderer:               %p [%p]\n", renderer, b1);
1059     LOG(Editing, "thisRenderedOffset:         %d\n", thisRenderedOffset);
1060     LOG(Editing, "posRenderer:            %p [%p]\n", posRenderer, b2);
1061     LOG(Editing, "posRenderedOffset:      %d\n", posRenderedOffset);
1062     LOG(Editing, "node min/max:           %d:%d\n", caretMinOffset(deprecatedNode()), caretMaxOffset(deprecatedNode()));
1063     LOG(Editing, "pos node min/max:       %d:%d\n", caretMinOffset(pos.deprecatedNode()), caretMaxOffset(pos.deprecatedNode()));
1064     LOG(Editing, "----------------------------------------------------------------------\n");
1065
1066     if (!b1 || !b2) {
1067         return false;
1068     }
1069
1070     if (&b1->root() != &b2->root()) {
1071         return true;
1072     }
1073
1074     if (nextRenderedEditable(deprecatedNode()) == pos.deprecatedNode()
1075         && thisRenderedOffset == caretMaxOffset(deprecatedNode()) && !posRenderedOffset) {
1076         return false;
1077     }
1078     
1079     if (previousRenderedEditable(deprecatedNode()) == pos.deprecatedNode()
1080         && !thisRenderedOffset && posRenderedOffset == caretMaxOffset(pos.deprecatedNode())) {
1081         return false;
1082     }
1083
1084     return true;
1085 }
1086
1087 // This assumes that it starts in editable content.
1088 Position Position::leadingWhitespacePosition(EAffinity affinity, bool considerNonCollapsibleWhitespace) const
1089 {
1090     ASSERT(isEditablePosition(*this));
1091     if (isNull())
1092         return Position();
1093     
1094     if (upstream().deprecatedNode()->hasTagName(brTag))
1095         return Position();
1096
1097     Position prev = previousCharacterPosition(affinity);
1098     if (prev != *this && inSameEnclosingBlockFlowElement(deprecatedNode(), prev.deprecatedNode()) && is<Text>(*prev.deprecatedNode())) {
1099         String string = downcast<Text>(*prev.deprecatedNode()).data();
1100         UChar c = string[prev.deprecatedEditingOffset()];
1101         if (considerNonCollapsibleWhitespace ? (isSpaceOrNewline(c) || c == noBreakSpace) : deprecatedIsCollapsibleWhitespace(c))
1102             if (isEditablePosition(prev))
1103                 return prev;
1104     }
1105
1106     return Position();
1107 }
1108
1109 // This assumes that it starts in editable content.
1110 Position Position::trailingWhitespacePosition(EAffinity, bool considerNonCollapsibleWhitespace) const
1111 {
1112     ASSERT(isEditablePosition(*this));
1113     if (isNull())
1114         return Position();
1115     
1116     VisiblePosition v(*this);
1117     UChar c = v.characterAfter();
1118     // The space must not be in another paragraph and it must be editable.
1119     if (!isEndOfParagraph(v) && v.next(CannotCrossEditingBoundary).isNotNull())
1120         if (considerNonCollapsibleWhitespace ? (isSpaceOrNewline(c) || c == noBreakSpace) : deprecatedIsCollapsibleWhitespace(c))
1121             return *this;
1122     
1123     return Position();
1124 }
1125
1126 void Position::getInlineBoxAndOffset(EAffinity affinity, InlineBox*& inlineBox, int& caretOffset) const
1127 {
1128     getInlineBoxAndOffset(affinity, primaryDirection(), inlineBox, caretOffset);
1129 }
1130
1131 static bool isNonTextLeafChild(RenderObject& object)
1132 {
1133     if (is<RenderText>(object))
1134         return false;
1135     return !downcast<RenderElement>(object).firstChild();
1136 }
1137
1138 static InlineTextBox* searchAheadForBetterMatch(RenderObject* renderer)
1139 {
1140     RenderBlock* container = renderer->containingBlock();
1141     RenderObject* next = renderer;
1142     while ((next = next->nextInPreOrder(container))) {
1143         if (is<RenderBlock>(*next))
1144             return nullptr;
1145         if (next->isBR())
1146             return nullptr;
1147         if (isNonTextLeafChild(*next))
1148             return nullptr;
1149         if (is<RenderText>(*next)) {
1150             InlineTextBox* match = nullptr;
1151             int minOffset = INT_MAX;
1152             for (InlineTextBox* box = downcast<RenderText>(*next).firstTextBox(); box; box = box->nextTextBox()) {
1153                 int caretMinOffset = box->caretMinOffset();
1154                 if (caretMinOffset < minOffset) {
1155                     match = box;
1156                     minOffset = caretMinOffset;
1157                 }
1158             }
1159             if (match)
1160                 return match;
1161         }
1162     }
1163     return nullptr;
1164 }
1165
1166 static Position downstreamIgnoringEditingBoundaries(Position position)
1167 {
1168     Position lastPosition;
1169     while (position != lastPosition) {
1170         lastPosition = position;
1171         position = position.downstream(CanCrossEditingBoundary);
1172     }
1173     return position;
1174 }
1175
1176 static Position upstreamIgnoringEditingBoundaries(Position position)
1177 {
1178     Position lastPosition;
1179     while (position != lastPosition) {
1180         lastPosition = position;
1181         position = position.upstream(CanCrossEditingBoundary);
1182     }
1183     return position;
1184 }
1185
1186 void Position::getInlineBoxAndOffset(EAffinity affinity, TextDirection primaryDirection, InlineBox*& inlineBox, int& caretOffset) const
1187 {
1188     caretOffset = deprecatedEditingOffset();
1189     RenderObject* renderer = deprecatedNode()->renderer();
1190
1191     if (renderer->isBR())
1192         inlineBox = !caretOffset ? downcast<RenderLineBreak>(*renderer).inlineBoxWrapper() : nullptr;
1193     else if (is<RenderText>(*renderer)) {
1194         auto& textRenderer = downcast<RenderText>(*renderer);
1195         textRenderer.ensureLineBoxes();
1196
1197         InlineTextBox* box;
1198         InlineTextBox* candidate = nullptr;
1199
1200         for (box = textRenderer.firstTextBox(); box; box = box->nextTextBox()) {
1201             int caretMinOffset = box->caretMinOffset();
1202             int caretMaxOffset = box->caretMaxOffset();
1203
1204             if (caretOffset < caretMinOffset || caretOffset > caretMaxOffset || (caretOffset == caretMaxOffset && box->isLineBreak()))
1205                 continue;
1206
1207             if (caretOffset > caretMinOffset && caretOffset < caretMaxOffset) {
1208                 inlineBox = box;
1209                 return;
1210             }
1211
1212             if (((caretOffset == caretMaxOffset) ^ (affinity == DOWNSTREAM))
1213                 || ((caretOffset == caretMinOffset) ^ (affinity == UPSTREAM))
1214                 || (caretOffset == caretMaxOffset && box->nextLeafChild() && box->nextLeafChild()->isLineBreak()))
1215                 break;
1216
1217             candidate = box;
1218         }
1219         if (candidate && candidate == textRenderer.lastTextBox() && affinity == DOWNSTREAM) {
1220             box = searchAheadForBetterMatch(&textRenderer);
1221             if (box)
1222                 caretOffset = box->caretMinOffset();
1223         }
1224         inlineBox = box ? box : candidate;
1225     } else {
1226         inlineBox = nullptr;
1227         if (canHaveChildrenForEditing(deprecatedNode()) && is<RenderBlockFlow>(*renderer) && hasRenderedNonAnonymousDescendantsWithHeight(downcast<RenderBlockFlow>(*renderer))) {
1228             // Try a visually equivalent position with possibly opposite editability. This helps in case |this| is in
1229             // an editable block but surrounded by non-editable positions. It acts to negate the logic at the beginning
1230             // of RenderObject::createVisiblePosition().
1231             Position equivalent = downstreamIgnoringEditingBoundaries(*this);
1232             if (equivalent == *this) {
1233                 equivalent = upstreamIgnoringEditingBoundaries(*this);
1234                 if (equivalent == *this || downstreamIgnoringEditingBoundaries(equivalent) == *this)
1235                     return;
1236             }
1237
1238             equivalent.getInlineBoxAndOffset(UPSTREAM, primaryDirection, inlineBox, caretOffset);
1239             return;
1240         }
1241         if (is<RenderBox>(*renderer)) {
1242             inlineBox = downcast<RenderBox>(*renderer).inlineBoxWrapper();
1243             if (!inlineBox || (caretOffset > inlineBox->caretMinOffset() && caretOffset < inlineBox->caretMaxOffset()))
1244                 return;
1245         }
1246     }
1247
1248     if (!inlineBox)
1249         return;
1250
1251     unsigned char level = inlineBox->bidiLevel();
1252
1253     if (inlineBox->direction() == primaryDirection) {
1254         if (caretOffset == inlineBox->caretRightmostOffset()) {
1255             InlineBox* nextBox = inlineBox->nextLeafChild();
1256             if (!nextBox || nextBox->bidiLevel() >= level)
1257                 return;
1258
1259             level = nextBox->bidiLevel();
1260             InlineBox* prevBox = inlineBox;
1261             do {
1262                 prevBox = prevBox->prevLeafChild();
1263             } while (prevBox && prevBox->bidiLevel() > level);
1264
1265             if (prevBox && prevBox->bidiLevel() == level)   // For example, abc FED 123 ^ CBA
1266                 return;
1267
1268             // For example, abc 123 ^ CBA
1269             while (InlineBox* nextBox = inlineBox->nextLeafChild()) {
1270                 if (nextBox->bidiLevel() < level)
1271                     break;
1272                 inlineBox = nextBox;
1273             }
1274             caretOffset = inlineBox->caretRightmostOffset();
1275         } else {
1276             InlineBox* prevBox = inlineBox->prevLeafChild();
1277             if (!prevBox || prevBox->bidiLevel() >= level)
1278                 return;
1279
1280             level = prevBox->bidiLevel();
1281             InlineBox* nextBox = inlineBox;
1282             do {
1283                 nextBox = nextBox->nextLeafChild();
1284             } while (nextBox && nextBox->bidiLevel() > level);
1285
1286             if (nextBox && nextBox->bidiLevel() == level)
1287                 return;
1288
1289             while (InlineBox* prevBox = inlineBox->prevLeafChild()) {
1290                 if (prevBox->bidiLevel() < level)
1291                     break;
1292                 inlineBox = prevBox;
1293             }
1294             caretOffset = inlineBox->caretLeftmostOffset();
1295         }
1296         return;
1297     }
1298
1299     if (caretOffset == inlineBox->caretLeftmostOffset()) {
1300         InlineBox* prevBox = inlineBox->prevLeafChildIgnoringLineBreak();
1301         if (!prevBox || prevBox->bidiLevel() < level) {
1302             // Left edge of a secondary run. Set to the right edge of the entire run.
1303             while (InlineBox* nextBox = inlineBox->nextLeafChildIgnoringLineBreak()) {
1304                 if (nextBox->bidiLevel() < level)
1305                     break;
1306                 inlineBox = nextBox;
1307             }
1308             caretOffset = inlineBox->caretRightmostOffset();
1309         } else if (prevBox->bidiLevel() > level) {
1310             // Right edge of a "tertiary" run. Set to the left edge of that run.
1311             while (InlineBox* tertiaryBox = inlineBox->prevLeafChildIgnoringLineBreak()) {
1312                 if (tertiaryBox->bidiLevel() <= level)
1313                     break;
1314                 inlineBox = tertiaryBox;
1315             }
1316             caretOffset = inlineBox->caretLeftmostOffset();
1317         }
1318     } else {
1319         InlineBox* nextBox = inlineBox->nextLeafChildIgnoringLineBreak();
1320         if (!nextBox || nextBox->bidiLevel() < level) {
1321             // Right edge of a secondary run. Set to the left edge of the entire run.
1322             while (InlineBox* prevBox = inlineBox->prevLeafChildIgnoringLineBreak()) {
1323                 if (prevBox->bidiLevel() < level)
1324                     break;
1325                 inlineBox = prevBox;
1326             }
1327             caretOffset = inlineBox->caretLeftmostOffset();
1328         } else if (nextBox->bidiLevel() > level) {
1329             // Left edge of a "tertiary" run. Set to the right edge of that run.
1330             while (InlineBox* tertiaryBox = inlineBox->nextLeafChildIgnoringLineBreak()) {
1331                 if (tertiaryBox->bidiLevel() <= level)
1332                     break;
1333                 inlineBox = tertiaryBox;
1334             }
1335             caretOffset = inlineBox->caretRightmostOffset();
1336         }
1337     }
1338 }
1339
1340 TextDirection Position::primaryDirection() const
1341 {
1342     if (!m_anchorNode->renderer())
1343         return LTR;
1344     if (auto* blockFlow = lineageOfType<RenderBlockFlow>(*m_anchorNode->renderer()).first())
1345         return blockFlow->style().direction();
1346     return LTR;
1347 }
1348
1349
1350 void Position::debugPosition(const char* msg) const
1351 {
1352     if (isNull())
1353         fprintf(stderr, "Position [%s]: null\n", msg);
1354     else
1355         fprintf(stderr, "Position [%s]: %s [%p] at %d\n", msg, deprecatedNode()->nodeName().utf8().data(), deprecatedNode(), m_offset);
1356 }
1357
1358 #ifndef NDEBUG
1359
1360 void Position::formatForDebugger(char* buffer, unsigned length) const
1361 {
1362     StringBuilder result;
1363
1364     if (isNull())
1365         result.appendLiteral("<null>");
1366     else {
1367         char s[1024];
1368         result.appendLiteral("offset ");
1369         result.appendNumber(m_offset);
1370         result.appendLiteral(" of ");
1371         deprecatedNode()->formatForDebugger(s, sizeof(s));
1372         result.append(s);
1373     }
1374
1375     strncpy(buffer, result.toString().utf8().data(), length - 1);
1376 }
1377
1378 void Position::showAnchorTypeAndOffset() const
1379 {
1380     if (m_isLegacyEditingPosition)
1381         fputs("legacy, ", stderr);
1382     switch (anchorType()) {
1383     case PositionIsOffsetInAnchor:
1384         fputs("offset", stderr);
1385         break;
1386     case PositionIsBeforeChildren:
1387         fputs("beforeChildren", stderr);
1388         break;
1389     case PositionIsAfterChildren:
1390         fputs("afterChildren", stderr);
1391         break;
1392     case PositionIsBeforeAnchor:
1393         fputs("before", stderr);
1394         break;
1395     case PositionIsAfterAnchor:
1396         fputs("after", stderr);
1397         break;
1398     }
1399     fprintf(stderr, ", offset:%d\n", m_offset);
1400 }
1401
1402 void Position::showTreeForThis() const
1403 {
1404     if (anchorNode()) {
1405         anchorNode()->showTreeForThis();
1406         showAnchorTypeAndOffset();
1407     }
1408 }
1409
1410 #endif
1411
1412
1413
1414 } // namespace WebCore
1415
1416 #ifndef NDEBUG
1417
1418 void showTree(const WebCore::Position& pos)
1419 {
1420     pos.showTreeForThis();
1421 }
1422
1423 void showTree(const WebCore::Position* pos)
1424 {
1425     if (pos)
1426         pos->showTreeForThis();
1427 }
1428
1429 #endif