htmlediting.cpp revision 8e35f3cfc7fba1d1c829dc557ebad6409cbe16a2
18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2004, 2005, 2006, 2007 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 "htmlediting.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CharacterNames.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "EditingText.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLElement.h" 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLInterchange.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h" 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PositionIterator.h" 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderObject.h" 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RegularExpression.h" 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Range.h" 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Selection.h" 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Text.h" 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "TextIterator.h" 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "VisiblePosition.h" 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "visible_units.h" 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std; 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames; 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Atomic means that the node has no children, or has children which are ignored for the 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// purposes of editing. 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool isAtomicNode(const Node *node) 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return node && (!node->hasChildNodes() || editingIgnoresContent(node)); 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Returns true for nodes that either have no content, or have content that is ignored (skipped 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// over) while editing. There are no VisiblePositions inside these nodes. 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool editingIgnoresContent(const Node* node) 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return !canHaveChildrenForEditing(node) && !node->isTextNode(); 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool canHaveChildrenForEditing(const Node* node) 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return !node->hasTagName(hrTag) && 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project !node->hasTagName(brTag) && 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project !node->hasTagName(imgTag) && 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project !node->hasTagName(buttonTag) && 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project !node->hasTagName(inputTag) && 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project !node->hasTagName(textareaTag) && 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project !node->hasTagName(objectTag) && 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project !node->hasTagName(iframeTag) && 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project !node->hasTagName(embedTag) && 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project !node->hasTagName(appletTag) && 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project !node->hasTagName(selectTag) && 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project !node->isTextNode(); 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Compare two positions, taking into account the possibility that one or both 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// could be inside a shadow tree. Only works for non-null values. 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint comparePositions(const Position& a, const Position& b) 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* nodeA = a.node(); 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(nodeA); 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* nodeB = b.node(); 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(nodeB); 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int offsetA = a.offset(); 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int offsetB = b.offset(); 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* shadowAncestorA = nodeA->shadowAncestorNode(); 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (shadowAncestorA == nodeA) 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project shadowAncestorA = 0; 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* shadowAncestorB = nodeB->shadowAncestorNode(); 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (shadowAncestorB == nodeB) 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project shadowAncestorB = 0; 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int bias = 0; 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (shadowAncestorA != shadowAncestorB) { 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (shadowAncestorA) { 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project nodeA = shadowAncestorA; 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offsetA = 0; 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bias = 1; 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (shadowAncestorB) { 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project nodeB = shadowAncestorB; 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offsetB = 0; 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bias = -1; 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int result = Range::compareBoundaryPoints(nodeA, offsetA, nodeB, offsetB); 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result ? result : bias; 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* highestEditableRoot(const Position& position) 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* node = position.node(); 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!node) 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* highestRoot = editableRootForPosition(position); 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!highestRoot) 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project node = highestRoot; 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (node) { 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (node->isContentEditable()) 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project highestRoot = node; 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (node->hasTagName(bodyTag)) 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project node = node->parentNode(); 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return highestRoot; 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* lowestEditableAncestor(Node* node) 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!node) 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node *lowestRoot = 0; 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (node) { 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (node->isContentEditable()) 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return node->rootEditableElement(); 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (node->hasTagName(bodyTag)) 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project node = node->parentNode(); 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return lowestRoot; 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool isEditablePosition(const Position& p) 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* node = p.node(); 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!node) 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (node->renderer() && node->renderer()->isTable()) 1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project node = node->parentNode(); 1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return node->isContentEditable(); 1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool isRichlyEditablePosition(const Position& p) 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* node = p.node(); 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!node) 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (node->renderer() && node->renderer()->isTable()) 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project node = node->parentNode(); 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return node->isContentRichlyEditable(); 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectElement* editableRootForPosition(const Position& p) 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* node = p.node(); 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!node) 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (node->renderer() && node->renderer()->isTable()) 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project node = node->parentNode(); 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return node->rootEditableElement(); 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool isContentEditable(const Node* node) 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return node->isContentEditable(); 1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition nextCandidate(const Position& position) 1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PositionIterator p = position; 2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (!p.atEnd()) { 2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project p.increment(); 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (p.isCandidate()) 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return p; 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Position(); 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition nextVisuallyDistinctCandidate(const Position& position) 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position p = position; 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position downstreamStart = p.downstream(); 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (!p.atEnd()) { 2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project p = p.next(UsingComposedCharacters); 2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (p.isCandidate() && p.downstream() != downstreamStart) 2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return p; 2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Position(); 2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition previousCandidate(const Position& position) 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PositionIterator p = position; 2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (!p.atStart()) { 2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project p.decrement(); 2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (p.isCandidate()) 2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return p; 2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Position(); 2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition previousVisuallyDistinctCandidate(const Position& position) 2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position p = position; 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position downstreamStart = p.downstream(); 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (!p.atStart()) { 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project p = p.previous(UsingComposedCharacters); 2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (p.isCandidate() && p.downstream() != downstreamStart) 2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return p; 2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Position(); 2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectVisiblePosition firstEditablePositionAfterPositionInRoot(const Position& position, Node* highestRoot) 2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // position falls before highestRoot. 2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (comparePositions(position, Position(highestRoot, 0)) == -1 && highestRoot->isContentEditable()) 2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return VisiblePosition(Position(highestRoot, 0)); 2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position p = position; 2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (Node* shadowAncestor = p.node()->shadowAncestorNode()) 2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (shadowAncestor != p.node()) 2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project p = Position(shadowAncestor, maxDeepOffset(shadowAncestor)); 2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (p.node() && !isEditablePosition(p) && p.node()->isDescendantOf(highestRoot)) 2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project p = isAtomicNode(p.node()) ? positionAfterNode(p.node()) : nextVisuallyDistinctCandidate(p); 2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (p.node() && !p.node()->isDescendantOf(highestRoot)) 2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return VisiblePosition(); 2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return VisiblePosition(p); 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectVisiblePosition lastEditablePositionBeforePositionInRoot(const Position& position, Node* highestRoot) 2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // When position falls after highestRoot, the result is easy to compute. 2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (comparePositions(position, Position(highestRoot, maxDeepOffset(highestRoot))) == 1) 2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return VisiblePosition(Position(highestRoot, maxDeepOffset(highestRoot))); 2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position p = position; 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (Node* shadowAncestor = p.node()->shadowAncestorNode()) 2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (shadowAncestor != p.node()) 2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project p = Position(shadowAncestor, 0); 2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (p.node() && !isEditablePosition(p) && p.node()->isDescendantOf(highestRoot)) 2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project p = isAtomicNode(p.node()) ? positionBeforeNode(p.node()) : previousVisuallyDistinctCandidate(p); 2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (p.node() && !p.node()->isDescendantOf(highestRoot)) 2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return VisiblePosition(); 2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return VisiblePosition(p); 2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Whether or not content before and after this node will collapse onto the same line as it. 2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool isBlock(const Node* node) 2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return node && node->renderer() && !node->renderer()->isInline(); 2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// FIXME: Deploy this in all of the places where enclosingBlockFlow/enclosingBlockFlowOrTableElement are used. 2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// FIXME: Pass a position to this function. The enclosing block of [table, x] for example, should be the 2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// block that contains the table and not the table, and this function should be the only one responsible for 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// knowing about these kinds of special cases. 2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* enclosingBlock(Node* node) 2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return enclosingNodeOfType(Position(node, 0), &isBlock); 2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition rangeCompliantEquivalent(const Position& pos) 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (pos.isNull()) 3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Position(); 3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node *node = pos.node(); 3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (pos.offset() <= 0) { 3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (node->parentNode() && (editingIgnoresContent(node) || isTableElement(node))) 3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return positionBeforeNode(node); 3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Position(node, 0); 3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (node->offsetInCharacters()) 3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Position(node, min(node->maxCharacterOffset(), pos.offset())); 3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int maxCompliantOffset = node->childNodeCount(); 3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (pos.offset() > maxCompliantOffset) { 3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (node->parentNode()) 3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return positionAfterNode(node); 3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // there is no other option at this point than to 3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // use the highest allowed position in the node 3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Position(node, maxCompliantOffset); 3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Editing should never generate positions like this. 3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if ((pos.offset() < maxCompliantOffset) && editingIgnoresContent(node)) { 3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT_NOT_REACHED(); 3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return node->parentNode() ? positionBeforeNode(node) : Position(node, 0); 3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (pos.offset() == maxCompliantOffset && (editingIgnoresContent(node) || isTableElement(node))) 3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return positionAfterNode(node); 3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Position(pos); 3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition rangeCompliantEquivalent(const VisiblePosition& vpos) 3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return rangeCompliantEquivalent(vpos.deepEquivalent()); 3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// This method is used to create positions in the DOM. It returns the maximum valid offset 3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// in a node. It returns 1 for some elements even though they do not have children, which 3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// creates technically invalid DOM Positions. Be sure to call rangeCompliantEquivalent 3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// on a Position before using it to create a DOM Range, or an exception will be thrown. 3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint maxDeepOffset(const Node *node) 3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(node); 3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!node) 3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (node->offsetInCharacters()) 3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return node->maxCharacterOffset(); 3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (node->hasChildNodes()) 3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return node->childNodeCount(); 3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // NOTE: This should preempt the childNodeCount for, e.g., select nodes 3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (editingIgnoresContent(node)) 3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 1; 3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString stringWithRebalancedWhitespace(const String& string, bool startIsStartOfParagraph, bool endIsEndOfParagraph) 3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static String twoSpaces(" "); 3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static String nbsp("\xa0"); 3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static String pattern(" \xa0"); 3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project String rebalancedString = string; 3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rebalancedString.replace(noBreakSpace, ' '); 3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rebalancedString.replace('\n', ' '); 3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rebalancedString.replace('\t', ' '); 3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rebalancedString.replace(twoSpaces, pattern); 3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (startIsStartOfParagraph && rebalancedString[0] == ' ') 3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rebalancedString.replace(0, 1, nbsp); 3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int end = rebalancedString.length() - 1; 3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (endIsEndOfParagraph && rebalancedString[end] == ' ') 3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rebalancedString.replace(end, 1, nbsp); 3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return rebalancedString; 3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool isTableStructureNode(const Node *node) 3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject *r = node->renderer(); 3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return (r && (r->isTableCell() || r->isTableRow() || r->isTableSection() || r->isTableCol())); 3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst String& nonBreakingSpaceString() 3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static String nonBreakingSpaceString = String(&noBreakSpace, 1); 3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return nonBreakingSpaceString; 3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// FIXME: need to dump this 4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool isSpecialElement(const Node *n) 4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!n) 4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!n->isHTMLElement()) 4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (n->isLink()) 4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject *renderer = n->renderer(); 4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!renderer) 4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (renderer->style()->display() == TABLE || renderer->style()->display() == INLINE_TABLE) 4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (renderer->style()->isFloating()) 4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (renderer->style()->position() != StaticPosition) 4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Checks if a string is a valid tag for the FormatBlockCommand function of execCommand. Expects lower case strings. 4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool validBlockTag(const String& blockTag) 4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (blockTag == "address" || 4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project blockTag == "blockquote" || 4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project blockTag == "dd" || 4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project blockTag == "div" || 4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project blockTag == "dl" || 4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project blockTag == "dt" || 4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project blockTag == "h1" || 4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project blockTag == "h2" || 4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project blockTag == "h3" || 4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project blockTag == "h4" || 4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project blockTag == "h5" || 4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project blockTag == "h6" || 4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project blockTag == "p" || 4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project blockTag == "pre") 4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic Node* firstInSpecialElement(const Position& pos) 4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* rootEditableElement = pos.node()->rootEditableElement(); 4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (Node* n = pos.node(); n && n->rootEditableElement() == rootEditableElement; n = n->parentNode()) 4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isSpecialElement(n)) { 4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM); 4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project VisiblePosition firstInElement = VisiblePosition(n, 0, DOWNSTREAM); 4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isTableElement(n) && vPos == firstInElement.next()) 4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return n; 4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (vPos == firstInElement) 4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return n; 4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic Node* lastInSpecialElement(const Position& pos) 4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* rootEditableElement = pos.node()->rootEditableElement(); 4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (Node* n = pos.node(); n && n->rootEditableElement() == rootEditableElement; n = n->parentNode()) 4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isSpecialElement(n)) { 4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM); 4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project VisiblePosition lastInElement = VisiblePosition(n, n->childNodeCount(), DOWNSTREAM); 4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isTableElement(n) && vPos == lastInElement.previous()) 4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return n; 4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (vPos == lastInElement) 4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return n; 4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool isFirstVisiblePositionInSpecialElement(const Position& pos) 4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return firstInSpecialElement(pos); 4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition positionBeforeContainingSpecialElement(const Position& pos, Node** containingSpecialElement) 4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* n = firstInSpecialElement(pos); 4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!n) 4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return pos; 4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position result = positionBeforeNode(n); 4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (result.isNull() || result.node()->rootEditableElement() != pos.node()->rootEditableElement()) 4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return pos; 4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (containingSpecialElement) 4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *containingSpecialElement = n; 4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool isLastVisiblePositionInSpecialElement(const Position& pos) 4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return lastInSpecialElement(pos); 5008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition positionAfterContainingSpecialElement(const Position& pos, Node **containingSpecialElement) 5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* n = lastInSpecialElement(pos); 5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!n) 5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return pos; 5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position result = positionAfterNode(n); 5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (result.isNull() || result.node()->rootEditableElement() != pos.node()->rootEditableElement()) 5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return pos; 5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (containingSpecialElement) 5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *containingSpecialElement = n; 5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition positionOutsideContainingSpecialElement(const Position &pos, Node **containingSpecialElement) 5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isFirstVisiblePositionInSpecialElement(pos)) 5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return positionBeforeContainingSpecialElement(pos, containingSpecialElement); 5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isLastVisiblePositionInSpecialElement(pos)) 5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return positionAfterContainingSpecialElement(pos, containingSpecialElement); 5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return pos; 5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* isFirstPositionAfterTable(const VisiblePosition& visiblePosition) 5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position upstream(visiblePosition.deepEquivalent().upstream()); 5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (upstream.node() && upstream.node()->renderer() && upstream.node()->renderer()->isTable() && upstream.offset() == maxDeepOffset(upstream.node())) 5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return upstream.node(); 5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 5318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* isLastPositionBeforeTable(const VisiblePosition& visiblePosition) 5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position downstream(visiblePosition.deepEquivalent().downstream()); 5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (downstream.node() && downstream.node()->renderer() && downstream.node()->renderer()->isTable() && downstream.offset() == 0) 5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return downstream.node(); 5388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition positionBeforeNode(const Node *node) 5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Position(node->parentNode(), node->nodeIndex()); 5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition positionAfterNode(const Node *node) 5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Position(node->parentNode(), node->nodeIndex() + 1); 5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool isListElement(Node *n) 5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return (n && (n->hasTagName(ulTag) || n->hasTagName(olTag) || n->hasTagName(dlTag))); 5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* enclosingNodeWithTag(const Position& p, const QualifiedName& tagName) 5588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (p.isNull()) 5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* root = highestEditableRoot(p); 5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (Node* n = p.node(); n; n = n->parentNode()) { 5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (root && !isContentEditable(n)) 5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (n->hasTagName(tagName)) 5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return n; 5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (n == root) 5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 5738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* enclosingNodeOfType(const Position& p, bool (*nodeIsOfType)(const Node*), bool onlyReturnEditableNodes) 5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (p.isNull()) 5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* root = highestEditableRoot(p); 5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (Node* n = p.node(); n; n = n->parentNode()) { 5828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Don't return a non-editable node if the input position was editable, since 5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the callers from editing will no doubt want to perform editing inside the returned node. 5848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (root && !isContentEditable(n) && onlyReturnEditableNodes) 5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if ((*nodeIsOfType)(n)) 5878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return n; 5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (n == root) 5898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 5908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 5938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* enclosingTableCell(const Position& p) 5968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return enclosingNodeOfType(p, &isTableCell); 5988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* enclosingAnchorElement(const Position& p) 6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (p.isNull()) 6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* node = p.node(); 6068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (node && !(node->isElementNode() && node->isLink())) 6078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project node = node->parentNode(); 6088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return node; 6098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* enclosingList(Node* node) 6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!node) 6148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* root = highestEditableRoot(Position(node, 0)); 6178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (Node* n = node->parentNode(); n; n = n->parentNode()) { 6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (n->hasTagName(ulTag) || n->hasTagName(olTag)) 6208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return n; 6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (n == root) 6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 6238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 6268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* enclosingListChild(Node *node) 6298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!node) 6318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 6328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check for a list item element, or for a node whose parent is a list element. Such a node 6338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // will appear visually as a list item (but without a list marker) 6348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* root = highestEditableRoot(Position(node, 0)); 6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: This function is inappropriately named if it starts with node instead of node->parentNode() 6378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (Node* n = node; n && n->parentNode(); n = n->parentNode()) { 6388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (n->hasTagName(liTag) || isListElement(n->parentNode())) 6398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return n; 6408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (n == root || isTableCell(n)) 6418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 6428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic Node* embeddedSublist(Node* listItem) 6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check the DOM so that we'll find collapsed sublists without renderers. 6508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (Node* n = listItem->firstChild(); n; n = n->nextSibling()) { 6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isListElement(n)) 6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return n; 6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 6568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic Node* appendedSublist(Node* listItem) 6598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check the DOM so that we'll find collapsed sublists without renderers. 6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (Node* n = listItem->nextSibling(); n; n = n->nextSibling()) { 6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isListElement(n)) 6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return n; 6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (n->renderer() && n->renderer()->isListItem()) 6658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 6668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 6698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* enclosingEmptyListItem(const VisiblePosition& visiblePos) 6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check that position is on a line by itself inside a list item 6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* listChildNode = enclosingListChild(visiblePos.deepEquivalent().node()); 6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!listChildNode || !isStartOfParagraph(visiblePos) || !isEndOfParagraph(visiblePos)) 6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project VisiblePosition firstInListChild(Position(listChildNode, 0)); 6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project VisiblePosition lastInListChild(Position(listChildNode, maxDeepOffset(listChildNode))); 6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (firstInListChild != visiblePos || lastInListChild != visiblePos) 6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (embeddedSublist(listChildNode) || appendedSublist(listChildNode)) 6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return listChildNode; 6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* outermostEnclosingListChild(Node* node) 6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* listNode = 0; 6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* nextNode = node; 6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while ((nextNode = enclosingListChild(nextNode))) 6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project listNode = nextNode; 6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return listNode; 6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* outermostEnclosingList(Node* node) 7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* listNode = 0; 7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* nextNode = node; 7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while ((nextNode = enclosingList(nextNode))) 7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project listNode = nextNode; 7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return listNode; 7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* highestAncestor(Node* node) 7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(node); 7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* parent = node; 7128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while ((node = node->parentNode())) 7138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project parent = node; 7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return parent; 7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// FIXME: do not require renderer, so that this can be used within fragments, or rename to isRenderedTable() 7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool isTableElement(Node* n) 7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!n || !n->isElementNode()) 7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* renderer = n->renderer(); 7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return (renderer && (renderer->style()->display() == TABLE || renderer->style()->display() == INLINE_TABLE)); 7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool isTableCell(const Node* node) 7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* r = node->renderer(); 7308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!r) 7318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return node->hasTagName(tdTag) || node->hasTagName(thTag); 7328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return r->isTableCell(); 7348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Element> createDefaultParagraphElement(Document *document) 7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ExceptionCode ec = 0; 7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<Element> element = document->createElementNS(xhtmlNamespaceURI, "div", ec); 7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(ec == 0); 7418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return element.release(); 7428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Element> createBreakElement(Document *document) 7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ExceptionCode ec = 0; 7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<Element> breakNode = document->createElementNS(xhtmlNamespaceURI, "br", ec); 7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(ec == 0); 7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return breakNode.release(); 7508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Element> createOrderedListElement(Document *document) 7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ExceptionCode ec = 0; 7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<Element> element = document->createElementNS(xhtmlNamespaceURI, "ol", ec); 7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(ec == 0); 7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return element.release(); 7588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Element> createUnorderedListElement(Document *document) 7618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ExceptionCode ec = 0; 7638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<Element> element = document->createElementNS(xhtmlNamespaceURI, "ul", ec); 7648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(ec == 0); 7658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return element.release(); 7668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Element> createListItemElement(Document *document) 7698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ExceptionCode ec = 0; 7718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<Element> breakNode = document->createElementNS(xhtmlNamespaceURI, "li", ec); 7728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(ec == 0); 7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return breakNode.release(); 7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Element> createElement(Document* document, const String& tagName) 7778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ExceptionCode ec = 0; 7798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<Element> breakNode = document->createElementNS(xhtmlNamespaceURI, tagName, ec); 7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(ec == 0); 7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return breakNode.release(); 7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool isTabSpanNode(const Node *node) 7858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return node && node->hasTagName(spanTag) && node->isElementNode() && static_cast<const Element *>(node)->getAttribute(classAttr) == AppleTabSpanClass; 7878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool isTabSpanTextNode(const Node *node) 7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return node && node->isTextNode() && node->parentNode() && isTabSpanNode(node->parentNode()); 7928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode *tabSpanNode(const Node *node) 7958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return isTabSpanTextNode(node) ? node->parentNode() : 0; 7978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition positionBeforeTabSpan(const Position& pos) 8008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node *node = pos.node(); 8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isTabSpanTextNode(node)) 8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project node = tabSpanNode(node); 8048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else if (!isTabSpanNode(node)) 8058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return pos; 8068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return positionBeforeNode(node); 8088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Element> createTabSpanElement(Document* document, PassRefPtr<Node> tabTextNode) 8118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // make the span to hold the tab 8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ExceptionCode ec = 0; 8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<Element> spanElement = document->createElementNS(xhtmlNamespaceURI, "span", ec); 8158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(ec == 0); 8168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project spanElement->setAttribute(classAttr, AppleTabSpanClass); 8178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project spanElement->setAttribute(styleAttr, "white-space:pre"); 8188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // add tab text to that span 8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!tabTextNode) 8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project tabTextNode = document->createEditingTextNode("\t"); 8228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project spanElement->appendChild(tabTextNode, ec); 8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(ec == 0); 8248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return spanElement.release(); 8268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Element> createTabSpanElement(Document* document, const String& tabText) 8298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return createTabSpanElement(document, document->createTextNode(tabText)); 8318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Element> createTabSpanElement(Document* document) 8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return createTabSpanElement(document, PassRefPtr<Node>()); 8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool isNodeRendered(const Node *node) 8398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!node) 8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 8428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject *renderer = node->renderer(); 8448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!renderer) 8458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return renderer->style()->visibility() == VISIBLE; 8488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode *nearestMailBlockquote(const Node *node) 8518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (Node *n = const_cast<Node *>(node); n; n = n->parentNode()) { 8538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isMailBlockquote(n)) 8548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return n; 8558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 8578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool isMailBlockquote(const Node *node) 8608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!node || !node->isElementNode() && !node->hasTagName(blockquoteTag)) 8628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 8638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return static_cast<const Element *>(node)->getAttribute("type") == "cite"; 8658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint caretMinOffset(const Node* n) 8688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* r = n->renderer(); 8708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!n->isCharacterDataNode() || !r || r->isText()); // FIXME: This was a runtime check that seemingly couldn't fail; changed it to an assertion for now. 8718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return r ? r->caretMinOffset() : 0; 8728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint caretMaxOffset(const Node* n) 8758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* r = n->renderer(); 8778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!n->isCharacterDataNode() || !r || r->isText()); // FIXME: This was a runtime check that seemingly couldn't fail; changed it to an assertion for now. 8788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (r) 8798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return r->caretMaxOffset(); 8808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (n->isCharacterDataNode()) { 8828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const CharacterData* c = static_cast<const CharacterData*>(n); 8838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return static_cast<int>(c->length()); 8848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 1; 8868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool lineBreakExistsAtPosition(const VisiblePosition& visiblePosition) 8898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (visiblePosition.isNull()) 8918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 8928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position downstream(visiblePosition.deepEquivalent().downstream()); 8948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return downstream.node()->hasTagName(brTag) || 8958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project downstream.node()->isTextNode() && downstream.node()->renderer()->style()->preserveNewline() && visiblePosition.characterAfter() == '\n'; 8968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Modifies selections that have an end point at the edge of a table 8998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// that contains the other endpoint so that they don't confuse 9008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// code that iterates over selected paragraphs. 9018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSelection selectionForParagraphIteration(const Selection& original) 9028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 9038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Selection newSelection(original); 9048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project VisiblePosition startOfSelection(newSelection.visibleStart()); 9058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project VisiblePosition endOfSelection(newSelection.visibleEnd()); 9068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the end of the selection to modify is just after a table, and 9088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // if the start of the selection is inside that table, then the last paragraph 9098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // that we'll want modify is the last one inside the table, not the table itself 9108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // (a table is itself a paragraph). 9118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (Node* table = isFirstPositionAfterTable(endOfSelection)) 9128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (startOfSelection.deepEquivalent().node()->isDescendantOf(table)) 9138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newSelection = Selection(startOfSelection, endOfSelection.previous(true)); 9148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the start of the selection to modify is just before a table, 9168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // and if the end of the selection is inside that table, then the first paragraph 9178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // we'll want to modify is the first one inside the table, not the paragraph 9188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // containing the table itself. 9198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (Node* table = isLastPositionBeforeTable(startOfSelection)) 9208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (endOfSelection.deepEquivalent().node()->isDescendantOf(table)) 9218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newSelection = Selection(startOfSelection.next(true), endOfSelection); 9228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return newSelection; 9248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint indexForVisiblePosition(VisiblePosition& visiblePosition) 9288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 9298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (visiblePosition.isNull()) 9308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 9318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Position p(visiblePosition.deepEquivalent()); 9328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<Range> range = Range::create(p.node()->document(), Position(p.node()->document(), 0), rangeCompliantEquivalent(p)); 9338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return TextIterator::rangeLength(range.get(), true); 9348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Range> avoidIntersectionWithNode(const Range* range, Node* node) 9378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 9388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!range) 9398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 9408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Document* document = range->ownerDocument(); 9428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* startContainer = range->startContainer(); 9448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int startOffset = range->startOffset(); 9458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* endContainer = range->endContainer(); 9468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int endOffset = range->endOffset(); 9478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!startContainer) 9498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 9508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(endContainer); 9528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (startContainer == node || startContainer->isDescendantOf(node)) { 9548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(node->parentNode()); 9558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project startContainer = node->parentNode(); 9568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project startOffset = node->nodeIndex(); 9578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (endContainer == node || endContainer->isDescendantOf(node)) { 9598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(node->parentNode()); 9608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project endContainer = node->parentNode(); 9618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project endOffset = node->nodeIndex(); 9628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Range::create(document, startContainer, startOffset, endContainer, endOffset); 9658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSelection avoidIntersectionWithNode(const Selection& selection, Node* node) 9688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 9698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (selection.isNone()) 9708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Selection(selection); 9718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Selection updatedSelection(selection); 9738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* base = selection.base().node(); 9748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* extent = selection.extent().node(); 9758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(base); 9768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(extent); 9778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (base == node || base->isDescendantOf(node)) { 9798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(node->parentNode()); 9808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project updatedSelection.setBase(Position(node->parentNode(), node->nodeIndex())); 9818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (extent == node || extent->isDescendantOf(node)) { 9848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(node->parentNode()); 9858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project updatedSelection.setExtent(Position(node->parentNode(), node->nodeIndex())); 9868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return updatedSelection; 9898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore 992