Use NeverDestroyed instead of DEPRECATED_DEFINE_STATIC_LOCAL
[WebKit-https.git] / Source / WebCore / editing / htmlediting.cpp
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 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 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 "HTMLTableElement.h"
44 #include "HTMLTextFormControlElement.h"
45 #include "HTMLUListElement.h"
46 #include "NodeTraversal.h"
47 #include "PositionIterator.h"
48 #include "RenderBlock.h"
49 #include "RenderElement.h"
50 #include "RenderTableCell.h"
51 #include "ShadowRoot.h"
52 #include "Text.h"
53 #include "TextIterator.h"
54 #include "VisibleUnits.h"
55 #include <wtf/Assertions.h>
56 #include <wtf/StdLibExtras.h>
57 #include <wtf/unicode/CharacterNames.h>
58
59 namespace WebCore {
60
61 using namespace HTMLNames;
62
63 // Atomic means that the node has no children, or has children which are ignored for the
64 // purposes of editing.
65 bool isAtomicNode(const Node *node)
66 {
67     return node && (!node->hasChildNodes() || editingIgnoresContent(node));
68 }
69
70 // Compare two positions, taking into account the possibility that one or both
71 // could be inside a shadow tree. Only works for non-null values.
72 int comparePositions(const Position& a, const Position& b)
73 {
74     TreeScope* commonScope = commonTreeScope(a.containerNode(), b.containerNode());
75
76     if (!commonScope)
77         return 0;
78
79     Node* nodeA = commonScope->ancestorInThisScope(a.containerNode());
80     ASSERT(nodeA);
81     bool hasDescendentA = nodeA != a.containerNode();
82     int offsetA = hasDescendentA ? 0 : a.computeOffsetInContainerNode();
83
84     Node* nodeB = commonScope->ancestorInThisScope(b.containerNode());
85     ASSERT(nodeB);
86     bool hasDescendentB = nodeB != b.containerNode();
87     int offsetB = hasDescendentB ? 0 : b.computeOffsetInContainerNode();
88
89     int bias = 0;
90     if (nodeA == nodeB) {
91         if (hasDescendentA)
92             bias = -1;
93         else if (hasDescendentB)
94             bias = 1;
95     }
96
97     int result = Range::compareBoundaryPoints(nodeA, offsetA, nodeB, offsetB, IGNORE_EXCEPTION);
98     return result ? result : bias;
99 }
100
101 int comparePositions(const VisiblePosition& a, const VisiblePosition& b)
102 {
103     return comparePositions(a.deepEquivalent(), b.deepEquivalent());
104 }
105
106 Node* highestEditableRoot(const Position& position, EditableType editableType)
107 {
108     Node* node = position.deprecatedNode();
109     if (!node)
110         return 0;
111
112     Node* highestEditableRoot = editableRootForPosition(position, editableType);
113     if (!highestEditableRoot)
114         return 0;
115
116     node = highestEditableRoot;
117     while (!node->hasTagName(bodyTag)) {
118         node = node->parentNode();
119         if (!node)
120             break;
121         if (hasEditableStyle(*node, editableType))
122             highestEditableRoot = node;
123     }
124
125     return highestEditableRoot;
126 }
127
128 Node* lowestEditableAncestor(Node* node)
129 {
130     if (!node)
131         return 0;
132     
133     while (node) {
134         if (node->hasEditableStyle())
135             return node->rootEditableElement();
136         if (node->hasTagName(bodyTag))
137             break;
138         node = node->parentNode();
139     }
140     
141     return 0;
142 }
143
144 static bool isEditableToAccessibility(const Node& node)
145 {
146     ASSERT(AXObjectCache::accessibilityEnabled());
147     ASSERT(node.document().existingAXObjectCache());
148
149     if (AXObjectCache* cache = node.document().existingAXObjectCache())
150         return cache->rootAXEditableElement(&node);
151
152     return false;
153 }
154
155 static bool computeEditability(const Node& node, EditableType editableType, Node::ShouldUpdateStyle shouldUpdateStyle)
156 {
157     if (node.computeEditability(Node::UserSelectAllIsAlwaysNonEditable, shouldUpdateStyle) != Node::Editability::ReadOnly)
158         return true;
159
160     switch (editableType) {
161     case ContentIsEditable:
162         return false;
163     case HasEditableAXRole:
164         return isEditableToAccessibility(node);
165     }
166     ASSERT_NOT_REACHED();
167     return false;
168 }
169
170 bool hasEditableStyle(const Node& node, EditableType editableType)
171 {
172     return computeEditability(node, editableType, Node::ShouldUpdateStyle::DoNotUpdate);
173 }
174
175 bool isEditableNode(const Node& node)
176 {
177     return computeEditability(node, ContentIsEditable, Node::ShouldUpdateStyle::Update);
178 }
179
180 bool isEditablePosition(const Position& position, EditableType editableType)
181 {
182     Node* node = position.containerNode();
183     return node && computeEditability(*node, editableType, Node::ShouldUpdateStyle::Update);
184 }
185
186 bool isAtUnsplittableElement(const Position& pos)
187 {
188     Node* node = pos.containerNode();
189     return (node == editableRootForPosition(pos) || node == enclosingNodeOfType(pos, &isTableCell));
190 }
191     
192     
193 bool isRichlyEditablePosition(const Position& position)
194 {
195     Node* node = position.containerNode();
196     if (!node)
197         return false;
198     return node->hasRichlyEditableStyle();
199 }
200
201 Element* editableRootForPosition(const Position& p, EditableType editableType)
202 {
203     Node* node = p.containerNode();
204     if (!node)
205         return 0;
206
207     switch (editableType) {
208     case HasEditableAXRole:
209         if (AXObjectCache* cache = node->document().existingAXObjectCache())
210             return const_cast<Element*>(cache->rootAXEditableElement(node));
211         FALLTHROUGH;
212     case ContentIsEditable:
213         return node->rootEditableElement();
214     }
215     return 0;
216 }
217
218 // Finds the enclosing element until which the tree can be split.
219 // When a user hits ENTER, he/she won't expect this element to be split into two.
220 // You may pass it as the second argument of splitTreeToNode.
221 Element* unsplittableElementForPosition(const Position& p)
222 {
223     // Since enclosingNodeOfType won't search beyond the highest root editable node,
224     // this code works even if the closest table cell was outside of the root editable node.
225     Element* enclosingCell = downcast<Element>(enclosingNodeOfType(p, &isTableCell));
226     if (enclosingCell)
227         return enclosingCell;
228
229     return editableRootForPosition(p);
230 }
231
232 Position nextCandidate(const Position& position)
233 {
234     PositionIterator p = position;
235     while (!p.atEnd()) {
236         p.increment();
237         if (p.isCandidate())
238             return p;
239     }
240     return Position();
241 }
242
243 Position nextVisuallyDistinctCandidate(const Position& position)
244 {
245     // FIXME: Use PositionIterator instead.
246     Position p = position;
247     Position downstreamStart = p.downstream();
248     while (!p.atEndOfTree()) {
249         p = p.next(Character);
250         if (p.isCandidate() && p.downstream() != downstreamStart)
251             return p;
252         if (auto* node = p.containerNode()) {
253             if (!node->renderer())
254                 p = lastPositionInOrAfterNode(node);
255         }
256     }
257     return Position();
258 }
259
260 Position previousCandidate(const Position& position)
261 {
262     PositionIterator p = position;
263     while (!p.atStart()) {
264         p.decrement();
265         if (p.isCandidate())
266             return p;
267     }
268     return Position();
269 }
270
271 Position previousVisuallyDistinctCandidate(const Position& position)
272 {
273     // FIXME: Use PositionIterator instead.
274     Position p = position;
275     Position downstreamStart = p.downstream();
276     while (!p.atStartOfTree()) {
277         p = p.previous(Character);
278         if (p.isCandidate() && p.downstream() != downstreamStart)
279             return p;
280         if (auto* node = p.containerNode()) {
281             if (!node->renderer())
282                 p = firstPositionInOrBeforeNode(node);
283         }
284     }
285     return Position();
286 }
287
288 Position firstEditablePositionAfterPositionInRoot(const Position& position, Node* highestRoot)
289 {
290     if (!highestRoot)
291         return Position();
292
293     // position falls before highestRoot.
294     if (comparePositions(position, firstPositionInNode(highestRoot)) == -1 && highestRoot->hasEditableStyle())
295         return firstPositionInNode(highestRoot);
296
297     Position p = position;
298
299     if (&position.deprecatedNode()->treeScope() != &highestRoot->treeScope()) {
300         Node* shadowAncestor = highestRoot->treeScope().ancestorInThisScope(p.deprecatedNode());
301         if (!shadowAncestor)
302             return Position();
303
304         p = positionAfterNode(shadowAncestor);
305     }
306
307     while (p.deprecatedNode() && !isEditablePosition(p) && p.deprecatedNode()->isDescendantOf(highestRoot))
308         p = isAtomicNode(p.deprecatedNode()) ? positionInParentAfterNode(p.deprecatedNode()) : nextVisuallyDistinctCandidate(p);
309     
310     if (p.deprecatedNode() && p.deprecatedNode() != highestRoot && !p.deprecatedNode()->isDescendantOf(highestRoot))
311         return Position();
312     
313     return p;
314 }
315
316 Position lastEditablePositionBeforePositionInRoot(const Position& position, Node* highestRoot)
317 {
318     if (!highestRoot)
319         return Position();
320
321     // When position falls after highestRoot, the result is easy to compute.
322     if (comparePositions(position, lastPositionInNode(highestRoot)) == 1)
323         return lastPositionInNode(highestRoot);
324
325     Position p = position;
326
327     if (&position.deprecatedNode()->treeScope() != &highestRoot->treeScope()) {
328         Node* shadowAncestor = highestRoot->treeScope().ancestorInThisScope(p.deprecatedNode());
329         if (!shadowAncestor)
330             return Position();
331
332         p = firstPositionInOrBeforeNode(shadowAncestor);
333     }
334     
335     while (p.deprecatedNode() && !isEditablePosition(p) && p.deprecatedNode()->isDescendantOf(highestRoot))
336         p = isAtomicNode(p.deprecatedNode()) ? positionInParentBeforeNode(p.deprecatedNode()) : previousVisuallyDistinctCandidate(p);
337     
338     if (p.deprecatedNode() && p.deprecatedNode() != highestRoot && !p.deprecatedNode()->isDescendantOf(highestRoot))
339         return Position();
340     
341     return p;
342 }
343
344 // FIXME: The method name, comment, and code say three different things here!
345 // Whether or not content before and after this node will collapse onto the same line as it.
346 bool isBlock(const Node* node)
347 {
348     return node && node->renderer() && !node->renderer()->isInline() && !node->renderer()->isRubyText();
349 }
350
351 bool isInline(const Node* node)
352 {
353     return node && node->renderer() && node->renderer()->isInline();
354 }
355
356 // FIXME: Deploy this in all of the places where enclosingBlockFlow/enclosingBlockFlowOrTableElement are used.
357 // FIXME: Pass a position to this function. The enclosing block of [table, x] for example, should be the 
358 // block that contains the table and not the table, and this function should be the only one responsible for 
359 // knowing about these kinds of special cases.
360 Element* enclosingBlock(Node* node, EditingBoundaryCrossingRule rule)
361 {
362     Node* enclosingNode = enclosingNodeOfType(firstPositionInOrBeforeNode(node), isBlock, rule);
363     return is<Element>(enclosingNode) ? downcast<Element>(enclosingNode) : nullptr;
364 }
365
366 TextDirection directionOfEnclosingBlock(const Position& position)
367 {
368     auto block = enclosingBlock(position.containerNode());
369     if (!block)
370         return LTR;
371     auto renderer = block->renderer();
372     if (!renderer)
373         return LTR;
374     return renderer->style().direction();
375 }
376
377 // This method is used to create positions in the DOM. It returns the maximum valid offset
378 // in a node. It returns 1 for some elements even though they do not have children, which
379 // creates technically invalid DOM Positions. Be sure to call parentAnchoredEquivalent
380 // on a Position before using it to create a DOM Range, or an exception will be thrown.
381 int lastOffsetForEditing(const Node* node)
382 {
383     ASSERT(node);
384     if (!node)
385         return 0;
386     if (node->offsetInCharacters())
387         return node->maxCharacterOffset();
388
389     if (node->hasChildNodes())
390         return node->countChildNodes();
391
392     // NOTE: This should preempt the countChildNodes() for, e.g., select nodes (what does this mean)?
393     if (editingIgnoresContent(node))
394         return 1;
395
396     return 0;
397 }
398
399 String stringWithRebalancedWhitespace(const String& string, bool startIsStartOfParagraph, bool endIsEndOfParagraph)
400 {
401     Vector<UChar> rebalancedString(string.length());
402     StringView(string).getCharactersWithUpconvert(rebalancedString.data());
403
404     bool previousCharacterWasSpace = false;
405     for (size_t i = 0; i < rebalancedString.size(); i++) {
406         if (!isWhitespace(rebalancedString[i])) {
407             previousCharacterWasSpace = false;
408             continue;
409         }
410
411         if (previousCharacterWasSpace || (!i && startIsStartOfParagraph) || (i + 1 == rebalancedString.size() && endIsEndOfParagraph)) {
412             rebalancedString[i] = noBreakSpace;
413             previousCharacterWasSpace = false;
414         } else {
415             rebalancedString[i] = ' ';
416             previousCharacterWasSpace = true;
417         }
418     }
419
420     return String::adopt(rebalancedString);
421 }
422
423 bool isTableStructureNode(const Node *node)
424 {
425     RenderObject* renderer = node->renderer();
426     return (renderer && (renderer->isTableCell() || renderer->isTableRow() || renderer->isTableSection() || renderer->isRenderTableCol()));
427 }
428
429 const String& nonBreakingSpaceString()
430 {
431     static NeverDestroyed<String> nonBreakingSpaceString(&noBreakSpace, 1);
432     return nonBreakingSpaceString;
433 }
434
435 // FIXME: need to dump this
436 bool isSpecialElement(const Node *n)
437 {
438     if (!n)
439         return false;
440         
441     if (!n->isHTMLElement())
442         return false;
443
444     if (n->isLink())
445         return true;
446
447     RenderObject* renderer = n->renderer();
448     if (!renderer)
449         return false;
450         
451     if (renderer->style().display() == TABLE || renderer->style().display() == INLINE_TABLE)
452         return true;
453
454     if (renderer->style().isFloating())
455         return true;
456
457     if (renderer->style().position() != StaticPosition)
458         return true;
459         
460     return false;
461 }
462
463 static Node* firstInSpecialElement(const Position& pos)
464 {
465     Node* rootEditableElement = pos.containerNode()->rootEditableElement();
466     for (Node* n = pos.deprecatedNode(); n && n->rootEditableElement() == rootEditableElement; n = n->parentNode())
467         if (isSpecialElement(n)) {
468             VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
469             VisiblePosition firstInElement = VisiblePosition(firstPositionInOrBeforeNode(n), DOWNSTREAM);
470             if (isRenderedTable(n) && vPos == firstInElement.next())
471                 return n;
472             if (vPos == firstInElement)
473                 return n;
474         }
475     return 0;
476 }
477
478 static Node* lastInSpecialElement(const Position& pos)
479 {
480     Node* rootEditableElement = pos.containerNode()->rootEditableElement();
481     for (Node* n = pos.deprecatedNode(); n && n->rootEditableElement() == rootEditableElement; n = n->parentNode())
482         if (isSpecialElement(n)) {
483             VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
484             VisiblePosition lastInElement = VisiblePosition(lastPositionInOrAfterNode(n), DOWNSTREAM);
485             if (isRenderedTable(n) && vPos == lastInElement.previous())
486                 return n;
487             if (vPos == lastInElement)
488                 return n;
489         }
490     return 0;
491 }
492
493 bool isFirstVisiblePositionInSpecialElement(const Position& pos)
494 {
495     return firstInSpecialElement(pos);
496 }
497
498 Position positionBeforeContainingSpecialElement(const Position& pos, Node** containingSpecialElement)
499 {
500     Node* n = firstInSpecialElement(pos);
501     if (!n)
502         return pos;
503     Position result = positionInParentBeforeNode(n);
504     if (result.isNull() || result.deprecatedNode()->rootEditableElement() != pos.deprecatedNode()->rootEditableElement())
505         return pos;
506     if (containingSpecialElement)
507         *containingSpecialElement = n;
508     return result;
509 }
510
511 bool isLastVisiblePositionInSpecialElement(const Position& pos)
512 {
513     return lastInSpecialElement(pos);
514 }
515
516 Position positionAfterContainingSpecialElement(const Position& pos, Node **containingSpecialElement)
517 {
518     Node* n = lastInSpecialElement(pos);
519     if (!n)
520         return pos;
521     Position result = positionInParentAfterNode(n);
522     if (result.isNull() || result.deprecatedNode()->rootEditableElement() != pos.deprecatedNode()->rootEditableElement())
523         return pos;
524     if (containingSpecialElement)
525         *containingSpecialElement = n;
526     return result;
527 }
528
529 Position positionOutsideContainingSpecialElement(const Position &pos, Node **containingSpecialElement)
530 {
531     if (isFirstVisiblePositionInSpecialElement(pos))
532         return positionBeforeContainingSpecialElement(pos, containingSpecialElement);
533     if (isLastVisiblePositionInSpecialElement(pos))
534         return positionAfterContainingSpecialElement(pos, containingSpecialElement);
535     return pos;
536 }
537
538 Node* isFirstPositionAfterTable(const VisiblePosition& visiblePosition)
539 {
540     Position upstream(visiblePosition.deepEquivalent().upstream());
541     if (upstream.deprecatedNode() && upstream.deprecatedNode()->renderer() && upstream.deprecatedNode()->renderer()->isTable() && upstream.atLastEditingPositionForNode())
542         return upstream.deprecatedNode();
543     
544     return 0;
545 }
546
547 Node* isLastPositionBeforeTable(const VisiblePosition& visiblePosition)
548 {
549     Position downstream(visiblePosition.deepEquivalent().downstream());
550     if (downstream.deprecatedNode() && downstream.deprecatedNode()->renderer() && downstream.deprecatedNode()->renderer()->isTable() && downstream.atFirstEditingPositionForNode())
551         return downstream.deprecatedNode();
552     
553     return 0;
554 }
555
556 // Returns the visible position at the beginning of a node
557 VisiblePosition visiblePositionBeforeNode(Node* node)
558 {
559     ASSERT(node);
560     if (node->hasChildNodes())
561         return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
562     ASSERT(node->parentNode());
563     ASSERT(!node->parentNode()->isShadowRoot());
564     return positionInParentBeforeNode(node);
565 }
566
567 // Returns the visible position at the ending of a node
568 VisiblePosition visiblePositionAfterNode(Node* node)
569 {
570     ASSERT(node);
571     if (node->hasChildNodes())
572         return VisiblePosition(lastPositionInOrAfterNode(node), DOWNSTREAM);
573     ASSERT(node->parentNode());
574     ASSERT(!node->parentNode()->isShadowRoot());
575     return positionInParentAfterNode(node);
576 }
577
578 bool isListElement(Node *n)
579 {
580     return (n && (n->hasTagName(ulTag) || n->hasTagName(olTag) || n->hasTagName(dlTag)));
581 }
582
583 bool isListItem(const Node *n)
584 {
585     return n && (isListElement(n->parentNode()) || (n->renderer() && n->renderer()->isListItem()));
586 }
587
588 Element* enclosingElementWithTag(const Position& position, const QualifiedName& tagName)
589 {
590     if (position.isNull())
591         return nullptr;
592
593     Node* root = highestEditableRoot(position);
594     for (Node* node = position.deprecatedNode(); node; node = node->parentNode()) {
595         if (root && !node->hasEditableStyle())
596             continue;
597         if (!is<Element>(*node))
598             continue;
599         if (downcast<Element>(*node).hasTagName(tagName))
600             return downcast<Element>(node);
601         if (node == root)
602             return nullptr;
603     }
604
605     return nullptr;
606 }
607
608 Node* enclosingNodeOfType(const Position& p, bool (*nodeIsOfType)(const Node*), EditingBoundaryCrossingRule rule)
609 {
610     // FIXME: support CanSkipCrossEditingBoundary
611     ASSERT(rule == CanCrossEditingBoundary || rule == CannotCrossEditingBoundary);
612     if (p.isNull())
613         return 0;
614         
615     Node* root = rule == CannotCrossEditingBoundary ? highestEditableRoot(p) : 0;
616     for (Node* n = p.deprecatedNode(); n; n = n->parentNode()) {
617         // Don't return a non-editable node if the input position was editable, since
618         // the callers from editing will no doubt want to perform editing inside the returned node.
619         if (root && !n->hasEditableStyle())
620             continue;
621         if (nodeIsOfType(n))
622             return n;
623         if (n == root)
624             return 0;
625     }
626     
627     return 0;
628 }
629
630 Node* highestEnclosingNodeOfType(const Position& p, bool (*nodeIsOfType)(const Node*), EditingBoundaryCrossingRule rule, Node* stayWithin)
631 {
632     Node* highest = nullptr;
633     Node* root = rule == CannotCrossEditingBoundary ? highestEditableRoot(p) : 0;
634     for (Node* n = p.containerNode(); n && n != stayWithin; n = n->parentNode()) {
635         if (root && !n->hasEditableStyle())
636             continue;
637         if (nodeIsOfType(n))
638             highest = n;
639         if (n == root)
640             break;
641     }
642     
643     return highest;
644 }
645
646 static bool hasARenderedDescendant(Node* node, Node* excludedNode)
647 {
648     for (Node* n = node->firstChild(); n;) {
649         if (n == excludedNode) {
650             n = NodeTraversal::nextSkippingChildren(*n, node);
651             continue;
652         }
653         if (n->renderer())
654             return true;
655         n = NodeTraversal::next(*n, node);
656     }
657     return false;
658 }
659
660 Node* highestNodeToRemoveInPruning(Node* node)
661 {
662     Node* previousNode = nullptr;
663     Node* rootEditableElement = node ? node->rootEditableElement() : 0;
664     for (; node; node = node->parentNode()) {
665         if (RenderObject* renderer = node->renderer()) {
666             if (!renderer->canHaveChildren() || hasARenderedDescendant(node, previousNode) || rootEditableElement == node)
667                 return previousNode;
668         }
669         previousNode = node;
670     }
671     return 0;
672 }
673
674 Node* enclosingTableCell(const Position& p)
675 {
676     return downcast<Element>(enclosingNodeOfType(p, isTableCell));
677 }
678
679 Element* enclosingAnchorElement(const Position& p)
680 {
681     if (p.isNull())
682         return nullptr;
683
684     for (Node* node = p.deprecatedNode(); node; node = node->parentNode()) {
685         if (is<Element>(*node) && node->isLink())
686             return downcast<Element>(node);
687     }
688     return nullptr;
689 }
690
691 HTMLElement* enclosingList(Node* node)
692 {
693     if (!node)
694         return nullptr;
695         
696     Node* root = highestEditableRoot(firstPositionInOrBeforeNode(node));
697     
698     for (ContainerNode* ancestor = node->parentNode(); ancestor; ancestor = ancestor->parentNode()) {
699         if (is<HTMLUListElement>(*ancestor) || is<HTMLOListElement>(*ancestor))
700             return downcast<HTMLElement>(ancestor);
701         if (ancestor == root)
702             return nullptr;
703     }
704     
705     return nullptr;
706 }
707
708 Node* enclosingListChild(Node *node)
709 {
710     if (!node)
711         return nullptr;
712     // Check for a list item element, or for a node whose parent is a list element. Such a node
713     // will appear visually as a list item (but without a list marker)
714     Node* root = highestEditableRoot(firstPositionInOrBeforeNode(node));
715     
716     // FIXME: This function is inappropriately named if it starts with node instead of node->parentNode()
717     for (Node* n = node; n && n->parentNode(); n = n->parentNode()) {
718         if (n->hasTagName(liTag) || (isListElement(n->parentNode()) && n != root))
719             return n;
720         if (n == root || isTableCell(n))
721             return nullptr;
722     }
723     
724     return nullptr;
725 }
726
727 static HTMLElement* embeddedSublist(Node* listItem)
728 {
729     // Check the DOM so that we'll find collapsed sublists without renderers.
730     for (Node* n = listItem->firstChild(); n; n = n->nextSibling()) {
731         if (isListElement(n))
732             return downcast<HTMLElement>(n);
733     }
734     
735     return nullptr;
736 }
737
738 static Node* appendedSublist(Node* listItem)
739 {
740     // Check the DOM so that we'll find collapsed sublists without renderers.
741     for (Node* n = listItem->nextSibling(); n; n = n->nextSibling()) {
742         if (isListElement(n))
743             return downcast<HTMLElement>(n);
744         if (isListItem(listItem))
745             return nullptr;
746     }
747     
748     return nullptr;
749 }
750
751 // FIXME: This method should not need to call isStartOfParagraph/isEndOfParagraph
752 Node* enclosingEmptyListItem(const VisiblePosition& visiblePos)
753 {
754     // Check that position is on a line by itself inside a list item
755     Node* listChildNode = enclosingListChild(visiblePos.deepEquivalent().deprecatedNode());
756     if (!listChildNode || !isStartOfParagraph(visiblePos) || !isEndOfParagraph(visiblePos))
757         return 0;
758
759     VisiblePosition firstInListChild(firstPositionInOrBeforeNode(listChildNode));
760     VisiblePosition lastInListChild(lastPositionInOrAfterNode(listChildNode));
761
762     if (firstInListChild != visiblePos || lastInListChild != visiblePos)
763         return 0;
764     
765     if (embeddedSublist(listChildNode) || appendedSublist(listChildNode))
766         return 0;
767         
768     return listChildNode;
769 }
770
771 HTMLElement* outermostEnclosingList(Node* node, Node* rootList)
772 {
773     HTMLElement* list = enclosingList(node);
774     if (!list)
775         return 0;
776
777     while (HTMLElement* nextList = enclosingList(list)) {
778         if (nextList == rootList)
779             break;
780         list = nextList;
781     }
782
783     return list;
784 }
785
786 bool canMergeLists(Element* firstList, Element* secondList)
787 {
788     if (!firstList || !secondList || !firstList->isHTMLElement() || !secondList->isHTMLElement())
789         return false;
790
791     return firstList->hasTagName(secondList->tagQName()) // make sure the list types match (ol vs. ul)
792     && firstList->hasEditableStyle() && secondList->hasEditableStyle() // both lists are editable
793     && firstList->rootEditableElement() == secondList->rootEditableElement() // don't cross editing boundaries
794     && isVisiblyAdjacent(positionInParentAfterNode(firstList), positionInParentBeforeNode(secondList));
795     // Make sure there is no visible content between this li and the previous list
796 }
797
798 Node* highestAncestor(Node* node)
799 {
800     ASSERT(node);
801     Node* parent = node;
802     while ((node = node->parentNode()))
803         parent = node;
804     return parent;
805 }
806
807 static Node* previousNodeConsideringAtomicNodes(const Node* node)
808 {
809     if (node->previousSibling()) {
810         Node* n = node->previousSibling();
811         while (!isAtomicNode(n) && n->lastChild())
812             n = n->lastChild();
813         return n;
814     }
815     if (node->parentNode())
816         return node->parentNode();
817     return 0;
818 }
819
820 static Node* nextNodeConsideringAtomicNodes(const Node* node)
821 {
822     if (!isAtomicNode(node) && node->firstChild())
823         return node->firstChild();
824     if (node->nextSibling())
825         return node->nextSibling();
826     const Node* n = node;
827     while (n && !n->nextSibling())
828         n = n->parentNode();
829     if (n)
830         return n->nextSibling();
831     return 0;
832 }
833
834 Node* previousLeafNode(const Node* node)
835 {
836     Node* n = previousNodeConsideringAtomicNodes(node);
837     while (n) {
838         if (isAtomicNode(n))
839             return n;
840         n = previousNodeConsideringAtomicNodes(n);
841     }
842     return 0;
843 }
844
845 Node* nextLeafNode(const Node* node)
846 {
847     Node* n = nextNodeConsideringAtomicNodes(node);
848     while (n) {
849         if (isAtomicNode(n))
850             return n;
851         n = nextNodeConsideringAtomicNodes(n);
852     }
853     return 0;
854 }
855
856 // FIXME: do not require renderer, so that this can be used within fragments
857 bool isRenderedTable(const Node* n)
858 {
859     if (!n || !n->isElementNode())
860         return false;
861
862     RenderObject* renderer = n->renderer();
863     return (renderer && renderer->isTable());
864 }
865
866 bool isTableCell(const Node* node)
867 {
868     RenderObject* r = node->renderer();
869     if (!r)
870         return node->hasTagName(tdTag) || node->hasTagName(thTag);
871     
872     return r->isTableCell();
873 }
874
875 bool isEmptyTableCell(const Node* node)
876 {
877     // Returns true IFF the passed in node is one of:
878     //   .) a table cell with no children,
879     //   .) a table cell with a single BR child, and which has no other child renderers, including :before and :after renderers
880     //   .) the BR child of such a table cell
881
882     // Find rendered node
883     while (node && !node->renderer())
884         node = node->parentNode();
885     if (!node)
886         return false;
887
888     // Make sure the rendered node is a table cell or <br>.
889     // If it's a <br>, then the parent node has to be a table cell.
890     RenderObject* renderer = node->renderer();
891     if (renderer->isBR()) {
892         renderer = renderer->parent();
893         if (!renderer)
894             return false;
895     }
896     if (!is<RenderTableCell>(*renderer))
897         return false;
898
899     // Check that the table cell contains no child renderers except for perhaps a single <br>.
900     RenderObject* childRenderer = downcast<RenderTableCell>(*renderer).firstChild();
901     if (!childRenderer)
902         return true;
903     if (!childRenderer->isBR())
904         return false;
905     return !childRenderer->nextSibling();
906 }
907
908 Ref<HTMLElement> createDefaultParagraphElement(Document& document)
909 {
910     switch (document.frame()->editor().defaultParagraphSeparator()) {
911     case EditorParagraphSeparatorIsDiv:
912         return HTMLDivElement::create(document);
913     case EditorParagraphSeparatorIsP:
914         break;
915     }
916     return HTMLParagraphElement::create(document);
917 }
918
919 Ref<HTMLElement> createBreakElement(Document& document)
920 {
921     return HTMLBRElement::create(document);
922 }
923
924 PassRefPtr<HTMLElement> createOrderedListElement(Document& document)
925 {
926     return HTMLOListElement::create(document);
927 }
928
929 PassRefPtr<HTMLElement> createUnorderedListElement(Document& document)
930 {
931     return HTMLUListElement::create(document);
932 }
933
934 PassRefPtr<HTMLElement> createListItemElement(Document& document)
935 {
936     return HTMLLIElement::create(document);
937 }
938
939 Ref<HTMLElement> createHTMLElement(Document& document, const QualifiedName& name)
940 {
941     return HTMLElementFactory::createElement(name, document);
942 }
943
944 Ref<HTMLElement> createHTMLElement(Document& document, const AtomicString& tagName)
945 {
946     return createHTMLElement(document, QualifiedName(nullAtom, tagName, xhtmlNamespaceURI));
947 }
948
949 bool isTabSpanNode(const Node *node)
950 {
951     return node && node->hasTagName(spanTag) && node->isElementNode() && static_cast<const Element *>(node)->getAttribute(classAttr) == AppleTabSpanClass;
952 }
953
954 bool isTabSpanTextNode(const Node *node)
955 {
956     return node && node->isTextNode() && node->parentNode() && isTabSpanNode(node->parentNode());
957 }
958
959 Node* tabSpanNode(const Node *node)
960 {
961     return isTabSpanTextNode(node) ? node->parentNode() : 0;
962 }
963     
964 Position 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
978 Ref<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.releaseNonNull(), ASSERT_NO_EXCEPTION);
992
993     return spanElement.releaseNonNull();
994 }
995
996 Ref<Element> createTabSpanElement(Document& document, const String& tabText)
997 {
998     return createTabSpanElement(document, document.createTextNode(tabText));
999 }
1000
1001 Ref<Element> createTabSpanElement(Document& document)
1002 {
1003     return createTabSpanElement(document, PassRefPtr<Node>());
1004 }
1005
1006 bool 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
1018 unsigned 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
1028 void updatePositionForNodeRemoval(Position& position, Node& node)
1029 {
1030     if (position.isNull())
1031         return;
1032     switch (position.anchorType()) {
1033     case Position::PositionIsBeforeChildren:
1034         if (node.containsIncludingShadowDOM(position.containerNode()))
1035             position = positionInParentBeforeNode(&node);
1036         break;
1037     case Position::PositionIsAfterChildren:
1038         if (node.containsIncludingShadowDOM(position.containerNode()))
1039             position = positionInParentBeforeNode(&node);
1040         break;
1041     case Position::PositionIsOffsetInAnchor:
1042         if (position.containerNode() == node.parentNode() && static_cast<unsigned>(position.offsetInContainerNode()) > node.computeNodeIndex())
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
1058 bool 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
1066 int 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.
1075 int 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
1084 bool lineBreakExistsAtVisiblePosition(const VisiblePosition& visiblePosition)
1085 {
1086     return lineBreakExistsAtPosition(visiblePosition.deepEquivalent().downstream());
1087 }
1088
1089 bool 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 (!is<Text>(*position.anchorNode()) || !position.anchorNode()->renderer()->style().preserveNewline())
1101         return false;
1102     
1103     Text& textNode = downcast<Text>(*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.
1111 VisibleSelection 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.
1142 int 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     return TextIterator::rangeLength(range.get(), true);
1158 }
1159
1160 // FIXME: Merge these two functions.
1161 int indexForVisiblePosition(Node* node, const VisiblePosition& visiblePosition, bool forSelectionPreservation)
1162 {
1163     ASSERT(node);
1164     RefPtr<Range> range = Range::create(node->document(), firstPositionInNode(node), visiblePosition.deepEquivalent().parentAnchoredEquivalent());
1165     return TextIterator::rangeLength(range.get(), forSelectionPreservation);
1166 }
1167
1168 VisiblePosition visiblePositionForIndex(int index, ContainerNode* scope)
1169 {
1170     RefPtr<Range> range = TextIterator::rangeFromLocationAndLength(scope, index, 0, true);
1171     // Check for an invalid index. Certain editing operations invalidate indices because 
1172     // of problems with TextIteratorEmitsCharactersBetweenAllVisiblePositions.
1173     if (!range)
1174         return VisiblePosition();
1175     return VisiblePosition(range->startPosition());
1176 }
1177
1178 VisiblePosition visiblePositionForIndexUsingCharacterIterator(Node* node, int index)
1179 {
1180     ASSERT(node);
1181     if (index <= 0)
1182         return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
1183
1184     RefPtr<Range> range = Range::create(node->document());
1185     range->selectNodeContents(node, IGNORE_EXCEPTION);
1186     CharacterIterator it(*range);
1187     it.advance(index - 1);
1188     return VisiblePosition(it.atEnd() ? range->endPosition() : it.range()->endPosition(), UPSTREAM);
1189 }
1190
1191 // Determines whether two positions are visibly next to each other (first then second)
1192 // while ignoring whitespaces and unrendered nodes
1193 bool isVisiblyAdjacent(const Position& first, const Position& second)
1194 {
1195     return VisiblePosition(first) == VisiblePosition(second.upstream());
1196 }
1197
1198 // Determines whether a node is inside a range or visibly starts and ends at the boundaries of the range.
1199 // Call this function to determine whether a node is visibly fit inside selectedRange
1200 bool isNodeVisiblyContainedWithin(Node* node, const Range* selectedRange)
1201 {
1202     ASSERT(node);
1203     ASSERT(selectedRange);
1204     // If the node is inside the range, then it surely is contained within
1205     if (selectedRange->compareNode(node, IGNORE_EXCEPTION) == Range::NODE_INSIDE)
1206         return true;
1207
1208     bool startIsVisuallySame = visiblePositionBeforeNode(node) == selectedRange->startPosition();
1209     if (startIsVisuallySame && comparePositions(positionInParentAfterNode(node), selectedRange->endPosition()) < 0)
1210         return true;
1211
1212     bool endIsVisuallySame = visiblePositionAfterNode(node) == selectedRange->endPosition();
1213     if (endIsVisuallySame && comparePositions(selectedRange->startPosition(), positionInParentBeforeNode(node)) < 0)
1214         return true;
1215
1216     return startIsVisuallySame && endIsVisuallySame;
1217 }
1218
1219 bool isRenderedAsNonInlineTableImageOrHR(const Node* node)
1220 {
1221     if (!node)
1222         return false;
1223     RenderObject* renderer = node->renderer();
1224     return renderer && ((renderer->isTable() && !renderer->isInline()) || (renderer->isImage() && !renderer->isInline()) || renderer->isHR());
1225 }
1226
1227 bool areIdenticalElements(const Node* first, const Node* second)
1228 {
1229     if (!is<Element>(*first) || !is<Element>(*second))
1230         return false;
1231
1232     const Element& firstElement = downcast<Element>(*first);
1233     const Element& secondElement = downcast<Element>(*second);
1234     if (!firstElement.hasTagName(secondElement.tagQName()))
1235         return false;
1236
1237     return firstElement.hasEquivalentAttributes(&secondElement);
1238 }
1239
1240 bool isNonTableCellHTMLBlockElement(const Node* node)
1241 {
1242     return node->hasTagName(listingTag)
1243         || node->hasTagName(olTag)
1244         || node->hasTagName(preTag)
1245         || is<HTMLTableElement>(*node)
1246         || node->hasTagName(ulTag)
1247         || node->hasTagName(xmpTag)
1248         || node->hasTagName(h1Tag)
1249         || node->hasTagName(h2Tag)
1250         || node->hasTagName(h3Tag)
1251         || node->hasTagName(h4Tag)
1252         || node->hasTagName(h5Tag);
1253 }
1254
1255 Position adjustedSelectionStartForStyleComputation(const VisibleSelection& selection)
1256 {
1257     // This function is used by range style computations to avoid bugs like:
1258     // <rdar://problem/4017641> REGRESSION (Mail): you can only bold/unbold a selection starting from end of line once
1259     // It is important to skip certain irrelevant content at the start of the selection, so we do not wind up 
1260     // with a spurious "mixed" style.
1261
1262     VisiblePosition visiblePosition = selection.start();
1263     if (visiblePosition.isNull())
1264         return Position();
1265
1266     // if the selection is a caret, just return the position, since the style
1267     // behind us is relevant
1268     if (selection.isCaret())
1269         return visiblePosition.deepEquivalent();
1270
1271     // if the selection starts just before a paragraph break, skip over it
1272     if (isEndOfParagraph(visiblePosition))
1273         return visiblePosition.next().deepEquivalent().downstream();
1274
1275     // otherwise, make sure to be at the start of the first selected node,
1276     // instead of possibly at the end of the last node before the selection
1277     return visiblePosition.deepEquivalent().downstream();
1278 }
1279
1280 // FIXME: Should this be deprecated like deprecatedEnclosingBlockFlowElement is?
1281 bool isBlockFlowElement(const Node* node)
1282 {
1283     if (!node->isElementNode())
1284         return false;
1285     RenderObject* renderer = node->renderer();
1286     return renderer && renderer->isRenderBlockFlow();
1287 }
1288
1289 Element* deprecatedEnclosingBlockFlowElement(Node* node)
1290 {
1291     if (!node)
1292         return nullptr;
1293     if (isBlockFlowElement(node))
1294         return downcast<Element>(node);
1295     while ((node = node->parentNode())) {
1296         if (isBlockFlowElement(node) || is<HTMLBodyElement>(*node))
1297             return downcast<Element>(node);
1298     }
1299     return nullptr;
1300 }
1301
1302 static inline bool caretRendersInsideNode(Node* node)
1303 {
1304     return node && !isRenderedTable(node) && !editingIgnoresContent(node);
1305 }
1306
1307 RenderBlock* rendererForCaretPainting(Node* node)
1308 {
1309     if (!node)
1310         return nullptr;
1311
1312     RenderObject* renderer = node->renderer();
1313     if (!renderer)
1314         return nullptr;
1315
1316     // If caretNode is a block and caret is inside it, then caret should be painted by that block.
1317     bool paintedByBlock = is<RenderBlockFlow>(*renderer) && caretRendersInsideNode(node);
1318     return paintedByBlock ? downcast<RenderBlock>(renderer) : renderer->containingBlock();
1319 }
1320
1321 LayoutRect localCaretRectInRendererForCaretPainting(const VisiblePosition& caretPosition, RenderBlock*& caretPainter)
1322 {
1323     if (caretPosition.isNull())
1324         return LayoutRect();
1325
1326     ASSERT(caretPosition.deepEquivalent().deprecatedNode()->renderer());
1327
1328     // First compute a rect local to the renderer at the selection start.
1329     RenderObject* renderer;
1330     LayoutRect localRect = caretPosition.localCaretRect(renderer);
1331
1332     // Get the renderer that will be responsible for painting the caret
1333     // (which is either the renderer we just found, or one of its containers).
1334     caretPainter = rendererForCaretPainting(caretPosition.deepEquivalent().deprecatedNode());
1335
1336     // Compute an offset between the renderer and the caretPainter.
1337     while (renderer != caretPainter) {
1338         RenderElement* containerObject = renderer->container();
1339         if (!containerObject)
1340             return LayoutRect();
1341         localRect.move(renderer->offsetFromContainer(*containerObject, localRect.location()));
1342         renderer = containerObject;
1343     }
1344
1345     return localRect;
1346 }
1347
1348 IntRect absoluteBoundsForLocalCaretRect(RenderBlock* rendererForCaretPainting, const LayoutRect& rect)
1349 {
1350     if (!rendererForCaretPainting || rect.isEmpty())
1351         return IntRect();
1352
1353     LayoutRect localRect(rect);
1354     rendererForCaretPainting->flipForWritingMode(localRect);
1355     return rendererForCaretPainting->localToAbsoluteQuad(FloatRect(localRect)).enclosingBoundingBox();
1356 }
1357
1358 } // namespace WebCore