18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 2635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "VisiblePosition.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CString.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h" 31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "FloatQuad.h" 325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "HTMLElement.h" 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "InlineTextBox.h" 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Logging.h" 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Range.h" 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Text.h" 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "htmlediting.h" 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "visible_units.h" 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <stdio.h> 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames; 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectVisiblePosition::VisiblePosition(const Position &pos, EAffinity affinity) 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project init(pos, affinity); 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectVisiblePosition::VisiblePosition(Node *node, int offset, EAffinity affinity) 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(offset >= 0); 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project init(Position(node, offset), affinity); 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid VisiblePosition::init(const Position& position, EAffinity affinity) 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_affinity = affinity; 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_deepPosition = canonicalPosition(position); 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // When not at a line wrap, make sure to end up with DOWNSTREAM affinity. 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_affinity == UPSTREAM && (isNull() || inSameLine(VisiblePosition(position, DOWNSTREAM), *this))) 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_affinity = DOWNSTREAM; 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectVisiblePosition VisiblePosition::next(bool stayInEditableContent) const 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project VisiblePosition next(nextVisuallyDistinctCandidate(m_deepPosition), m_affinity); 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!stayInEditableContent) 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return next; 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return honorEditableBoundaryAtOrAfter(next); 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectVisiblePosition VisiblePosition::previous(bool stayInEditableContent) const 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // find first previous DOM position that is visible 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position pos = previousVisuallyDistinctCandidate(m_deepPosition); 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // return null visible position if there is no previous visible position 848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (pos.atStartOfTree()) 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return VisiblePosition(); 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project VisiblePosition prev = VisiblePosition(pos, DOWNSTREAM); 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(prev != *this); 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // we should always be able to make the affinity DOWNSTREAM, because going previous from an 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // UPSTREAM position can never yield another UPSTREAM position (unless line wrap length is 0!). 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (prev.isNotNull() && m_affinity == UPSTREAM) { 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project VisiblePosition temp = prev; 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project temp.setAffinity(UPSTREAM); 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(inSameLine(temp, prev)); 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!stayInEditableContent) 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return prev; 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return honorEditableBoundaryAtOrBefore(prev); 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition VisiblePosition::leftVisuallyDistinctCandidate() const 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position p = m_deepPosition; 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!p.node()) 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Position(); 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position downstreamStart = p.downstream(); 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project TextDirection primaryDirection = LTR; 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RenderObject* r = p.node()->renderer(); r; r = r->parent()) { 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (r->isBlockFlow()) { 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project primaryDirection = r->style()->direction(); 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (true) { 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineBox* box; 1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int offset; 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project p.getInlineBoxAndOffset(m_affinity, primaryDirection, box, offset); 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!box) 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return primaryDirection == LTR ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition); 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderObject* renderer = box->renderer(); 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (true) { 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if ((renderer->isReplaced() || renderer->isBR()) && offset == box->caretRightmostOffset()) 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return box->direction() == LTR ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition); 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset = box->direction() == LTR ? renderer->previousOffset(offset) : renderer->nextOffset(offset); 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int caretMinOffset = box->caretMinOffset(); 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int caretMaxOffset = box->caretMaxOffset(); 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (offset > caretMinOffset && offset < caretMaxOffset) 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (box->direction() == LTR ? offset < caretMinOffset : offset > caretMaxOffset) { 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Overshot to the left. 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineBox* prevBox = box->prevLeafChild(); 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!prevBox) 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return primaryDirection == LTR ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition); 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Reposition at the other logical position corresponding to our edge's visual position and go for another round. 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project box = prevBox; 1508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian renderer = box->renderer(); 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset = prevBox->caretRightmostOffset(); 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(offset == box->caretLeftmostOffset()); 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned char level = box->bidiLevel(); 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineBox* prevBox = box->prevLeafChild(); 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (box->direction() == primaryDirection) { 1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!prevBox || prevBox->bidiLevel() >= level) 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project level = prevBox->bidiLevel(); 1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineBox* nextBox = box; 1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project do { 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project nextBox = nextBox->nextLeafChild(); 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } while (nextBox && nextBox->bidiLevel() > level); 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (nextBox && nextBox->bidiLevel() == level) 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (InlineBox* prevBox = box->prevLeafChild()) { 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (prevBox->bidiLevel() < level) 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project box = prevBox; 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian renderer = box->renderer(); 1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset = box->caretRightmostOffset(); 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (box->direction() == primaryDirection) 1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (prevBox) { 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project box = prevBox; 1888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian renderer = box->renderer(); 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset = box->caretRightmostOffset(); 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (box->bidiLevel() > level) { 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project do { 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project prevBox = box->prevLeafChild(); 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } while (prevBox && prevBox->bidiLevel() > level); 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!prevBox || prevBox->bidiLevel() < level) 1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Trailing edge of a secondary run. Set to the leading edge of the entire run. 2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (true) { 2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (InlineBox* nextBox = box->nextLeafChild()) { 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (nextBox->bidiLevel() < level) 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project box = nextBox; 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (box->bidiLevel() == level) 2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project level = box->bidiLevel(); 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (InlineBox* prevBox = box->prevLeafChild()) { 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (prevBox->bidiLevel() < level) 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project box = prevBox; 2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (box->bidiLevel() == level) 2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project level = box->bidiLevel(); 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian renderer = box->renderer(); 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset = primaryDirection == LTR ? box->caretMinOffset() : box->caretMaxOffset(); 2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian p = Position(renderer->node(), offset); 2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if ((p.isCandidate() && p.downstream() != downstreamStart) || p.atStartOfTree() || p.atEndOfTree()) 2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return p; 2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectVisiblePosition VisiblePosition::left(bool stayInEditableContent) const 2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position pos = leftVisuallyDistinctCandidate(); 2348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // FIXME: Why can't we move left from the last position in a tree? 2358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (pos.atStartOfTree() || pos.atEndOfTree()) 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return VisiblePosition(); 2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project VisiblePosition left = VisiblePosition(pos, DOWNSTREAM); 2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(left != *this); 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!stayInEditableContent) 2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return left; 2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: This may need to do something different from "before". 2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return honorEditableBoundaryAtOrBefore(left); 2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition VisiblePosition::rightVisuallyDistinctCandidate() const 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position p = m_deepPosition; 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!p.node()) 2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Position(); 2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position downstreamStart = p.downstream(); 2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project TextDirection primaryDirection = LTR; 2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RenderObject* r = p.node()->renderer(); r; r = r->parent()) { 2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (r->isBlockFlow()) { 2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project primaryDirection = r->style()->direction(); 2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (true) { 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineBox* box; 2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int offset; 2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project p.getInlineBoxAndOffset(m_affinity, primaryDirection, box, offset); 2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!box) 2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return primaryDirection == LTR ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition); 2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderObject* renderer = box->renderer(); 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (true) { 2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if ((renderer->isReplaced() || renderer->isBR()) && offset == box->caretLeftmostOffset()) 2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return box->direction() == LTR ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition); 2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset = box->direction() == LTR ? renderer->nextOffset(offset) : renderer->previousOffset(offset); 2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int caretMinOffset = box->caretMinOffset(); 2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int caretMaxOffset = box->caretMaxOffset(); 2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (offset > caretMinOffset && offset < caretMaxOffset) 2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (box->direction() == LTR ? offset > caretMaxOffset : offset < caretMinOffset) { 2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Overshot to the right. 2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineBox* nextBox = box->nextLeafChild(); 2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!nextBox) 2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return primaryDirection == LTR ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition); 2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Reposition at the other logical position corresponding to our edge's visual position and go for another round. 2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project box = nextBox; 2928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian renderer = box->renderer(); 2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset = nextBox->caretLeftmostOffset(); 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(offset == box->caretRightmostOffset()); 2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned char level = box->bidiLevel(); 3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineBox* nextBox = box->nextLeafChild(); 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (box->direction() == primaryDirection) { 3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!nextBox || nextBox->bidiLevel() >= level) 3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project level = nextBox->bidiLevel(); 3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineBox* prevBox = box; 3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project do { 3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project prevBox = prevBox->prevLeafChild(); 3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } while (prevBox && prevBox->bidiLevel() > level); 3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (prevBox && prevBox->bidiLevel() == level) // For example, abc FED 123 ^ CBA 3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // For example, abc 123 ^ CBA 3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (InlineBox* nextBox = box->nextLeafChild()) { 3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (nextBox->bidiLevel() < level) 3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project box = nextBox; 3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian renderer = box->renderer(); 3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset = box->caretLeftmostOffset(); 3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (box->direction() == primaryDirection) 3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (nextBox) { 3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project box = nextBox; 3318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian renderer = box->renderer(); 3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset = box->caretLeftmostOffset(); 3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (box->bidiLevel() > level) { 3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project do { 3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project nextBox = box->nextLeafChild(); 3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } while (nextBox && nextBox->bidiLevel() > level); 3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!nextBox || nextBox->bidiLevel() < level) 3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Trailing edge of a secondary run. Set to the leading edge of the entire run. 3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (true) { 3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (InlineBox* prevBox = box->prevLeafChild()) { 3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (prevBox->bidiLevel() < level) 3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project box = prevBox; 3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (box->bidiLevel() == level) 3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project level = box->bidiLevel(); 3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (InlineBox* nextBox = box->nextLeafChild()) { 3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (nextBox->bidiLevel() < level) 3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project box = nextBox; 3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (box->bidiLevel() == level) 3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project level = box->bidiLevel(); 3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian renderer = box->renderer(); 3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset = primaryDirection == LTR ? box->caretMaxOffset() : box->caretMinOffset(); 3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian p = Position(renderer->node(), offset); 3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if ((p.isCandidate() && p.downstream() != downstreamStart) || p.atStartOfTree() || p.atEndOfTree()) 3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return p; 3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectVisiblePosition VisiblePosition::right(bool stayInEditableContent) const 3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position pos = rightVisuallyDistinctCandidate(); 3778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // FIXME: Why can't we move left from the last position in a tree? 3788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (pos.atStartOfTree() || pos.atEndOfTree()) 3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return VisiblePosition(); 3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project VisiblePosition right = VisiblePosition(pos, DOWNSTREAM); 3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(right != *this); 3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!stayInEditableContent) 3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return right; 3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: This may need to do something different from "after". 3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return honorEditableBoundaryAtOrAfter(right); 3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectVisiblePosition VisiblePosition::honorEditableBoundaryAtOrBefore(const VisiblePosition &pos) const 3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (pos.isNull()) 3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return pos; 3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* highestRoot = highestEditableRoot(deepEquivalent()); 3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Return empty position if pos is not somewhere inside the editable region containing this position 3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (highestRoot && !pos.deepEquivalent().node()->isDescendantOf(highestRoot)) 4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return VisiblePosition(); 4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Return pos itself if the two are from the very same editable region, or both are non-editable 4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: In the non-editable case, just because the new position is non-editable doesn't mean movement 4048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // to it is allowed. VisibleSelection::adjustForEditableContent has this problem too. 4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (highestEditableRoot(pos.deepEquivalent()) == highestRoot) 4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return pos; 4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Return empty position if this position is non-editable, but pos is editable 4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Move to the previous non-editable region. 4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!highestRoot) 4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return VisiblePosition(); 4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Return the last position before pos that is in the same editable region as this position 4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return lastEditablePositionBeforePositionInRoot(pos.deepEquivalent(), highestRoot); 4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectVisiblePosition VisiblePosition::honorEditableBoundaryAtOrAfter(const VisiblePosition &pos) const 4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (pos.isNull()) 4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return pos; 4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* highestRoot = highestEditableRoot(deepEquivalent()); 4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Return empty position if pos is not somewhere inside the editable region containing this position 4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (highestRoot && !pos.deepEquivalent().node()->isDescendantOf(highestRoot)) 4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return VisiblePosition(); 4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Return pos itself if the two are from the very same editable region, or both are non-editable 4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: In the non-editable case, just because the new position is non-editable doesn't mean movement 4308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // to it is allowed. VisibleSelection::adjustForEditableContent has this problem too. 4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (highestEditableRoot(pos.deepEquivalent()) == highestRoot) 4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return pos; 4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Return empty position if this position is non-editable, but pos is editable 4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Move to the next non-editable region. 4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!highestRoot) 4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return VisiblePosition(); 4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Return the next position after pos that is in the same editable region as this position 4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return firstEditablePositionAfterPositionInRoot(pos.deepEquivalent(), highestRoot); 4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 443635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic Position canonicalizeCandidate(const Position& candidate) 4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (candidate.isNull()) 4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Position(); 4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(candidate.isCandidate()); 4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position upstream = candidate.upstream(); 4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (upstream.isCandidate()) 4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return upstream; 4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return candidate; 4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition VisiblePosition::canonicalPosition(const Position& position) 4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME (9535): Canonicalizing to the leftmost candidate means that if we're at a line wrap, we will 4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // ask renderers to paint downstream carets for other renderers. 4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // To fix this, we need to either a) add code to all paintCarets to pass the responsibility off to 4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the appropriate renderer for VisiblePosition's like these, or b) canonicalize to the rightmost candidate 4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // unless the affinity is upstream. 4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* node = position.node(); 4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!node) 4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Position(); 4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project node->document()->updateLayoutIgnorePendingStylesheets(); 4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position candidate = position.upstream(); 4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (candidate.isCandidate()) 4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return candidate; 4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project candidate = position.downstream(); 4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (candidate.isCandidate()) 4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return candidate; 4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // When neither upstream or downstream gets us to a candidate (upstream/downstream won't leave 4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // blocks or enter new ones), we search forward and backward until we find one. 4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position next = canonicalizeCandidate(nextCandidate(position)); 4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position prev = canonicalizeCandidate(previousCandidate(position)); 4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* nextNode = next.node(); 4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* prevNode = prev.node(); 4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The new position must be in the same editable element. Enforce that first. 4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Unless the descent is from a non-editable html element to an editable body. 4838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (node->hasTagName(htmlTag) && !node->isContentEditable() && node->document()->body() && node->document()->body()->isContentEditable()) 4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return next.isNotNull() ? next : prev; 4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* editingRoot = editableRootForPosition(position); 4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the html element is editable, descending into its body will look like a descent 4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // from non-editable to editable content since rootEditableElement() always stops at the body. 4908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if ((editingRoot && editingRoot->hasTagName(htmlTag)) || position.node()->isDocumentNode()) 4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return next.isNotNull() ? next : prev; 4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool prevIsInSameEditableElement = prevNode && editableRootForPosition(prev) == editingRoot; 4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool nextIsInSameEditableElement = nextNode && editableRootForPosition(next) == editingRoot; 4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (prevIsInSameEditableElement && !nextIsInSameEditableElement) 4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return prev; 4978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (nextIsInSameEditableElement && !prevIsInSameEditableElement) 4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return next; 5008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!nextIsInSameEditableElement && !prevIsInSameEditableElement) 5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Position(); 5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The new position should be in the same block flow element. Favor that. 5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node *originalBlock = node->enclosingBlockFlowElement(); 5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool nextIsOutsideOriginalBlock = !nextNode->isDescendantOf(originalBlock) && nextNode != originalBlock; 5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool prevIsOutsideOriginalBlock = !prevNode->isDescendantOf(originalBlock) && prevNode != originalBlock; 5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (nextIsOutsideOriginalBlock && !prevIsOutsideOriginalBlock) 5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return prev; 5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return next; 5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5145f1ab04193ad0130ca8204aadaceae083aca9881Feng QianUChar32 VisiblePosition::characterAfter() const 5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We canonicalize to the first of two equivalent candidates, but the second of the two candidates 5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // is the one that will be inside the text node containing the character after this visible position. 5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position pos = m_deepPosition.downstream(); 5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* node = pos.node(); 5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!node || !node->isTextNode()) 5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Text* textNode = static_cast<Text*>(pos.node()); 5235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned offset = pos.deprecatedEditingOffset(); 5245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned length = textNode->length(); 5255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (offset >= length) 5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 5275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 5285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian UChar32 ch; 5295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian const UChar* characters = textNode->data().characters(); 5305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian U16_NEXT(characters, offset, length, ch); 5315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return ch; 5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 534635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectIntRect VisiblePosition::localCaretRect(RenderObject*& renderer) const 5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* node = m_deepPosition.node(); 537635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!node) { 538635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project renderer = 0; 5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return IntRect(); 540635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 541635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 542635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project renderer = node->renderer(); 5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!renderer) 5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return IntRect(); 5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineBox* inlineBox; 5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int caretOffset; 5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project getInlineBoxAndOffset(inlineBox, caretOffset); 5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (inlineBox) 5518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian renderer = inlineBox->renderer(); 5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 553635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return renderer->localCaretRect(inlineBox, caretOffset); 554635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 555635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 556635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectIntRect VisiblePosition::absoluteCaretBounds() const 557635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 558635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderObject* renderer; 559635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project IntRect localRect = localCaretRect(renderer); 560635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (localRect.isEmpty() || !renderer) 561635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return IntRect(); 562635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 563635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return renderer->localToAbsoluteQuad(FloatRect(localRect)).enclosingBoundingBox(); 564635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 565635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 566635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectint VisiblePosition::xOffsetForVerticalNavigation() const 567635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 568635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderObject* renderer; 569635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project IntRect localRect = localCaretRect(renderer); 570635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (localRect.isEmpty() || !renderer) 571635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return 0; 572635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 573635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // This ignores transforms on purpose, for now. Vertical navigation is done 574635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // without consulting transforms, so that 'up' in transformed text is 'up' 575635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // relative to the text, not absolute 'up'. 576635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return renderer->localToAbsolute(localRect.location()).x(); 5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid VisiblePosition::debugPosition(const char* msg) const 5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isNull()) 5828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project fprintf(stderr, "Position [%s]: null\n", msg); 5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 5845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian fprintf(stderr, "Position [%s]: %s [%p] at %d\n", msg, m_deepPosition.node()->nodeName().utf8().data(), m_deepPosition.node(), m_deepPosition.deprecatedEditingOffset()); 5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG 5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid VisiblePosition::formatForDebugger(char* buffer, unsigned length) const 5908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_deepPosition.formatForDebugger(buffer, length); 5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid VisiblePosition::showTreeForThis() const 5958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_deepPosition.showTreeForThis(); 5978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Range> makeRange(const VisiblePosition &start, const VisiblePosition &end) 6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 603635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (start.isNull() || end.isNull()) 604635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return 0; 605635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 6068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position s = rangeCompliantEquivalent(start); 6078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position e = rangeCompliantEquivalent(end); 6085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return Range::create(s.node()->document(), s.node(), s.deprecatedEditingOffset(), e.node(), e.deprecatedEditingOffset()); 6098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectVisiblePosition startVisiblePosition(const Range *r, EAffinity affinity) 6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int exception = 0; 6148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return VisiblePosition(r->startContainer(exception), r->startOffset(exception), affinity); 6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectVisiblePosition endVisiblePosition(const Range *r, EAffinity affinity) 6188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int exception = 0; 6208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return VisiblePosition(r->endContainer(exception), r->endOffset(exception), affinity); 6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool setStart(Range *r, const VisiblePosition &visiblePosition) 6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!r) 6268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position p = rangeCompliantEquivalent(visiblePosition); 6288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int code = 0; 6295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian r->setStart(p.node(), p.deprecatedEditingOffset(), code); 6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return code == 0; 6318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool setEnd(Range *r, const VisiblePosition &visiblePosition) 6348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!r) 6368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position p = rangeCompliantEquivalent(visiblePosition); 6388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int code = 0; 6395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian r->setEnd(p.node(), p.deprecatedEditingOffset(), code); 6408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return code == 0; 6418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode *enclosingBlockFlowElement(const VisiblePosition &visiblePosition) 6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (visiblePosition.isNull()) 6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return NULL; 6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return visiblePosition.deepEquivalent().node()->enclosingBlockFlowElement(); 6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool isFirstVisiblePositionInNode(const VisiblePosition &visiblePosition, const Node *node) 6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (visiblePosition.isNull()) 6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!visiblePosition.deepEquivalent().node()->isDescendantOf(node)) 6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project VisiblePosition previous = visiblePosition.previous(); 6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return previous.isNull() || !previous.deepEquivalent().node()->isDescendantOf(node); 6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool isLastVisiblePositionInNode(const VisiblePosition &visiblePosition, const Node *node) 6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (visiblePosition.isNull()) 6668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!visiblePosition.deepEquivalent().node()->isDescendantOf(node)) 6698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project VisiblePosition next = visiblePosition.next(); 6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return next.isNull() || !next.deepEquivalent().node()->isDescendantOf(node); 6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore 6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG 6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid showTree(const WebCore::VisiblePosition* vpos) 6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (vpos) 6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vpos->showTreeForThis(); 6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid showTree(const WebCore::VisiblePosition& vpos) 6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vpos.showTreeForThis(); 6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 691