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 "AXObjectCache.h"
30#include "Document.h"
31#include "Editor.h"
32#include "ExceptionCodePlaceholder.h"
33#include "Frame.h"
34#include "HTMLBRElement.h"
35#include "HTMLDivElement.h"
36#include "HTMLElementFactory.h"
37#include "HTMLInterchange.h"
38#include "HTMLLIElement.h"
39#include "HTMLNames.h"
40#include "HTMLOListElement.h"
41#include "HTMLObjectElement.h"
42#include "HTMLParagraphElement.h"
43#include "HTMLTextFormControlElement.h"
44#include "HTMLUListElement.h"
45#include "NodeTraversal.h"
46#include "PositionIterator.h"
47#include "Range.h"
48#include "RenderObject.h"
49#include "ShadowRoot.h"
50#include "Text.h"
51#include "TextIterator.h"
52#include "VisiblePosition.h"
53#include "VisibleSelection.h"
54#include "VisibleUnits.h"
55#include <wtf/Assertions.h>
56#include <wtf/StdLibExtras.h>
57#include <wtf/unicode/CharacterNames.h>
58
59using namespace std;
60
61namespace WebCore {
62
63using namespace HTMLNames;
64
65// Atomic means that the node has no children, or has children which are ignored for the
66// purposes of editing.
67bool isAtomicNode(const Node *node)
68{
69    return node && (!node->hasChildNodes() || editingIgnoresContent(node));
70}
71
72// Compare two positions, taking into account the possibility that one or both
73// could be inside a shadow tree. Only works for non-null values.
74int comparePositions(const Position& a, const Position& b)
75{
76    TreeScope* commonScope = commonTreeScope(a.containerNode(), b.containerNode());
77
78    ASSERT(commonScope);
79    if (!commonScope)
80        return 0;
81
82    Node* nodeA = commonScope->ancestorInThisScope(a.containerNode());
83    ASSERT(nodeA);
84    bool hasDescendentA = nodeA != a.containerNode();
85    int offsetA = hasDescendentA ? 0 : a.computeOffsetInContainerNode();
86
87    Node* nodeB = commonScope->ancestorInThisScope(b.containerNode());
88    ASSERT(nodeB);
89    bool hasDescendentB = nodeB != b.containerNode();
90    int offsetB = hasDescendentB ? 0 : b.computeOffsetInContainerNode();
91
92    int bias = 0;
93    if (nodeA == nodeB) {
94        if (hasDescendentA)
95            bias = -1;
96        else if (hasDescendentB)
97            bias = 1;
98    }
99
100    int result = Range::compareBoundaryPoints(nodeA, offsetA, nodeB, offsetB, IGNORE_EXCEPTION);
101    return result ? result : bias;
102}
103
104int comparePositions(const VisiblePosition& a, const VisiblePosition& b)
105{
106    return comparePositions(a.deepEquivalent(), b.deepEquivalent());
107}
108
109Node* highestEditableRoot(const Position& position, EditableType editableType)
110{
111    Node* node = position.deprecatedNode();
112    if (!node)
113        return 0;
114
115    Node* highestRoot = editableRootForPosition(position, editableType);
116    if (!highestRoot)
117        return 0;
118
119    node = highestRoot;
120    while (node) {
121        if (node->rendererIsEditable(editableType))
122            highestRoot = node;
123        if (node->hasTagName(bodyTag))
124            break;
125        node = node->parentNode();
126    }
127
128    return highestRoot;
129}
130
131Node* lowestEditableAncestor(Node* node)
132{
133    if (!node)
134        return 0;
135
136    Node* lowestRoot = 0;
137    while (node) {
138        if (node->rendererIsEditable())
139            return node->rootEditableElement();
140        if (node->hasTagName(bodyTag))
141            break;
142        node = node->parentNode();
143    }
144
145    return lowestRoot;
146}
147
148bool isEditablePosition(const Position& p, EditableType editableType, EUpdateStyle updateStyle)
149{
150    Node* node = p.deprecatedNode();
151    if (!node)
152        return false;
153    if (updateStyle == UpdateStyle)
154        node->document()->updateLayoutIgnorePendingStylesheets();
155    else
156        ASSERT(updateStyle == DoNotUpdateStyle);
157
158    if (node->renderer() && node->renderer()->isTable())
159        node = node->parentNode();
160
161    return node->rendererIsEditable(editableType);
162}
163
164bool isAtUnsplittableElement(const Position& pos)
165{
166    Node* node = pos.deprecatedNode();
167    return (node == editableRootForPosition(pos) || node == enclosingNodeOfType(pos, &isTableCell));
168}
169
170
171bool isRichlyEditablePosition(const Position& p, EditableType editableType)
172{
173    Node* node = p.deprecatedNode();
174    if (!node)
175        return false;
176
177    if (node->renderer() && node->renderer()->isTable())
178        node = node->parentNode();
179
180    return node->rendererIsRichlyEditable(editableType);
181}
182
183Element* editableRootForPosition(const Position& p, EditableType editableType)
184{
185    Node* node = p.containerNode();
186    if (!node)
187        return 0;
188
189    if (node->renderer() && node->renderer()->isTable())
190        node = node->parentNode();
191
192    return node->rootEditableElement(editableType);
193}
194
195// Finds the enclosing element until which the tree can be split.
196// When a user hits ENTER, he/she won't expect this element to be split into two.
197// You may pass it as the second argument of splitTreeToNode.
198Element* unsplittableElementForPosition(const Position& p)
199{
200    // Since enclosingNodeOfType won't search beyond the highest root editable node,
201    // this code works even if the closest table cell was outside of the root editable node.
202    Element* enclosingCell = toElement(enclosingNodeOfType(p, &isTableCell));
203    if (enclosingCell)
204        return enclosingCell;
205
206    return editableRootForPosition(p);
207}
208
209Position nextCandidate(const Position& position)
210{
211    PositionIterator p = position;
212    while (!p.atEnd()) {
213        p.increment();
214        if (p.isCandidate())
215            return p;
216    }
217    return Position();
218}
219
220Position nextVisuallyDistinctCandidate(const Position& position)
221{
222    Position p = position;
223    Position downstreamStart = p.downstream();
224    while (!p.atEndOfTree()) {
225        p = p.next(Character);
226        if (p.isCandidate() && p.downstream() != downstreamStart)
227            return p;
228    }
229    return Position();
230}
231
232Position previousCandidate(const Position& position)
233{
234    PositionIterator p = position;
235    while (!p.atStart()) {
236        p.decrement();
237        if (p.isCandidate())
238            return p;
239    }
240    return Position();
241}
242
243Position previousVisuallyDistinctCandidate(const Position& position)
244{
245    Position p = position;
246    Position downstreamStart = p.downstream();
247    while (!p.atStartOfTree()) {
248        p = p.previous(Character);
249        if (p.isCandidate() && p.downstream() != downstreamStart)
250            return p;
251    }
252    return Position();
253}
254
255VisiblePosition firstEditablePositionAfterPositionInRoot(const Position& position, Node* highestRoot)
256{
257    // position falls before highestRoot.
258    if (comparePositions(position, firstPositionInNode(highestRoot)) == -1 && highestRoot->rendererIsEditable())
259        return firstPositionInNode(highestRoot);
260
261    Position p = position;
262
263    if (position.deprecatedNode()->treeScope() != highestRoot->treeScope()) {
264        Node* shadowAncestor = highestRoot->treeScope()->ancestorInThisScope(p.deprecatedNode());
265        if (!shadowAncestor)
266            return VisiblePosition();
267
268        p = positionAfterNode(shadowAncestor);
269    }
270
271    while (p.deprecatedNode() && !isEditablePosition(p) && p.deprecatedNode()->isDescendantOf(highestRoot))
272        p = isAtomicNode(p.deprecatedNode()) ? positionInParentAfterNode(p.deprecatedNode()) : nextVisuallyDistinctCandidate(p);
273
274    if (p.deprecatedNode() && p.deprecatedNode() != highestRoot && !p.deprecatedNode()->isDescendantOf(highestRoot))
275        return VisiblePosition();
276
277    return VisiblePosition(p);
278}
279
280VisiblePosition lastEditablePositionBeforePositionInRoot(const Position& position, Node* highestRoot)
281{
282    // When position falls after highestRoot, the result is easy to compute.
283    if (comparePositions(position, lastPositionInNode(highestRoot)) == 1)
284        return lastPositionInNode(highestRoot);
285
286    Position p = position;
287
288    if (position.deprecatedNode()->treeScope() != highestRoot->treeScope()) {
289        Node* shadowAncestor = highestRoot->treeScope()->ancestorInThisScope(p.deprecatedNode());
290        if (!shadowAncestor)
291            return VisiblePosition();
292
293        p = firstPositionInOrBeforeNode(shadowAncestor);
294    }
295
296    while (p.deprecatedNode() && !isEditablePosition(p) && p.deprecatedNode()->isDescendantOf(highestRoot))
297        p = isAtomicNode(p.deprecatedNode()) ? positionInParentBeforeNode(p.deprecatedNode()) : previousVisuallyDistinctCandidate(p);
298
299    if (p.deprecatedNode() && p.deprecatedNode() != highestRoot && !p.deprecatedNode()->isDescendantOf(highestRoot))
300        return VisiblePosition();
301
302    return VisiblePosition(p);
303}
304
305// FIXME: The method name, comment, and code say three different things here!
306// Whether or not content before and after this node will collapse onto the same line as it.
307bool isBlock(const Node* node)
308{
309    return node && node->renderer() && !node->renderer()->isInline() && !node->renderer()->isRubyText();
310}
311
312bool isInline(const Node* node)
313{
314    return node && node->renderer() && node->renderer()->isInline();
315}
316
317// FIXME: Deploy this in all of the places where enclosingBlockFlow/enclosingBlockFlowOrTableElement are used.
318// FIXME: Pass a position to this function. The enclosing block of [table, x] for example, should be the
319// block that contains the table and not the table, and this function should be the only one responsible for
320// knowing about these kinds of special cases.
321Element* enclosingBlock(Node* node, EditingBoundaryCrossingRule rule)
322{
323    Node* enclosingNode = enclosingNodeOfType(firstPositionInOrBeforeNode(node), isBlock, rule);
324    return enclosingNode && enclosingNode->isElementNode() ? toElement(enclosingNode) : 0;
325}
326
327TextDirection directionOfEnclosingBlock(const Position& position)
328{
329    Node* enclosingBlockNode = enclosingBlock(position.containerNode());
330    if (!enclosingBlockNode)
331        return LTR;
332    RenderObject* renderer = enclosingBlockNode->renderer();
333    return renderer ? renderer->style()->direction() : LTR;
334}
335
336// This method is used to create positions in the DOM. It returns the maximum valid offset
337// in a node. It returns 1 for some elements even though they do not have children, which
338// creates technically invalid DOM Positions. Be sure to call parentAnchoredEquivalent
339// on a Position before using it to create a DOM Range, or an exception will be thrown.
340int lastOffsetForEditing(const Node* node)
341{
342    ASSERT(node);
343    if (!node)
344        return 0;
345    if (node->offsetInCharacters())
346        return node->maxCharacterOffset();
347
348    if (node->hasChildNodes())
349        return node->childNodeCount();
350
351    // NOTE: This should preempt the childNodeCount for, e.g., select nodes
352    if (editingIgnoresContent(node))
353        return 1;
354
355    return 0;
356}
357
358String stringWithRebalancedWhitespace(const String& string, bool startIsStartOfParagraph, bool endIsEndOfParagraph)
359{
360    Vector<UChar> rebalancedString;
361    append(rebalancedString, string);
362
363    bool previousCharacterWasSpace = false;
364    for (size_t i = 0; i < rebalancedString.size(); i++) {
365        if (!isWhitespace(rebalancedString[i])) {
366            previousCharacterWasSpace = false;
367            continue;
368        }
369
370        if (previousCharacterWasSpace || (!i && startIsStartOfParagraph) || (i + 1 == rebalancedString.size() && endIsEndOfParagraph)) {
371            rebalancedString[i] = noBreakSpace;
372            previousCharacterWasSpace = false;
373        } else {
374            rebalancedString[i] = ' ';
375            previousCharacterWasSpace = true;
376        }
377
378    }
379
380    return String::adopt(rebalancedString);
381}
382
383bool isTableStructureNode(const Node *node)
384{
385    RenderObject* renderer = node->renderer();
386    return (renderer && (renderer->isTableCell() || renderer->isTableRow() || renderer->isTableSection() || renderer->isRenderTableCol()));
387}
388
389const String& nonBreakingSpaceString()
390{
391    DEFINE_STATIC_LOCAL(String, nonBreakingSpaceString, (&noBreakSpace, 1));
392    return nonBreakingSpaceString;
393}
394
395// FIXME: need to dump this
396bool isSpecialElement(const Node *n)
397{
398    if (!n)
399        return false;
400
401    if (!n->isHTMLElement())
402        return false;
403
404    if (n->isLink())
405        return true;
406
407    RenderObject* renderer = n->renderer();
408    if (!renderer)
409        return false;
410
411    if (renderer->style()->display() == TABLE || renderer->style()->display() == INLINE_TABLE)
412        return true;
413
414    if (renderer->style()->isFloating())
415        return true;
416
417    if (renderer->style()->position() != StaticPosition)
418        return true;
419
420    return false;
421}
422
423static Node* firstInSpecialElement(const Position& pos)
424{
425    Node* rootEditableElement = pos.containerNode()->rootEditableElement();
426    for (Node* n = pos.deprecatedNode(); n && n->rootEditableElement() == rootEditableElement; n = n->parentNode())
427        if (isSpecialElement(n)) {
428            VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
429            VisiblePosition firstInElement = VisiblePosition(firstPositionInOrBeforeNode(n), DOWNSTREAM);
430            if (isTableElement(n) && vPos == firstInElement.next())
431                return n;
432            if (vPos == firstInElement)
433                return n;
434        }
435    return 0;
436}
437
438static Node* lastInSpecialElement(const Position& pos)
439{
440    Node* rootEditableElement = pos.containerNode()->rootEditableElement();
441    for (Node* n = pos.deprecatedNode(); n && n->rootEditableElement() == rootEditableElement; n = n->parentNode())
442        if (isSpecialElement(n)) {
443            VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
444            VisiblePosition lastInElement = VisiblePosition(lastPositionInOrAfterNode(n), DOWNSTREAM);
445            if (isTableElement(n) && vPos == lastInElement.previous())
446                return n;
447            if (vPos == lastInElement)
448                return n;
449        }
450    return 0;
451}
452
453bool isFirstVisiblePositionInSpecialElement(const Position& pos)
454{
455    return firstInSpecialElement(pos);
456}
457
458Position positionBeforeContainingSpecialElement(const Position& pos, Node** containingSpecialElement)
459{
460    Node* n = firstInSpecialElement(pos);
461    if (!n)
462        return pos;
463    Position result = positionInParentBeforeNode(n);
464    if (result.isNull() || result.deprecatedNode()->rootEditableElement() != pos.deprecatedNode()->rootEditableElement())
465        return pos;
466    if (containingSpecialElement)
467        *containingSpecialElement = n;
468    return result;
469}
470
471bool isLastVisiblePositionInSpecialElement(const Position& pos)
472{
473    return lastInSpecialElement(pos);
474}
475
476Position positionAfterContainingSpecialElement(const Position& pos, Node **containingSpecialElement)
477{
478    Node* n = lastInSpecialElement(pos);
479    if (!n)
480        return pos;
481    Position result = positionInParentAfterNode(n);
482    if (result.isNull() || result.deprecatedNode()->rootEditableElement() != pos.deprecatedNode()->rootEditableElement())
483        return pos;
484    if (containingSpecialElement)
485        *containingSpecialElement = n;
486    return result;
487}
488
489Position positionOutsideContainingSpecialElement(const Position &pos, Node **containingSpecialElement)
490{
491    if (isFirstVisiblePositionInSpecialElement(pos))
492        return positionBeforeContainingSpecialElement(pos, containingSpecialElement);
493    if (isLastVisiblePositionInSpecialElement(pos))
494        return positionAfterContainingSpecialElement(pos, containingSpecialElement);
495    return pos;
496}
497
498Node* isFirstPositionAfterTable(const VisiblePosition& visiblePosition)
499{
500    Position upstream(visiblePosition.deepEquivalent().upstream());
501    if (upstream.deprecatedNode() && upstream.deprecatedNode()->renderer() && upstream.deprecatedNode()->renderer()->isTable() && upstream.atLastEditingPositionForNode())
502        return upstream.deprecatedNode();
503
504    return 0;
505}
506
507Node* isLastPositionBeforeTable(const VisiblePosition& visiblePosition)
508{
509    Position downstream(visiblePosition.deepEquivalent().downstream());
510    if (downstream.deprecatedNode() && downstream.deprecatedNode()->renderer() && downstream.deprecatedNode()->renderer()->isTable() && downstream.atFirstEditingPositionForNode())
511        return downstream.deprecatedNode();
512
513    return 0;
514}
515
516// Returns the visible position at the beginning of a node
517VisiblePosition visiblePositionBeforeNode(Node* node)
518{
519    ASSERT(node);
520    if (node->childNodeCount())
521        return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
522    ASSERT(node->parentNode());
523    ASSERT(!node->parentNode()->isShadowRoot());
524    return positionInParentBeforeNode(node);
525}
526
527// Returns the visible position at the ending of a node
528VisiblePosition visiblePositionAfterNode(Node* node)
529{
530    ASSERT(node);
531    if (node->childNodeCount())
532        return VisiblePosition(lastPositionInOrAfterNode(node), DOWNSTREAM);
533    ASSERT(node->parentNode());
534    ASSERT(!node->parentNode()->isShadowRoot());
535    return positionInParentAfterNode(node);
536}
537
538// Create a range object with two visible positions, start and end.
539// create(PassRefPtr<Document>, const Position&, const Position&); will use deprecatedEditingOffset
540// Use this function instead of create a regular range object (avoiding editing offset).
541PassRefPtr<Range> createRange(PassRefPtr<Document> document, const VisiblePosition& start, const VisiblePosition& end, ExceptionCode& ec)
542{
543    ec = 0;
544    RefPtr<Range> selectedRange = Range::create(document);
545    selectedRange->setStart(start.deepEquivalent().containerNode(), start.deepEquivalent().computeOffsetInContainerNode(), ec);
546    if (!ec)
547        selectedRange->setEnd(end.deepEquivalent().containerNode(), end.deepEquivalent().computeOffsetInContainerNode(), ec);
548    return selectedRange.release();
549}
550
551// Extend rangeToExtend to include nodes that wraps range and visibly starts and ends inside or at the boudnaries of maximumRange
552// e.g. if the original range spaned "hello" in <div>hello</div>, then this function extends the range to contain div's around it.
553// Call this function before copying / moving paragraphs to contain all wrapping nodes.
554// This function stops extending the range immediately below rootNode; i.e. the extended range can contain a child node of rootNode
555// but it can never contain rootNode itself.
556PassRefPtr<Range> extendRangeToWrappingNodes(PassRefPtr<Range> range, const Range* maximumRange, const Node* rootNode)
557{
558    ASSERT(range);
559    ASSERT(maximumRange);
560
561    Node* ancestor = range->commonAncestorContainer(IGNORE_EXCEPTION); // Find the closest common ancestor.
562    Node* highestNode = 0;
563    // traverse through ancestors as long as they are contained within the range, content-editable, and below rootNode (could be =0).
564    while (ancestor && ancestor->rendererIsEditable() && isNodeVisiblyContainedWithin(ancestor, maximumRange) && ancestor != rootNode) {
565        highestNode = ancestor;
566        ancestor = ancestor->parentNode();
567    }
568
569    if (!highestNode)
570        return range;
571
572    // Create new range with the highest editable node contained within the range
573    RefPtr<Range> extendedRange = Range::create(range->ownerDocument());
574    extendedRange->selectNode(highestNode, IGNORE_EXCEPTION);
575    return extendedRange.release();
576}
577
578bool isListElement(Node *n)
579{
580    return (n && (n->hasTagName(ulTag) || n->hasTagName(olTag) || n->hasTagName(dlTag)));
581}
582
583bool isListItem(const Node *n)
584{
585    return n && n->renderer() && n->renderer()->isListItem();
586}
587
588Node* enclosingNodeWithTag(const Position& p, const QualifiedName& tagName)
589{
590    if (p.isNull())
591        return 0;
592
593    Node* root = highestEditableRoot(p);
594    for (Node* n = p.deprecatedNode(); n; n = n->parentNode()) {
595        if (root && !n->rendererIsEditable())
596            continue;
597        if (n->hasTagName(tagName))
598            return n;
599        if (n == root)
600            return 0;
601    }
602
603    return 0;
604}
605
606Node* enclosingNodeOfType(const Position& p, bool (*nodeIsOfType)(const Node*), EditingBoundaryCrossingRule rule)
607{
608    // FIXME: support CanSkipCrossEditingBoundary
609    ASSERT(rule == CanCrossEditingBoundary || rule == CannotCrossEditingBoundary);
610    if (p.isNull())
611        return 0;
612
613    Node* root = rule == CannotCrossEditingBoundary ? highestEditableRoot(p) : 0;
614    for (Node* n = p.deprecatedNode(); n; n = n->parentNode()) {
615        // Don't return a non-editable node if the input position was editable, since
616        // the callers from editing will no doubt want to perform editing inside the returned node.
617        if (root && !n->rendererIsEditable())
618            continue;
619        if (nodeIsOfType(n))
620            return n;
621        if (n == root)
622            return 0;
623    }
624
625    return 0;
626}
627
628Node* highestEnclosingNodeOfType(const Position& p, bool (*nodeIsOfType)(const Node*), EditingBoundaryCrossingRule rule, Node* stayWithin)
629{
630    Node* highest = 0;
631    Node* root = rule == CannotCrossEditingBoundary ? highestEditableRoot(p) : 0;
632    for (Node* n = p.containerNode(); n && n != stayWithin; n = n->parentNode()) {
633        if (root && !n->rendererIsEditable())
634            continue;
635        if (nodeIsOfType(n))
636            highest = n;
637        if (n == root)
638            break;
639    }
640
641    return highest;
642}
643
644static bool hasARenderedDescendant(Node* node, Node* excludedNode)
645{
646    for (Node* n = node->firstChild(); n;) {
647        if (n == excludedNode) {
648            n = NodeTraversal::nextSkippingChildren(n, node);
649            continue;
650        }
651        if (n->renderer())
652            return true;
653        n = NodeTraversal::next(n, node);
654    }
655    return false;
656}
657
658Node* highestNodeToRemoveInPruning(Node* node)
659{
660    Node* previousNode = 0;
661    Node* rootEditableElement = node ? node->rootEditableElement() : 0;
662    for (; node; node = node->parentNode()) {
663        if (RenderObject* renderer = node->renderer()) {
664            if (!renderer->canHaveChildren() || hasARenderedDescendant(node, previousNode) || rootEditableElement == node)
665                return previousNode;
666        }
667        previousNode = node;
668    }
669    return 0;
670}
671
672Node* enclosingTableCell(const Position& p)
673{
674    return toElement(enclosingNodeOfType(p, isTableCell));
675}
676
677Element* enclosingAnchorElement(const Position& p)
678{
679    if (p.isNull())
680        return 0;
681
682    for (Node* node = p.deprecatedNode(); node; node = node->parentNode()) {
683        if (node->isElementNode() && node->isLink())
684            return toElement(node);
685    }
686    return 0;
687}
688
689HTMLElement* enclosingList(Node* node)
690{
691    if (!node)
692        return 0;
693
694    Node* root = highestEditableRoot(firstPositionInOrBeforeNode(node));
695
696    for (ContainerNode* n = node->parentNode(); n; n = n->parentNode()) {
697        if (n->hasTagName(ulTag) || n->hasTagName(olTag))
698            return toHTMLElement(n);
699        if (n == root)
700            return 0;
701    }
702
703    return 0;
704}
705
706Node* enclosingListChild(Node *node)
707{
708    if (!node)
709        return 0;
710    // Check for a list item element, or for a node whose parent is a list element. Such a node
711    // will appear visually as a list item (but without a list marker)
712    Node* root = highestEditableRoot(firstPositionInOrBeforeNode(node));
713
714    // FIXME: This function is inappropriately named if it starts with node instead of node->parentNode()
715    for (Node* n = node; n && n->parentNode(); n = n->parentNode()) {
716        if (n->hasTagName(liTag) || (isListElement(n->parentNode()) && n != root))
717            return n;
718        if (n == root || isTableCell(n))
719            return 0;
720    }
721
722    return 0;
723}
724
725static HTMLElement* embeddedSublist(Node* listItem)
726{
727    // Check the DOM so that we'll find collapsed sublists without renderers.
728    for (Node* n = listItem->firstChild(); n; n = n->nextSibling()) {
729        if (isListElement(n))
730            return toHTMLElement(n);
731    }
732
733    return 0;
734}
735
736static Node* appendedSublist(Node* listItem)
737{
738    // Check the DOM so that we'll find collapsed sublists without renderers.
739    for (Node* n = listItem->nextSibling(); n; n = n->nextSibling()) {
740        if (isListElement(n))
741            return toHTMLElement(n);
742        if (isListItem(listItem))
743            return 0;
744    }
745
746    return 0;
747}
748
749// FIXME: This method should not need to call isStartOfParagraph/isEndOfParagraph
750Node* enclosingEmptyListItem(const VisiblePosition& visiblePos)
751{
752    // Check that position is on a line by itself inside a list item
753    Node* listChildNode = enclosingListChild(visiblePos.deepEquivalent().deprecatedNode());
754    if (!listChildNode || !isStartOfParagraph(visiblePos) || !isEndOfParagraph(visiblePos))
755        return 0;
756
757    VisiblePosition firstInListChild(firstPositionInOrBeforeNode(listChildNode));
758    VisiblePosition lastInListChild(lastPositionInOrAfterNode(listChildNode));
759
760    if (firstInListChild != visiblePos || lastInListChild != visiblePos)
761        return 0;
762
763    if (embeddedSublist(listChildNode) || appendedSublist(listChildNode))
764        return 0;
765
766    return listChildNode;
767}
768
769HTMLElement* outermostEnclosingList(Node* node, Node* rootList)
770{
771    HTMLElement* list = enclosingList(node);
772    if (!list)
773        return 0;
774
775    while (HTMLElement* nextList = enclosingList(list)) {
776        if (nextList == rootList)
777            break;
778        list = nextList;
779    }
780
781    return list;
782}
783
784bool canMergeLists(Element* firstList, Element* secondList)
785{
786    if (!firstList || !secondList || !firstList->isHTMLElement() || !secondList->isHTMLElement())
787        return false;
788
789    return firstList->hasTagName(secondList->tagQName()) // make sure the list types match (ol vs. ul)
790    && firstList->rendererIsEditable() && secondList->rendererIsEditable() // both lists are editable
791    && firstList->rootEditableElement() == secondList->rootEditableElement() // don't cross editing boundaries
792    && isVisiblyAdjacent(positionInParentAfterNode(firstList), positionInParentBeforeNode(secondList));
793    // Make sure there is no visible content between this li and the previous list
794}
795
796Node* highestAncestor(Node* node)
797{
798    ASSERT(node);
799    Node* parent = node;
800    while ((node = node->parentNode()))
801        parent = node;
802    return parent;
803}
804
805static Node* previousNodeConsideringAtomicNodes(const Node* node)
806{
807    if (node->previousSibling()) {
808        Node* n = node->previousSibling();
809        while (!isAtomicNode(n) && n->lastChild())
810            n = n->lastChild();
811        return n;
812    }
813    if (node->parentNode())
814        return node->parentNode();
815    return 0;
816}
817
818static Node* nextNodeConsideringAtomicNodes(const Node* node)
819{
820    if (!isAtomicNode(node) && node->firstChild())
821        return node->firstChild();
822    if (node->nextSibling())
823        return node->nextSibling();
824    const Node* n = node;
825    while (n && !n->nextSibling())
826        n = n->parentNode();
827    if (n)
828        return n->nextSibling();
829    return 0;
830}
831
832Node* previousLeafNode(const Node* node)
833{
834    Node* n = previousNodeConsideringAtomicNodes(node);
835    while (n) {
836        if (isAtomicNode(n))
837            return n;
838        n = previousNodeConsideringAtomicNodes(n);
839    }
840    return 0;
841}
842
843Node* nextLeafNode(const Node* node)
844{
845    Node* n = nextNodeConsideringAtomicNodes(node);
846    while (n) {
847        if (isAtomicNode(n))
848            return n;
849        n = nextNodeConsideringAtomicNodes(n);
850    }
851    return 0;
852}
853
854// FIXME: do not require renderer, so that this can be used within fragments, or rename to isRenderedTable()
855bool isTableElement(Node* n)
856{
857    if (!n || !n->isElementNode())
858        return false;
859
860    RenderObject* renderer = n->renderer();
861    return (renderer && (renderer->style()->display() == TABLE || renderer->style()->display() == INLINE_TABLE));
862}
863
864bool isTableCell(const Node* node)
865{
866    RenderObject* r = node->renderer();
867    if (!r)
868        return node->hasTagName(tdTag) || node->hasTagName(thTag);
869
870    return r->isTableCell();
871}
872
873bool isEmptyTableCell(const Node* node)
874{
875    // Returns true IFF the passed in node is one of:
876    //   .) a table cell with no children,
877    //   .) a table cell with a single BR child, and which has no other child renderers, including :before and :after renderers
878    //   .) the BR child of such a table cell
879
880    // Find rendered node
881    while (node && !node->renderer())
882        node = node->parentNode();
883    if (!node)
884        return false;
885
886    // Make sure the rendered node is a table cell or <br>.
887    // If it's a <br>, then the parent node has to be a table cell.
888    RenderObject* renderer = node->renderer();
889    if (renderer->isBR()) {
890        renderer = renderer->parent();
891        if (!renderer)
892            return false;
893    }
894    if (!renderer->isTableCell())
895        return false;
896
897    // Check that the table cell contains no child renderers except for perhaps a single <br>.
898    RenderObject* childRenderer = renderer->firstChild();
899    if (!childRenderer)
900        return true;
901    if (!childRenderer->isBR())
902        return false;
903    return !childRenderer->nextSibling();
904}
905
906PassRefPtr<HTMLElement> createDefaultParagraphElement(Document* document)
907{
908    switch (document->frame()->editor().defaultParagraphSeparator()) {
909    case EditorParagraphSeparatorIsDiv:
910        return HTMLDivElement::create(document);
911    case EditorParagraphSeparatorIsP:
912        return HTMLParagraphElement::create(document);
913    }
914
915    ASSERT_NOT_REACHED();
916    return 0;
917}
918
919PassRefPtr<HTMLElement> createBreakElement(Document* document)
920{
921    return HTMLBRElement::create(document);
922}
923
924PassRefPtr<HTMLElement> createOrderedListElement(Document* document)
925{
926    return HTMLOListElement::create(document);
927}
928
929PassRefPtr<HTMLElement> createUnorderedListElement(Document* document)
930{
931    return HTMLUListElement::create(document);
932}
933
934PassRefPtr<HTMLElement> createListItemElement(Document* document)
935{
936    return HTMLLIElement::create(document);
937}
938
939PassRefPtr<HTMLElement> createHTMLElement(Document* document, const QualifiedName& name)
940{
941    return HTMLElementFactory::createHTMLElement(name, document, 0, false);
942}
943
944PassRefPtr<HTMLElement> createHTMLElement(Document* document, const AtomicString& tagName)
945{
946    return createHTMLElement(document, QualifiedName(nullAtom, tagName, xhtmlNamespaceURI));
947}
948
949bool isTabSpanNode(const Node *node)
950{
951    return node && node->hasTagName(spanTag) && node->isElementNode() && static_cast<const Element *>(node)->getAttribute(classAttr) == AppleTabSpanClass;
952}
953
954bool isTabSpanTextNode(const Node *node)
955{
956    return node && node->isTextNode() && node->parentNode() && isTabSpanNode(node->parentNode());
957}
958
959Node* tabSpanNode(const Node *node)
960{
961    return isTabSpanTextNode(node) ? node->parentNode() : 0;
962}
963
964Position positionOutsideTabSpan(const Position& pos)
965{
966    Node* node = pos.containerNode();
967    if (isTabSpanTextNode(node))
968        node = tabSpanNode(node);
969    else if (!isTabSpanNode(node))
970        return pos;
971
972    if (node && VisiblePosition(pos) == lastPositionInNode(node))
973        return positionInParentAfterNode(node);
974
975    return positionInParentBeforeNode(node);
976}
977
978PassRefPtr<Element> createTabSpanElement(Document* document, PassRefPtr<Node> prpTabTextNode)
979{
980    RefPtr<Node> tabTextNode = prpTabTextNode;
981
982    // Make the span to hold the tab.
983    RefPtr<Element> spanElement = document->createElement(spanTag, false);
984    spanElement->setAttribute(classAttr, AppleTabSpanClass);
985    spanElement->setAttribute(styleAttr, "white-space:pre");
986
987    // Add tab text to that span.
988    if (!tabTextNode)
989        tabTextNode = document->createEditingTextNode("\t");
990
991    spanElement->appendChild(tabTextNode.release(), ASSERT_NO_EXCEPTION);
992
993    return spanElement.release();
994}
995
996PassRefPtr<Element> createTabSpanElement(Document* document, const String& tabText)
997{
998    return createTabSpanElement(document, document->createTextNode(tabText));
999}
1000
1001PassRefPtr<Element> createTabSpanElement(Document* document)
1002{
1003    return createTabSpanElement(document, PassRefPtr<Node>());
1004}
1005
1006bool isNodeRendered(const Node *node)
1007{
1008    if (!node)
1009        return false;
1010
1011    RenderObject* renderer = node->renderer();
1012    if (!renderer)
1013        return false;
1014
1015    return renderer->style()->visibility() == VISIBLE;
1016}
1017
1018unsigned numEnclosingMailBlockquotes(const Position& p)
1019{
1020    unsigned num = 0;
1021    for (Node* n = p.deprecatedNode(); n; n = n->parentNode())
1022        if (isMailBlockquote(n))
1023            num++;
1024
1025    return num;
1026}
1027
1028void updatePositionForNodeRemoval(Position& position, Node* node)
1029{
1030    if (position.isNull())
1031        return;
1032    switch (position.anchorType()) {
1033    case Position::PositionIsBeforeChildren:
1034        if (position.containerNode() == node)
1035            position = positionInParentBeforeNode(node);
1036        break;
1037    case Position::PositionIsAfterChildren:
1038        if (position.containerNode() == node)
1039            position = positionInParentAfterNode(node);
1040        break;
1041    case Position::PositionIsOffsetInAnchor:
1042        if (position.containerNode() == node->parentNode() && static_cast<unsigned>(position.offsetInContainerNode()) > node->nodeIndex())
1043            position.moveToOffset(position.offsetInContainerNode() - 1);
1044        else if (node->containsIncludingShadowDOM(position.containerNode()))
1045            position = positionInParentBeforeNode(node);
1046        break;
1047    case Position::PositionIsAfterAnchor:
1048        if (node->containsIncludingShadowDOM(position.anchorNode()))
1049            position = positionInParentAfterNode(node);
1050        break;
1051    case Position::PositionIsBeforeAnchor:
1052        if (node->containsIncludingShadowDOM(position.anchorNode()))
1053            position = positionInParentBeforeNode(node);
1054        break;
1055    }
1056}
1057
1058bool isMailBlockquote(const Node *node)
1059{
1060    if (!node || !node->hasTagName(blockquoteTag))
1061        return false;
1062
1063    return static_cast<const Element *>(node)->getAttribute("type") == "cite";
1064}
1065
1066int caretMinOffset(const Node* n)
1067{
1068    RenderObject* r = n->renderer();
1069    ASSERT(!n->isCharacterDataNode() || !r || r->isText()); // FIXME: This was a runtime check that seemingly couldn't fail; changed it to an assertion for now.
1070    return r ? r->caretMinOffset() : 0;
1071}
1072
1073// If a node can contain candidates for VisiblePositions, return the offset of the last candidate, otherwise
1074// return the number of children for container nodes and the length for unrendered text nodes.
1075int caretMaxOffset(const Node* n)
1076{
1077    // For rendered text nodes, return the last position that a caret could occupy.
1078    if (n->isTextNode() && n->renderer())
1079        return n->renderer()->caretMaxOffset();
1080    // For containers return the number of children. For others do the same as above.
1081    return lastOffsetForEditing(n);
1082}
1083
1084bool lineBreakExistsAtVisiblePosition(const VisiblePosition& visiblePosition)
1085{
1086    return lineBreakExistsAtPosition(visiblePosition.deepEquivalent().downstream());
1087}
1088
1089bool lineBreakExistsAtPosition(const Position& position)
1090{
1091    if (position.isNull())
1092        return false;
1093
1094    if (position.anchorNode()->hasTagName(brTag) && position.atFirstEditingPositionForNode())
1095        return true;
1096
1097    if (!position.anchorNode()->renderer())
1098        return false;
1099
1100    if (!position.anchorNode()->isTextNode() || !position.anchorNode()->renderer()->style()->preserveNewline())
1101        return false;
1102
1103    Text* textNode = toText(position.anchorNode());
1104    unsigned offset = position.offsetInContainerNode();
1105    return offset < textNode->length() && textNode->data()[offset] == '\n';
1106}
1107
1108// Modifies selections that have an end point at the edge of a table
1109// that contains the other endpoint so that they don't confuse
1110// code that iterates over selected paragraphs.
1111VisibleSelection selectionForParagraphIteration(const VisibleSelection& original)
1112{
1113    VisibleSelection newSelection(original);
1114    VisiblePosition startOfSelection(newSelection.visibleStart());
1115    VisiblePosition endOfSelection(newSelection.visibleEnd());
1116
1117    // If the end of the selection to modify is just after a table, and
1118    // if the start of the selection is inside that table, then the last paragraph
1119    // that we'll want modify is the last one inside the table, not the table itself
1120    // (a table is itself a paragraph).
1121    if (Node* table = isFirstPositionAfterTable(endOfSelection))
1122        if (startOfSelection.deepEquivalent().deprecatedNode()->isDescendantOf(table))
1123            newSelection = VisibleSelection(startOfSelection, endOfSelection.previous(CannotCrossEditingBoundary));
1124
1125    // If the start of the selection to modify is just before a table,
1126    // and if the end of the selection is inside that table, then the first paragraph
1127    // we'll want to modify is the first one inside the table, not the paragraph
1128    // containing the table itself.
1129    if (Node* table = isLastPositionBeforeTable(startOfSelection))
1130        if (endOfSelection.deepEquivalent().deprecatedNode()->isDescendantOf(table))
1131            newSelection = VisibleSelection(startOfSelection.next(CannotCrossEditingBoundary), endOfSelection);
1132
1133    return newSelection;
1134}
1135
1136// FIXME: indexForVisiblePosition and visiblePositionForIndex use TextIterators to convert between
1137// VisiblePositions and indices. But TextIterator iteration using TextIteratorEmitsCharactersBetweenAllVisiblePositions
1138// does not exactly match VisiblePosition iteration, so using them to preserve a selection during an editing
1139// opertion is unreliable. TextIterator's TextIteratorEmitsCharactersBetweenAllVisiblePositions mode needs to be fixed,
1140// or these functions need to be changed to iterate using actual VisiblePositions.
1141// FIXME: Deploy these functions everywhere that TextIterators are used to convert between VisiblePositions and indices.
1142int indexForVisiblePosition(const VisiblePosition& visiblePosition, RefPtr<ContainerNode>& scope)
1143{
1144    if (visiblePosition.isNull())
1145        return 0;
1146
1147    Position p(visiblePosition.deepEquivalent());
1148    Document* document = p.anchorNode()->document();
1149    ShadowRoot* shadowRoot = p.anchorNode()->containingShadowRoot();
1150
1151    if (shadowRoot)
1152        scope = shadowRoot;
1153    else
1154        scope = document->documentElement();
1155
1156    RefPtr<Range> range = Range::create(document, firstPositionInNode(scope.get()), p.parentAnchoredEquivalent());
1157
1158    return TextIterator::rangeLength(range.get(), true);
1159}
1160
1161VisiblePosition visiblePositionForIndex(int index, ContainerNode* scope)
1162{
1163    RefPtr<Range> range = TextIterator::rangeFromLocationAndLength(scope, index, 0, true);
1164    // Check for an invalid index. Certain editing operations invalidate indices because
1165    // of problems with TextIteratorEmitsCharactersBetweenAllVisiblePositions.
1166    if (!range)
1167        return VisiblePosition();
1168    return VisiblePosition(range->startPosition());
1169}
1170
1171// Determines whether two positions are visibly next to each other (first then second)
1172// while ignoring whitespaces and unrendered nodes
1173bool isVisiblyAdjacent(const Position& first, const Position& second)
1174{
1175    return VisiblePosition(first) == VisiblePosition(second.upstream());
1176}
1177
1178// Determines whether a node is inside a range or visibly starts and ends at the boundaries of the range.
1179// Call this function to determine whether a node is visibly fit inside selectedRange
1180bool isNodeVisiblyContainedWithin(Node* node, const Range* selectedRange)
1181{
1182    ASSERT(node);
1183    ASSERT(selectedRange);
1184    // If the node is inside the range, then it surely is contained within
1185    if (selectedRange->compareNode(node, IGNORE_EXCEPTION) == Range::NODE_INSIDE)
1186        return true;
1187
1188    bool startIsVisuallySame = visiblePositionBeforeNode(node) == selectedRange->startPosition();
1189    if (startIsVisuallySame && comparePositions(positionInParentAfterNode(node), selectedRange->endPosition()) < 0)
1190        return true;
1191
1192    bool endIsVisuallySame = visiblePositionAfterNode(node) == selectedRange->endPosition();
1193    if (endIsVisuallySame && comparePositions(selectedRange->startPosition(), positionInParentBeforeNode(node)) < 0)
1194        return true;
1195
1196    return startIsVisuallySame && endIsVisuallySame;
1197}
1198
1199bool isRenderedAsNonInlineTableImageOrHR(const Node* node)
1200{
1201    if (!node)
1202        return false;
1203    RenderObject* renderer = node->renderer();
1204    return renderer && ((renderer->isTable() && !renderer->isInline()) || (renderer->isImage() && !renderer->isInline()) || renderer->isHR());
1205}
1206
1207bool areIdenticalElements(const Node* first, const Node* second)
1208{
1209    if (!first->isElementNode() || !second->isElementNode())
1210        return false;
1211
1212    const Element* firstElement = toElement(first);
1213    const Element* secondElement = toElement(second);
1214    if (!firstElement->hasTagName(secondElement->tagQName()))
1215        return false;
1216
1217    return firstElement->hasEquivalentAttributes(secondElement);
1218}
1219
1220bool isNonTableCellHTMLBlockElement(const Node* node)
1221{
1222    return node->hasTagName(listingTag)
1223        || node->hasTagName(olTag)
1224        || node->hasTagName(preTag)
1225        || node->hasTagName(tableTag)
1226        || node->hasTagName(ulTag)
1227        || node->hasTagName(xmpTag)
1228        || node->hasTagName(h1Tag)
1229        || node->hasTagName(h2Tag)
1230        || node->hasTagName(h3Tag)
1231        || node->hasTagName(h4Tag)
1232        || node->hasTagName(h5Tag);
1233}
1234
1235Position adjustedSelectionStartForStyleComputation(const VisibleSelection& selection)
1236{
1237    // This function is used by range style computations to avoid bugs like:
1238    // <rdar://problem/4017641> REGRESSION (Mail): you can only bold/unbold a selection starting from end of line once
1239    // It is important to skip certain irrelevant content at the start of the selection, so we do not wind up
1240    // with a spurious "mixed" style.
1241
1242    VisiblePosition visiblePosition = selection.start();
1243    if (visiblePosition.isNull())
1244        return Position();
1245
1246    // if the selection is a caret, just return the position, since the style
1247    // behind us is relevant
1248    if (selection.isCaret())
1249        return visiblePosition.deepEquivalent();
1250
1251    // if the selection starts just before a paragraph break, skip over it
1252    if (isEndOfParagraph(visiblePosition))
1253        return visiblePosition.next().deepEquivalent().downstream();
1254
1255    // otherwise, make sure to be at the start of the first selected node,
1256    // instead of possibly at the end of the last node before the selection
1257    return visiblePosition.deepEquivalent().downstream();
1258}
1259
1260// FIXME: Should this be deprecated like deprecatedEnclosingBlockFlowElement is?
1261bool isBlockFlowElement(const Node* node)
1262{
1263    if (!node->isElementNode())
1264        return false;
1265    RenderObject* renderer = node->renderer();
1266    return renderer && renderer->isBlockFlow();
1267}
1268
1269Element* deprecatedEnclosingBlockFlowElement(Node* node)
1270{
1271    if (!node)
1272        return 0;
1273    if (isBlockFlowElement(node))
1274        return toElement(node);
1275    while ((node = node->parentNode())) {
1276        if (isBlockFlowElement(node) || node->hasTagName(bodyTag))
1277            return toElement(node);
1278    }
1279    return 0;
1280}
1281
1282} // namespace WebCore
1283