Home | History | Annotate | Download | only in editing
      1 /*
      2  * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "htmlediting.h"
     28 
     29 #include "CharacterNames.h"
     30 #include "Document.h"
     31 #include "EditingText.h"
     32 #include "HTMLBRElement.h"
     33 #include "HTMLDivElement.h"
     34 #include "HTMLElementFactory.h"
     35 #include "HTMLInterchange.h"
     36 #include "HTMLLIElement.h"
     37 #include "HTMLNames.h"
     38 #include "HTMLOListElement.h"
     39 #include "HTMLUListElement.h"
     40 #include "PositionIterator.h"
     41 #include "RenderObject.h"
     42 #include "Range.h"
     43 #include "VisibleSelection.h"
     44 #include "Text.h"
     45 #include "TextIterator.h"
     46 #include "VisiblePosition.h"
     47 #include "visible_units.h"
     48 #include <wtf/StdLibExtras.h>
     49 
     50 #if ENABLE(WML)
     51 #include "WMLNames.h"
     52 #endif
     53 
     54 using namespace std;
     55 
     56 namespace WebCore {
     57 
     58 using namespace HTMLNames;
     59 
     60 // Atomic means that the node has no children, or has children which are ignored for the
     61 // purposes of editing.
     62 bool isAtomicNode(const Node *node)
     63 {
     64     return node && (!node->hasChildNodes() || editingIgnoresContent(node));
     65 }
     66 
     67 // Returns true for nodes that either have no content, or have content that is ignored (skipped
     68 // over) while editing.  There are no VisiblePositions inside these nodes.
     69 bool editingIgnoresContent(const Node* node)
     70 {
     71     return !canHaveChildrenForEditing(node) && !node->isTextNode();
     72 }
     73 
     74 bool canHaveChildrenForEditing(const Node* node)
     75 {
     76     return !node->hasTagName(hrTag) &&
     77            !node->hasTagName(brTag) &&
     78            !node->hasTagName(imgTag) &&
     79            !node->hasTagName(buttonTag) &&
     80            !node->hasTagName(inputTag) &&
     81            !node->hasTagName(textareaTag) &&
     82            !node->hasTagName(objectTag) &&
     83            !node->hasTagName(iframeTag) &&
     84            !node->hasTagName(embedTag) &&
     85            !node->hasTagName(appletTag) &&
     86            !node->hasTagName(selectTag) &&
     87            !node->hasTagName(datagridTag) &&
     88 #if ENABLE(WML)
     89            !node->hasTagName(WMLNames::doTag) &&
     90 #endif
     91            !node->isTextNode();
     92 }
     93 
     94 // Compare two positions, taking into account the possibility that one or both
     95 // could be inside a shadow tree. Only works for non-null values.
     96 int comparePositions(const Position& a, const Position& b)
     97 {
     98     Node* nodeA = a.node();
     99     ASSERT(nodeA);
    100     Node* nodeB = b.node();
    101     ASSERT(nodeB);
    102     int offsetA = a.deprecatedEditingOffset();
    103     int offsetB = b.deprecatedEditingOffset();
    104 
    105     Node* shadowAncestorA = nodeA->shadowAncestorNode();
    106     if (shadowAncestorA == nodeA)
    107         shadowAncestorA = 0;
    108     Node* shadowAncestorB = nodeB->shadowAncestorNode();
    109     if (shadowAncestorB == nodeB)
    110         shadowAncestorB = 0;
    111 
    112     int bias = 0;
    113     if (shadowAncestorA != shadowAncestorB) {
    114         if (shadowAncestorA) {
    115             nodeA = shadowAncestorA;
    116             offsetA = 0;
    117             bias = 1;
    118         }
    119         if (shadowAncestorB) {
    120             nodeB = shadowAncestorB;
    121             offsetB = 0;
    122             bias = -1;
    123         }
    124     }
    125 
    126     int result = Range::compareBoundaryPoints(nodeA, offsetA, nodeB, offsetB);
    127     return result ? result : bias;
    128 }
    129 
    130 int comparePositions(const VisiblePosition& a, const VisiblePosition& b)
    131 {
    132     return comparePositions(a.deepEquivalent(), b.deepEquivalent());
    133 }
    134 
    135 Node* highestEditableRoot(const Position& position)
    136 {
    137     Node* node = position.node();
    138     if (!node)
    139         return 0;
    140 
    141     Node* highestRoot = editableRootForPosition(position);
    142     if (!highestRoot)
    143         return 0;
    144 
    145     node = highestRoot;
    146     while (node) {
    147         if (node->isContentEditable())
    148             highestRoot = node;
    149         if (node->hasTagName(bodyTag))
    150             break;
    151         node = node->parentNode();
    152     }
    153 
    154     return highestRoot;
    155 }
    156 
    157 Node* lowestEditableAncestor(Node* node)
    158 {
    159     if (!node)
    160         return 0;
    161 
    162     Node *lowestRoot = 0;
    163     while (node) {
    164         if (node->isContentEditable())
    165             return node->rootEditableElement();
    166         if (node->hasTagName(bodyTag))
    167             break;
    168         node = node->parentNode();
    169     }
    170 
    171     return lowestRoot;
    172 }
    173 
    174 bool isEditablePosition(const Position& p)
    175 {
    176     Node* node = p.node();
    177     if (!node)
    178         return false;
    179 
    180     if (node->renderer() && node->renderer()->isTable())
    181         node = node->parentNode();
    182 
    183     return node->isContentEditable();
    184 }
    185 
    186 bool isAtUnsplittableElement(const Position& pos)
    187 {
    188     Node* node = pos.node();
    189     return (node == editableRootForPosition(pos) || node == enclosingNodeOfType(pos, &isTableCell));
    190 }
    191 
    192 
    193 bool isRichlyEditablePosition(const Position& p)
    194 {
    195     Node* node = p.node();
    196     if (!node)
    197         return false;
    198 
    199     if (node->renderer() && node->renderer()->isTable())
    200         node = node->parentNode();
    201 
    202     return node->isContentRichlyEditable();
    203 }
    204 
    205 Element* editableRootForPosition(const Position& p)
    206 {
    207     Node* node = p.node();
    208     if (!node)
    209         return 0;
    210 
    211     if (node->renderer() && node->renderer()->isTable())
    212         node = node->parentNode();
    213 
    214     return node->rootEditableElement();
    215 }
    216 
    217 // Finds the enclosing element until which the tree can be split.
    218 // When a user hits ENTER, he/she won't expect this element to be split into two.
    219 // You may pass it as the second argument of splitTreeToNode.
    220 Element* unsplittableElementForPosition(const Position& p)
    221 {
    222     // Since enclosingNodeOfType won't search beyond the highest root editable node,
    223     // this code works even if the closest table cell was outside of the root editable node.
    224     Element* enclosingCell = static_cast<Element*>(enclosingNodeOfType(p, &isTableCell, true));
    225     if (enclosingCell)
    226         return enclosingCell;
    227 
    228     return editableRootForPosition(p);
    229 }
    230 
    231 Position nextCandidate(const Position& position)
    232 {
    233     PositionIterator p = position;
    234     while (!p.atEnd()) {
    235         p.increment();
    236         if (p.isCandidate())
    237             return p;
    238     }
    239     return Position();
    240 }
    241 
    242 Position nextVisuallyDistinctCandidate(const Position& position)
    243 {
    244     Position p = position;
    245     Position downstreamStart = p.downstream();
    246     while (!p.atEndOfTree()) {
    247         p = p.next(Character);
    248         if (p.isCandidate() && p.downstream() != downstreamStart)
    249             return p;
    250     }
    251     return Position();
    252 }
    253 
    254 Position previousCandidate(const Position& position)
    255 {
    256     PositionIterator p = position;
    257     while (!p.atStart()) {
    258         p.decrement();
    259         if (p.isCandidate())
    260             return p;
    261     }
    262     return Position();
    263 }
    264 
    265 Position previousVisuallyDistinctCandidate(const Position& position)
    266 {
    267     Position p = position;
    268     Position downstreamStart = p.downstream();
    269     while (!p.atStartOfTree()) {
    270         p = p.previous(Character);
    271         if (p.isCandidate() && p.downstream() != downstreamStart)
    272             return p;
    273     }
    274     return Position();
    275 }
    276 
    277 VisiblePosition firstEditablePositionAfterPositionInRoot(const Position& position, Node* highestRoot)
    278 {
    279     // position falls before highestRoot.
    280     if (comparePositions(position, firstDeepEditingPositionForNode(highestRoot)) == -1 && highestRoot->isContentEditable())
    281         return firstDeepEditingPositionForNode(highestRoot);
    282 
    283     Position p = position;
    284 
    285     if (Node* shadowAncestor = p.node()->shadowAncestorNode())
    286         if (shadowAncestor != p.node())
    287             p = lastDeepEditingPositionForNode(shadowAncestor);
    288 
    289     while (p.node() && !isEditablePosition(p) && p.node()->isDescendantOf(highestRoot))
    290         p = isAtomicNode(p.node()) ? positionInParentAfterNode(p.node()) : nextVisuallyDistinctCandidate(p);
    291 
    292     if (p.node() && p.node() != highestRoot && !p.node()->isDescendantOf(highestRoot))
    293         return VisiblePosition();
    294 
    295     return VisiblePosition(p);
    296 }
    297 
    298 VisiblePosition lastEditablePositionBeforePositionInRoot(const Position& position, Node* highestRoot)
    299 {
    300     // When position falls after highestRoot, the result is easy to compute.
    301     if (comparePositions(position, lastDeepEditingPositionForNode(highestRoot)) == 1)
    302         return lastDeepEditingPositionForNode(highestRoot);
    303 
    304     Position p = position;
    305 
    306     if (Node* shadowAncestor = p.node()->shadowAncestorNode())
    307         if (shadowAncestor != p.node())
    308             p = firstDeepEditingPositionForNode(shadowAncestor);
    309 
    310     while (p.node() && !isEditablePosition(p) && p.node()->isDescendantOf(highestRoot))
    311         p = isAtomicNode(p.node()) ? positionInParentBeforeNode(p.node()) : previousVisuallyDistinctCandidate(p);
    312 
    313     if (p.node() && p.node() != highestRoot && !p.node()->isDescendantOf(highestRoot))
    314         return VisiblePosition();
    315 
    316     return VisiblePosition(p);
    317 }
    318 
    319 // FIXME: The method name, comment, and code say three different things here!
    320 // Whether or not content before and after this node will collapse onto the same line as it.
    321 bool isBlock(const Node* node)
    322 {
    323     return node && node->renderer() && !node->renderer()->isInline();
    324 }
    325 
    326 // FIXME: Deploy this in all of the places where enclosingBlockFlow/enclosingBlockFlowOrTableElement are used.
    327 // FIXME: Pass a position to this function.  The enclosing block of [table, x] for example, should be the
    328 // block that contains the table and not the table, and this function should be the only one responsible for
    329 // knowing about these kinds of special cases.
    330 Node* enclosingBlock(Node* node)
    331 {
    332     return static_cast<Element*>(enclosingNodeOfType(Position(node, 0), isBlock));
    333 }
    334 
    335 // Internally editing uses "invalid" positions for historical reasons.  For
    336 // example, in <div><img /></div>, Editing might use (img, 1) for the position
    337 // after <img>, but we have to convert that to (div, 1) before handing the
    338 // position to a Range object.  Ideally all internal positions should
    339 // be "range compliant" for simplicity.
    340 Position rangeCompliantEquivalent(const Position& pos)
    341 {
    342     if (pos.isNull())
    343         return Position();
    344 
    345     Node* node = pos.node();
    346 
    347     if (pos.deprecatedEditingOffset() <= 0) {
    348         if (node->parentNode() && (editingIgnoresContent(node) || isTableElement(node)))
    349             return positionInParentBeforeNode(node);
    350         return Position(node, 0);
    351     }
    352 
    353     if (node->offsetInCharacters())
    354         return Position(node, min(node->maxCharacterOffset(), pos.deprecatedEditingOffset()));
    355 
    356     int maxCompliantOffset = node->childNodeCount();
    357     if (pos.deprecatedEditingOffset() > maxCompliantOffset) {
    358         if (node->parentNode())
    359             return positionInParentAfterNode(node);
    360 
    361         // there is no other option at this point than to
    362         // use the highest allowed position in the node
    363         return Position(node, maxCompliantOffset);
    364     }
    365 
    366     // Editing should never generate positions like this.
    367     if ((pos.deprecatedEditingOffset() < maxCompliantOffset) && editingIgnoresContent(node)) {
    368         ASSERT_NOT_REACHED();
    369         return node->parentNode() ? positionInParentBeforeNode(node) : Position(node, 0);
    370     }
    371 
    372     if (pos.deprecatedEditingOffset() == maxCompliantOffset && (editingIgnoresContent(node) || isTableElement(node)))
    373         return positionInParentAfterNode(node);
    374 
    375     return Position(pos);
    376 }
    377 
    378 Position rangeCompliantEquivalent(const VisiblePosition& vpos)
    379 {
    380     return rangeCompliantEquivalent(vpos.deepEquivalent());
    381 }
    382 
    383 // This method is used to create positions in the DOM. It returns the maximum valid offset
    384 // in a node.  It returns 1 for some elements even though they do not have children, which
    385 // creates technically invalid DOM Positions.  Be sure to call rangeCompliantEquivalent
    386 // on a Position before using it to create a DOM Range, or an exception will be thrown.
    387 int lastOffsetForEditing(const Node* node)
    388 {
    389     ASSERT(node);
    390     if (!node)
    391         return 0;
    392     if (node->offsetInCharacters())
    393         return node->maxCharacterOffset();
    394 
    395     if (node->hasChildNodes())
    396         return node->childNodeCount();
    397 
    398     // NOTE: This should preempt the childNodeCount for, e.g., select nodes
    399     if (editingIgnoresContent(node))
    400         return 1;
    401 
    402     return 0;
    403 }
    404 
    405 String stringWithRebalancedWhitespace(const String& string, bool startIsStartOfParagraph, bool endIsEndOfParagraph)
    406 {
    407     DEFINE_STATIC_LOCAL(String, twoSpaces, ("  "));
    408     DEFINE_STATIC_LOCAL(String, nbsp, ("\xa0"));
    409     DEFINE_STATIC_LOCAL(String, pattern, (" \xa0"));
    410 
    411     String rebalancedString = string;
    412 
    413     rebalancedString.replace(noBreakSpace, ' ');
    414     rebalancedString.replace('\n', ' ');
    415     rebalancedString.replace('\t', ' ');
    416 
    417     rebalancedString.replace(twoSpaces, pattern);
    418 
    419     if (startIsStartOfParagraph && rebalancedString[0] == ' ')
    420         rebalancedString.replace(0, 1, nbsp);
    421     int end = rebalancedString.length() - 1;
    422     if (endIsEndOfParagraph && rebalancedString[end] == ' ')
    423         rebalancedString.replace(end, 1, nbsp);
    424 
    425     return rebalancedString;
    426 }
    427 
    428 bool isTableStructureNode(const Node *node)
    429 {
    430     RenderObject *r = node->renderer();
    431     return (r && (r->isTableCell() || r->isTableRow() || r->isTableSection() || r->isTableCol()));
    432 }
    433 
    434 const String& nonBreakingSpaceString()
    435 {
    436     DEFINE_STATIC_LOCAL(String, nonBreakingSpaceString, (&noBreakSpace, 1));
    437     return nonBreakingSpaceString;
    438 }
    439 
    440 // FIXME: need to dump this
    441 bool isSpecialElement(const Node *n)
    442 {
    443     if (!n)
    444         return false;
    445 
    446     if (!n->isHTMLElement())
    447         return false;
    448 
    449     if (n->isLink())
    450         return true;
    451 
    452     RenderObject *renderer = n->renderer();
    453     if (!renderer)
    454         return false;
    455 
    456     if (renderer->style()->display() == TABLE || renderer->style()->display() == INLINE_TABLE)
    457         return true;
    458 
    459     if (renderer->style()->isFloating())
    460         return true;
    461 
    462     if (renderer->style()->position() != StaticPosition)
    463         return true;
    464 
    465     return false;
    466 }
    467 
    468 // Checks if a string is a valid tag for the FormatBlockCommand function of execCommand. Expects lower case strings.
    469 bool validBlockTag(const AtomicString& blockTag)
    470 {
    471     if (blockTag.isEmpty())
    472         return false;
    473 
    474     DEFINE_STATIC_LOCAL(HashSet<AtomicString>, blockTags, ());
    475     if (blockTags.isEmpty()) {
    476         blockTags.add(addressTag.localName());
    477         blockTags.add(articleTag.localName());
    478         blockTags.add(asideTag.localName());
    479         blockTags.add(blockquoteTag.localName());
    480         blockTags.add(ddTag.localName());
    481         blockTags.add(divTag.localName());
    482         blockTags.add(dlTag.localName());
    483         blockTags.add(dtTag.localName());
    484         blockTags.add(footerTag.localName());
    485         blockTags.add(h1Tag.localName());
    486         blockTags.add(h2Tag.localName());
    487         blockTags.add(h3Tag.localName());
    488         blockTags.add(h4Tag.localName());
    489         blockTags.add(h5Tag.localName());
    490         blockTags.add(h6Tag.localName());
    491         blockTags.add(headerTag.localName());
    492         blockTags.add(navTag.localName());
    493         blockTags.add(pTag.localName());
    494         blockTags.add(preTag.localName());
    495         blockTags.add(sectionTag.localName());
    496     }
    497     return blockTags.contains(blockTag);
    498 }
    499 
    500 static Node* firstInSpecialElement(const Position& pos)
    501 {
    502     // FIXME: This begins at pos.node(), which doesn't necessarily contain pos (suppose pos was [img, 0]).  See <rdar://problem/5027702>.
    503     Node* rootEditableElement = pos.node()->rootEditableElement();
    504     for (Node* n = pos.node(); n && n->rootEditableElement() == rootEditableElement; n = n->parentNode())
    505         if (isSpecialElement(n)) {
    506             VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
    507             VisiblePosition firstInElement = VisiblePosition(n, 0, DOWNSTREAM);
    508             if (isTableElement(n) && vPos == firstInElement.next())
    509                 return n;
    510             if (vPos == firstInElement)
    511                 return n;
    512         }
    513     return 0;
    514 }
    515 
    516 static Node* lastInSpecialElement(const Position& pos)
    517 {
    518     // FIXME: This begins at pos.node(), which doesn't necessarily contain pos (suppose pos was [img, 0]).  See <rdar://problem/5027702>.
    519     Node* rootEditableElement = pos.node()->rootEditableElement();
    520     for (Node* n = pos.node(); n && n->rootEditableElement() == rootEditableElement; n = n->parentNode())
    521         if (isSpecialElement(n)) {
    522             VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
    523             VisiblePosition lastInElement = VisiblePosition(n, n->childNodeCount(), DOWNSTREAM);
    524             if (isTableElement(n) && vPos == lastInElement.previous())
    525                 return n;
    526             if (vPos == lastInElement)
    527                 return n;
    528         }
    529     return 0;
    530 }
    531 
    532 bool isFirstVisiblePositionInSpecialElement(const Position& pos)
    533 {
    534     return firstInSpecialElement(pos);
    535 }
    536 
    537 Position positionBeforeContainingSpecialElement(const Position& pos, Node** containingSpecialElement)
    538 {
    539     Node* n = firstInSpecialElement(pos);
    540     if (!n)
    541         return pos;
    542     Position result = positionInParentBeforeNode(n);
    543     if (result.isNull() || result.node()->rootEditableElement() != pos.node()->rootEditableElement())
    544         return pos;
    545     if (containingSpecialElement)
    546         *containingSpecialElement = n;
    547     return result;
    548 }
    549 
    550 bool isLastVisiblePositionInSpecialElement(const Position& pos)
    551 {
    552     return lastInSpecialElement(pos);
    553 }
    554 
    555 Position positionAfterContainingSpecialElement(const Position& pos, Node **containingSpecialElement)
    556 {
    557     Node* n = lastInSpecialElement(pos);
    558     if (!n)
    559         return pos;
    560     Position result = positionInParentAfterNode(n);
    561     if (result.isNull() || result.node()->rootEditableElement() != pos.node()->rootEditableElement())
    562         return pos;
    563     if (containingSpecialElement)
    564         *containingSpecialElement = n;
    565     return result;
    566 }
    567 
    568 Position positionOutsideContainingSpecialElement(const Position &pos, Node **containingSpecialElement)
    569 {
    570     if (isFirstVisiblePositionInSpecialElement(pos))
    571         return positionBeforeContainingSpecialElement(pos, containingSpecialElement);
    572     if (isLastVisiblePositionInSpecialElement(pos))
    573         return positionAfterContainingSpecialElement(pos, containingSpecialElement);
    574     return pos;
    575 }
    576 
    577 Node* isFirstPositionAfterTable(const VisiblePosition& visiblePosition)
    578 {
    579     Position upstream(visiblePosition.deepEquivalent().upstream());
    580     if (upstream.node() && upstream.node()->renderer() && upstream.node()->renderer()->isTable() && upstream.atLastEditingPositionForNode())
    581         return upstream.node();
    582 
    583     return 0;
    584 }
    585 
    586 Node* isLastPositionBeforeTable(const VisiblePosition& visiblePosition)
    587 {
    588     Position downstream(visiblePosition.deepEquivalent().downstream());
    589     if (downstream.node() && downstream.node()->renderer() && downstream.node()->renderer()->isTable() && downstream.atFirstEditingPositionForNode())
    590         return downstream.node();
    591 
    592     return 0;
    593 }
    594 
    595 // Returns the visible position at the beginning of a node
    596 VisiblePosition visiblePositionBeforeNode(Node* node)
    597 {
    598     ASSERT(node);
    599     if (node->childNodeCount())
    600         return VisiblePosition(node, 0, DOWNSTREAM);
    601     ASSERT(node->parentNode());
    602     return positionInParentBeforeNode(node);
    603 }
    604 
    605 // Returns the visible position at the ending of a node
    606 VisiblePosition visiblePositionAfterNode(Node* node)
    607 {
    608     ASSERT(node);
    609     if (node->childNodeCount())
    610         return VisiblePosition(node, node->childNodeCount(), DOWNSTREAM);
    611     ASSERT(node->parentNode());
    612     return positionInParentAfterNode(node);
    613 }
    614 
    615 // Create a range object with two visible positions, start and end.
    616 // create(PassRefPtr<Document>, const Position&, const Position&); will use deprecatedEditingOffset
    617 // Use this function instead of create a regular range object (avoiding editing offset).
    618 PassRefPtr<Range> createRange(PassRefPtr<Document> document, const VisiblePosition& start, const VisiblePosition& end, ExceptionCode& ec)
    619 {
    620     ec = 0;
    621     RefPtr<Range> selectedRange = Range::create(document);
    622     selectedRange->setStart(start.deepEquivalent().containerNode(), start.deepEquivalent().computeOffsetInContainerNode(), ec);
    623     if (!ec)
    624         selectedRange->setEnd(end.deepEquivalent().containerNode(), end.deepEquivalent().computeOffsetInContainerNode(), ec);
    625     return selectedRange.release();
    626 }
    627 
    628 // Extend rangeToExtend to include nodes that wraps range and visibly starts and ends inside or at the boudnaries of maximumRange
    629 // e.g. if the original range spaned "hello" in <div>hello</div>, then this function extends the range to contain div's around it.
    630 // Call this function before copying / moving paragraphs to contain all wrapping nodes.
    631 // This function stops extending the range immediately below rootNode; i.e. the extended range can contain a child node of rootNode
    632 // but it can never contain rootNode itself.
    633 PassRefPtr<Range> extendRangeToWrappingNodes(PassRefPtr<Range> range, const Range* maximumRange, const Node* rootNode)
    634 {
    635     ASSERT(range);
    636     ASSERT(maximumRange);
    637 
    638     ExceptionCode ec = 0;
    639     Node* ancestor = range->commonAncestorContainer(ec);// find the cloeset common ancestor
    640     Node* highestNode = 0;
    641     // traverse through ancestors as long as they are contained within the range, content-editable, and below rootNode (could be =0).
    642     while (ancestor && ancestor->isContentEditable() && isNodeVisiblyContainedWithin(ancestor, maximumRange) && ancestor != rootNode) {
    643         highestNode = ancestor;
    644         ancestor = ancestor->parentNode();
    645     }
    646 
    647     if (!highestNode)
    648         return range;
    649 
    650     // Create new range with the highest editable node contained within the range
    651     RefPtr<Range> extendedRange = Range::create(range->ownerDocument());
    652     extendedRange->selectNode(highestNode, ec);
    653     return extendedRange.release();
    654 }
    655 
    656 bool isListElement(Node *n)
    657 {
    658     return (n && (n->hasTagName(ulTag) || n->hasTagName(olTag) || n->hasTagName(dlTag)));
    659 }
    660 
    661 bool isListItem(Node *n)
    662 {
    663     return n && n->renderer() && n->renderer()->isListItem();
    664 }
    665 
    666 Node* enclosingNodeWithTag(const Position& p, const QualifiedName& tagName)
    667 {
    668     if (p.isNull())
    669         return 0;
    670 
    671     Node* root = highestEditableRoot(p);
    672     for (Node* n = p.node(); n; n = n->parentNode()) {
    673         if (root && !n->isContentEditable())
    674             continue;
    675         if (n->hasTagName(tagName))
    676             return n;
    677         if (n == root)
    678             return 0;
    679     }
    680 
    681     return 0;
    682 }
    683 
    684 Node* enclosingNodeOfType(const Position& p, bool (*nodeIsOfType)(const Node*), bool onlyReturnEditableNodes)
    685 {
    686     if (p.isNull())
    687         return 0;
    688 
    689     Node* root = highestEditableRoot(p);
    690     for (Node* n = p.node(); n; n = n->parentNode()) {
    691         // Don't return a non-editable node if the input position was editable, since
    692         // the callers from editing will no doubt want to perform editing inside the returned node.
    693         if (root && !n->isContentEditable() && onlyReturnEditableNodes)
    694             continue;
    695         if ((*nodeIsOfType)(n))
    696             return n;
    697         if (n == root)
    698             return 0;
    699     }
    700 
    701     return 0;
    702 }
    703 
    704 Node* highestEnclosingNodeOfType(const Position& p, bool (*nodeIsOfType)(const Node*))
    705 {
    706     Node* highest = 0;
    707     Node* root = highestEditableRoot(p);
    708     for (Node* n = p.node(); n; n = n->parentNode()) {
    709         if ((*nodeIsOfType)(n))
    710             highest = n;
    711         if (n == root)
    712             break;
    713     }
    714 
    715     return highest;
    716 }
    717 
    718 Node* enclosingTableCell(const Position& p)
    719 {
    720     return static_cast<Element*>(enclosingNodeOfType(p, isTableCell));
    721 }
    722 
    723 Node* enclosingAnchorElement(const Position& p)
    724 {
    725     if (p.isNull())
    726         return 0;
    727 
    728     Node* node = p.node();
    729     while (node && !(node->isElementNode() && node->isLink()))
    730         node = node->parentNode();
    731     return node;
    732 }
    733 
    734 HTMLElement* enclosingList(Node* node)
    735 {
    736     if (!node)
    737         return 0;
    738 
    739     Node* root = highestEditableRoot(Position(node, 0));
    740 
    741     for (Node* n = node->parentNode(); n; n = n->parentNode()) {
    742         if (n->hasTagName(ulTag) || n->hasTagName(olTag))
    743             return static_cast<HTMLElement*>(n);
    744         if (n == root)
    745             return 0;
    746     }
    747 
    748     return 0;
    749 }
    750 
    751 HTMLElement* enclosingListChild(Node *node)
    752 {
    753     if (!node)
    754         return 0;
    755     // Check for a list item element, or for a node whose parent is a list element.  Such a node
    756     // will appear visually as a list item (but without a list marker)
    757     Node* root = highestEditableRoot(Position(node, 0));
    758 
    759     // FIXME: This function is inappropriately named if it starts with node instead of node->parentNode()
    760     for (Node* n = node; n && n->parentNode(); n = n->parentNode()) {
    761         if (n->hasTagName(liTag) || isListElement(n->parentNode()))
    762             return static_cast<HTMLElement*>(n);
    763         if (n == root || isTableCell(n))
    764             return 0;
    765     }
    766 
    767     return 0;
    768 }
    769 
    770 static HTMLElement* embeddedSublist(Node* listItem)
    771 {
    772     // Check the DOM so that we'll find collapsed sublists without renderers.
    773     for (Node* n = listItem->firstChild(); n; n = n->nextSibling()) {
    774         if (isListElement(n))
    775             return static_cast<HTMLElement*>(n);
    776     }
    777 
    778     return 0;
    779 }
    780 
    781 static Node* appendedSublist(Node* listItem)
    782 {
    783     // Check the DOM so that we'll find collapsed sublists without renderers.
    784     for (Node* n = listItem->nextSibling(); n; n = n->nextSibling()) {
    785         if (isListElement(n))
    786             return static_cast<HTMLElement*>(n);
    787         if (isListItem(listItem))
    788             return 0;
    789     }
    790 
    791     return 0;
    792 }
    793 
    794 // FIXME: This method should not need to call isStartOfParagraph/isEndOfParagraph
    795 Node* enclosingEmptyListItem(const VisiblePosition& visiblePos)
    796 {
    797     // Check that position is on a line by itself inside a list item
    798     Node* listChildNode = enclosingListChild(visiblePos.deepEquivalent().node());
    799     if (!listChildNode || !isStartOfParagraph(visiblePos) || !isEndOfParagraph(visiblePos))
    800         return 0;
    801 
    802     VisiblePosition firstInListChild(firstDeepEditingPositionForNode(listChildNode));
    803     VisiblePosition lastInListChild(lastDeepEditingPositionForNode(listChildNode));
    804 
    805     if (firstInListChild != visiblePos || lastInListChild != visiblePos)
    806         return 0;
    807 
    808     if (embeddedSublist(listChildNode) || appendedSublist(listChildNode))
    809         return 0;
    810 
    811     return listChildNode;
    812 }
    813 
    814 HTMLElement* outermostEnclosingList(Node* node)
    815 {
    816     HTMLElement* list = enclosingList(node);
    817     if (!list)
    818         return 0;
    819     while (HTMLElement* nextList = enclosingList(list))
    820         list = nextList;
    821     return list;
    822 }
    823 
    824 bool canMergeLists(Element* firstList, Element* secondList)
    825 {
    826     if (!firstList || !secondList)
    827         return false;
    828 
    829     return firstList->hasTagName(secondList->tagQName())// make sure the list types match (ol vs. ul)
    830     && firstList->isContentEditable() && secondList->isContentEditable()// both lists are editable
    831     && firstList->rootEditableElement() == secondList->rootEditableElement()// don't cross editing boundaries
    832     && isVisiblyAdjacent(positionInParentAfterNode(firstList), positionInParentBeforeNode(secondList));
    833     // Make sure there is no visible content between this li and the previous list
    834 }
    835 
    836 Node* highestAncestor(Node* node)
    837 {
    838     ASSERT(node);
    839     Node* parent = node;
    840     while ((node = node->parentNode()))
    841         parent = node;
    842     return parent;
    843 }
    844 
    845 // FIXME: do not require renderer, so that this can be used within fragments, or rename to isRenderedTable()
    846 bool isTableElement(Node* n)
    847 {
    848     if (!n || !n->isElementNode())
    849         return false;
    850 
    851     RenderObject* renderer = n->renderer();
    852     return (renderer && (renderer->style()->display() == TABLE || renderer->style()->display() == INLINE_TABLE));
    853 }
    854 
    855 bool isTableCell(const Node* node)
    856 {
    857     RenderObject* r = node->renderer();
    858     if (!r)
    859         return node->hasTagName(tdTag) || node->hasTagName(thTag);
    860 
    861     return r->isTableCell();
    862 }
    863 
    864 bool isEmptyTableCell(const Node* node)
    865 {
    866     return node && node->renderer() && (node->renderer()->isTableCell() || (node->renderer()->isBR() && node->parentNode()->renderer() && node->parentNode()->renderer()->isTableCell()));
    867 }
    868 
    869 PassRefPtr<HTMLElement> createDefaultParagraphElement(Document* document)
    870 {
    871     return new HTMLDivElement(divTag, document);
    872 }
    873 
    874 PassRefPtr<HTMLElement> createBreakElement(Document* document)
    875 {
    876     return new HTMLBRElement(brTag, document);
    877 }
    878 
    879 PassRefPtr<HTMLElement> createOrderedListElement(Document* document)
    880 {
    881     return new HTMLOListElement(olTag, document);
    882 }
    883 
    884 PassRefPtr<HTMLElement> createUnorderedListElement(Document* document)
    885 {
    886     return new HTMLUListElement(ulTag, document);
    887 }
    888 
    889 PassRefPtr<HTMLElement> createListItemElement(Document* document)
    890 {
    891     return new HTMLLIElement(liTag, document);
    892 }
    893 
    894 PassRefPtr<HTMLElement> createHTMLElement(Document* document, const QualifiedName& name)
    895 {
    896     return HTMLElementFactory::createHTMLElement(name, document, 0, false);
    897 }
    898 
    899 PassRefPtr<HTMLElement> createHTMLElement(Document* document, const AtomicString& tagName)
    900 {
    901     return createHTMLElement(document, QualifiedName(nullAtom, tagName, xhtmlNamespaceURI));
    902 }
    903 
    904 bool isTabSpanNode(const Node *node)
    905 {
    906     return node && node->hasTagName(spanTag) && node->isElementNode() && static_cast<const Element *>(node)->getAttribute(classAttr) == AppleTabSpanClass;
    907 }
    908 
    909 bool isTabSpanTextNode(const Node *node)
    910 {
    911     return node && node->isTextNode() && node->parentNode() && isTabSpanNode(node->parentNode());
    912 }
    913 
    914 Node *tabSpanNode(const Node *node)
    915 {
    916     return isTabSpanTextNode(node) ? node->parentNode() : 0;
    917 }
    918 
    919 bool isNodeInTextFormControl(Node* node)
    920 {
    921     if (!node)
    922         return false;
    923     Node* ancestor = node->shadowAncestorNode();
    924     if (ancestor == node)
    925         return false;
    926     return ancestor->isElementNode() && static_cast<Element*>(ancestor)->isTextFormControl();
    927 }
    928 
    929 Position positionBeforeTabSpan(const Position& pos)
    930 {
    931     Node *node = pos.node();
    932     if (isTabSpanTextNode(node))
    933         node = tabSpanNode(node);
    934     else if (!isTabSpanNode(node))
    935         return pos;
    936 
    937     return positionInParentBeforeNode(node);
    938 }
    939 
    940 PassRefPtr<Element> createTabSpanElement(Document* document, PassRefPtr<Node> tabTextNode)
    941 {
    942     // Make the span to hold the tab.
    943     RefPtr<Element> spanElement = document->createElement(spanTag, false);
    944     spanElement->setAttribute(classAttr, AppleTabSpanClass);
    945     spanElement->setAttribute(styleAttr, "white-space:pre");
    946 
    947     // Add tab text to that span.
    948     if (!tabTextNode)
    949         tabTextNode = document->createEditingTextNode("\t");
    950 
    951     ExceptionCode ec = 0;
    952     spanElement->appendChild(tabTextNode, ec);
    953     ASSERT(ec == 0);
    954 
    955     return spanElement.release();
    956 }
    957 
    958 PassRefPtr<Element> createTabSpanElement(Document* document, const String& tabText)
    959 {
    960     return createTabSpanElement(document, document->createTextNode(tabText));
    961 }
    962 
    963 PassRefPtr<Element> createTabSpanElement(Document* document)
    964 {
    965     return createTabSpanElement(document, PassRefPtr<Node>());
    966 }
    967 
    968 bool isNodeRendered(const Node *node)
    969 {
    970     if (!node)
    971         return false;
    972 
    973     RenderObject *renderer = node->renderer();
    974     if (!renderer)
    975         return false;
    976 
    977     return renderer->style()->visibility() == VISIBLE;
    978 }
    979 
    980 Node *nearestMailBlockquote(const Node *node)
    981 {
    982     for (Node *n = const_cast<Node *>(node); n; n = n->parentNode()) {
    983         if (isMailBlockquote(n))
    984             return n;
    985     }
    986     return 0;
    987 }
    988 
    989 unsigned numEnclosingMailBlockquotes(const Position& p)
    990 {
    991     unsigned num = 0;
    992     for (Node* n = p.node(); n; n = n->parentNode())
    993         if (isMailBlockquote(n))
    994             num++;
    995 
    996     return num;
    997 }
    998 
    999 bool isMailBlockquote(const Node *node)
   1000 {
   1001     if (!node || !node->hasTagName(blockquoteTag))
   1002         return false;
   1003 
   1004     return static_cast<const Element *>(node)->getAttribute("type") == "cite";
   1005 }
   1006 
   1007 int caretMinOffset(const Node* n)
   1008 {
   1009     RenderObject* r = n->renderer();
   1010     ASSERT(!n->isCharacterDataNode() || !r || r->isText()); // FIXME: This was a runtime check that seemingly couldn't fail; changed it to an assertion for now.
   1011     return r ? r->caretMinOffset() : 0;
   1012 }
   1013 
   1014 // If a node can contain candidates for VisiblePositions, return the offset of the last candidate, otherwise
   1015 // return the number of children for container nodes and the length for unrendered text nodes.
   1016 int caretMaxOffset(const Node* n)
   1017 {
   1018     // For rendered text nodes, return the last position that a caret could occupy.
   1019     if (n->isTextNode() && n->renderer())
   1020         return n->renderer()->caretMaxOffset();
   1021     // For containers return the number of children.  For others do the same as above.
   1022     return lastOffsetForEditing(n);
   1023 }
   1024 
   1025 bool lineBreakExistsAtVisiblePosition(const VisiblePosition& visiblePosition)
   1026 {
   1027     return lineBreakExistsAtPosition(visiblePosition.deepEquivalent().downstream());
   1028 }
   1029 
   1030 bool lineBreakExistsAtPosition(const Position& position)
   1031 {
   1032     if (position.isNull())
   1033         return false;
   1034 
   1035     if (position.anchorNode()->hasTagName(brTag) && position.atFirstEditingPositionForNode())
   1036         return true;
   1037 
   1038     if (!position.anchorNode()->isTextNode() || !position.anchorNode()->renderer()->style()->preserveNewline())
   1039         return false;
   1040 
   1041     Text* textNode = static_cast<Text*>(position.anchorNode());
   1042     unsigned offset = position.offsetInContainerNode();
   1043     return offset < textNode->length() && textNode->data()[offset] == '\n';
   1044 }
   1045 
   1046 // Modifies selections that have an end point at the edge of a table
   1047 // that contains the other endpoint so that they don't confuse
   1048 // code that iterates over selected paragraphs.
   1049 VisibleSelection selectionForParagraphIteration(const VisibleSelection& original)
   1050 {
   1051     VisibleSelection newSelection(original);
   1052     VisiblePosition startOfSelection(newSelection.visibleStart());
   1053     VisiblePosition endOfSelection(newSelection.visibleEnd());
   1054 
   1055     // If the end of the selection to modify is just after a table, and
   1056     // if the start of the selection is inside that table, then the last paragraph
   1057     // that we'll want modify is the last one inside the table, not the table itself
   1058     // (a table is itself a paragraph).
   1059     if (Node* table = isFirstPositionAfterTable(endOfSelection))
   1060         if (startOfSelection.deepEquivalent().node()->isDescendantOf(table))
   1061             newSelection = VisibleSelection(startOfSelection, endOfSelection.previous(true));
   1062 
   1063     // If the start of the selection to modify is just before a table,
   1064     // and if the end of the selection is inside that table, then the first paragraph
   1065     // we'll want to modify is the first one inside the table, not the paragraph
   1066     // containing the table itself.
   1067     if (Node* table = isLastPositionBeforeTable(startOfSelection))
   1068         if (endOfSelection.deepEquivalent().node()->isDescendantOf(table))
   1069             newSelection = VisibleSelection(startOfSelection.next(true), endOfSelection);
   1070 
   1071     return newSelection;
   1072 }
   1073 
   1074 
   1075 int indexForVisiblePosition(const VisiblePosition& visiblePosition)
   1076 {
   1077     if (visiblePosition.isNull())
   1078         return 0;
   1079     Position p(visiblePosition.deepEquivalent());
   1080     RefPtr<Range> range = Range::create(p.node()->document(), Position(p.node()->document(), 0), rangeCompliantEquivalent(p));
   1081     return TextIterator::rangeLength(range.get(), true);
   1082 }
   1083 
   1084 // Determines whether two positions are visibly next to each other (first then second)
   1085 // while ignoring whitespaces and unrendered nodes
   1086 bool isVisiblyAdjacent(const Position& first, const Position& second)
   1087 {
   1088     return VisiblePosition(first) == VisiblePosition(second.upstream());
   1089 }
   1090 
   1091 // Determines whether a node is inside a range or visibly starts and ends at the boundaries of the range.
   1092 // Call this function to determine whether a node is visibly fit inside selectedRange
   1093 bool isNodeVisiblyContainedWithin(Node* node, const Range* selectedRange)
   1094 {
   1095     ASSERT(node);
   1096     ASSERT(selectedRange);
   1097     // If the node is inside the range, then it surely is contained within
   1098     ExceptionCode ec = 0;
   1099     if (selectedRange->compareNode(node, ec) == Range::NODE_INSIDE)
   1100         return true;
   1101 
   1102     // If the node starts and ends at where selectedRange starts and ends, the node is contained within
   1103     return visiblePositionBeforeNode(node) == selectedRange->startPosition()
   1104         && visiblePositionAfterNode(node) == selectedRange->endPosition();
   1105 }
   1106 
   1107 bool isRenderedAsNonInlineTableImageOrHR(const Node* node)
   1108 {
   1109     if (!node)
   1110         return false;
   1111     RenderObject* renderer = node->renderer();
   1112     return renderer && ((renderer->isTable() && !renderer->isInline()) || (renderer->isImage() && !renderer->isInline()) || renderer->isHR());
   1113 }
   1114 
   1115 PassRefPtr<Range> avoidIntersectionWithNode(const Range* range, Node* node)
   1116 {
   1117     if (!range)
   1118         return 0;
   1119 
   1120     Document* document = range->ownerDocument();
   1121 
   1122     Node* startContainer = range->startContainer();
   1123     int startOffset = range->startOffset();
   1124     Node* endContainer = range->endContainer();
   1125     int endOffset = range->endOffset();
   1126 
   1127     if (!startContainer)
   1128         return 0;
   1129 
   1130     ASSERT(endContainer);
   1131 
   1132     if (startContainer == node || startContainer->isDescendantOf(node)) {
   1133         ASSERT(node->parentNode());
   1134         startContainer = node->parentNode();
   1135         startOffset = node->nodeIndex();
   1136     }
   1137     if (endContainer == node || endContainer->isDescendantOf(node)) {
   1138         ASSERT(node->parentNode());
   1139         endContainer = node->parentNode();
   1140         endOffset = node->nodeIndex();
   1141     }
   1142 
   1143     return Range::create(document, startContainer, startOffset, endContainer, endOffset);
   1144 }
   1145 
   1146 VisibleSelection avoidIntersectionWithNode(const VisibleSelection& selection, Node* node)
   1147 {
   1148     if (selection.isNone())
   1149         return VisibleSelection(selection);
   1150 
   1151     VisibleSelection updatedSelection(selection);
   1152     Node* base = selection.base().node();
   1153     Node* extent = selection.extent().node();
   1154     ASSERT(base);
   1155     ASSERT(extent);
   1156 
   1157     if (base == node || base->isDescendantOf(node)) {
   1158         ASSERT(node->parentNode());
   1159         updatedSelection.setBase(Position(node->parentNode(), node->nodeIndex()));
   1160     }
   1161 
   1162     if (extent == node || extent->isDescendantOf(node)) {
   1163         ASSERT(node->parentNode());
   1164         updatedSelection.setExtent(Position(node->parentNode(), node->nodeIndex()));
   1165     }
   1166 
   1167     return updatedSelection;
   1168 }
   1169 
   1170 } // namespace WebCore
   1171