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