8f04d081352b963256fbad757fe135e6dcd3d750
[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 VisiblePosition firstEditablePositionAfterPositionInRoot(const Position& position, Node* highestRoot)
289 {
290     // position falls before highestRoot.
291     if (comparePositions(position, firstPositionInNode(highestRoot)) == -1 && highestRoot->hasEditableStyle())
292         return firstPositionInNode(highestRoot);
293
294     Position p = position;
295
296     if (&position.deprecatedNode()->treeScope() != &highestRoot->treeScope()) {
297         Node* shadowAncestor = highestRoot->treeScope().ancestorInThisScope(p.deprecatedNode());
298         if (!shadowAncestor)
299             return VisiblePosition();
300
301         p = positionAfterNode(shadowAncestor);
302     }
303
304     while (p.deprecatedNode() && !isEditablePosition(p) && p.deprecatedNode()->isDescendantOf(highestRoot))
305         p = isAtomicNode(p.deprecatedNode()) ? positionInParentAfterNode(p.deprecatedNode()) : nextVisuallyDistinctCandidate(p);
306     
307     if (p.deprecatedNode() && p.deprecatedNode() != highestRoot && !p.deprecatedNode()->isDescendantOf(highestRoot))
308         return VisiblePosition();
309     
310     return VisiblePosition(p);
311 }
312
313 VisiblePosition lastEditablePositionBeforePositionInRoot(const Position& position, Node* highestRoot)
314 {
315     // When position falls after highestRoot, the result is easy to compute.
316     if (comparePositions(position, lastPositionInNode(highestRoot)) == 1)
317         return lastPositionInNode(highestRoot);
318
319     Position p = position;
320
321     if (&position.deprecatedNode()->treeScope() != &highestRoot->treeScope()) {
322         Node* shadowAncestor = highestRoot->treeScope().ancestorInThisScope(p.deprecatedNode());
323         if (!shadowAncestor)
324             return VisiblePosition();
325
326         p = firstPositionInOrBeforeNode(shadowAncestor);
327     }
328     
329     while (p.deprecatedNode() && !isEditablePosition(p) && p.deprecatedNode()->isDescendantOf(highestRoot))
330         p = isAtomicNode(p.deprecatedNode()) ? positionInParentBeforeNode(p.deprecatedNode()) : previousVisuallyDistinctCandidate(p);
331     
332     if (p.deprecatedNode() && p.deprecatedNode() != highestRoot && !p.deprecatedNode()->isDescendantOf(highestRoot))
333         return VisiblePosition();
334     
335     return VisiblePosition(p);
336 }
337
338 // FIXME: The method name, comment, and code say three different things here!
339 // Whether or not content before and after this node will collapse onto the same line as it.
340 bool isBlock(const Node* node)
341 {
342     return node && node->renderer() && !node->renderer()->isInline() && !node->renderer()->isRubyText();
343 }
344
345 bool isInline(const Node* node)
346 {
347     return node && node->renderer() && node->renderer()->isInline();
348 }
349
350 // FIXME: Deploy this in all of the places where enclosingBlockFlow/enclosingBlockFlowOrTableElement are used.
351 // FIXME: Pass a position to this function. The enclosing block of [table, x] for example, should be the 
352 // block that contains the table and not the table, and this function should be the only one responsible for 
353 // knowing about these kinds of special cases.
354 Element* enclosingBlock(Node* node, EditingBoundaryCrossingRule rule)
355 {
356     Node* enclosingNode = enclosingNodeOfType(firstPositionInOrBeforeNode(node), isBlock, rule);
357     return is<Element>(enclosingNode) ? downcast<Element>(enclosingNode) : nullptr;
358 }
359
360 TextDirection directionOfEnclosingBlock(const Position& position)
361 {
362     auto block = enclosingBlock(position.containerNode());
363     if (!block)
364         return LTR;
365     auto renderer = block->renderer();
366     if (!renderer)
367         return LTR;
368     return renderer->style().direction();
369 }
370
371 // This method is used to create positions in the DOM. It returns the maximum valid offset
372 // in a node. It returns 1 for some elements even though they do not have children, which
373 // creates technically invalid DOM Positions. Be sure to call parentAnchoredEquivalent
374 // on a Position before using it to create a DOM Range, or an exception will be thrown.
375 int lastOffsetForEditing(const Node* node)
376 {
377     ASSERT(node);
378     if (!node)
379         return 0;
380     if (node->offsetInCharacters())
381         return node->maxCharacterOffset();
382
383     if (node->hasChildNodes())
384         return node->countChildNodes();
385
386     // NOTE: This should preempt the countChildNodes() for, e.g., select nodes (what does this mean)?
387     if (editingIgnoresContent(node))
388         return 1;
389
390     return 0;
391 }
392
393 String stringWithRebalancedWhitespace(const String& string, bool startIsStartOfParagraph, bool endIsEndOfParagraph)
394 {
395     Vector<UChar> rebalancedString(string.length());
396     StringView(string).getCharactersWithUpconvert(rebalancedString.data());
397
398     bool previousCharacterWasSpace = false;
399     for (size_t i = 0; i < rebalancedString.size(); i++) {
400         if (!isWhitespace(rebalancedString[i])) {
401             previousCharacterWasSpace = false;
402             continue;
403         }
404
405         if (previousCharacterWasSpace || (!i && startIsStartOfParagraph) || (i + 1 == rebalancedString.size() && endIsEndOfParagraph)) {
406             rebalancedString[i] = noBreakSpace;
407             previousCharacterWasSpace = false;
408         } else {
409             rebalancedString[i] = ' ';
410             previousCharacterWasSpace = true;
411         }
412     }
413
414     return String::adopt(rebalancedString);
415 }
416
417 bool isTableStructureNode(const Node *node)
418 {
419     RenderObject* renderer = node->renderer();
420     return (renderer && (renderer->isTableCell() || renderer->isTableRow() || renderer->isTableSection() || renderer->isRenderTableCol()));
421 }
422
423 const String& nonBreakingSpaceString()
424 {
425     DEPRECATED_DEFINE_STATIC_LOCAL(String, nonBreakingSpaceString, (&noBreakSpace, 1));
426     return nonBreakingSpaceString;
427 }
428
429 // FIXME: need to dump this
430 bool isSpecialElement(const Node *n)
431 {
432     if (!n)
433         return false;
434         
435     if (!n->isHTMLElement())
436         return false;
437
438     if (n->isLink())
439         return true;
440
441     RenderObject* renderer = n->renderer();
442     if (!renderer)
443         return false;
444         
445     if (renderer->style().display() == TABLE || renderer->style().display() == INLINE_TABLE)
446         return true;
447
448     if (renderer->style().isFloating())
449         return true;
450
451     if (renderer->style().position() != StaticPosition)
452         return true;
453         
454     return false;
455 }
456
457 static Node* firstInSpecialElement(const Position& pos)
458 {
459     Node* rootEditableElement = pos.containerNode()->rootEditableElement();
460     for (Node* n = pos.deprecatedNode(); n && n->rootEditableElement() == rootEditableElement; n = n->parentNode())
461         if (isSpecialElement(n)) {
462             VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
463             VisiblePosition firstInElement = VisiblePosition(firstPositionInOrBeforeNode(n), DOWNSTREAM);
464             if (isRenderedTable(n) && vPos == firstInElement.next())
465                 return n;
466             if (vPos == firstInElement)
467                 return n;
468         }
469     return 0;
470 }
471
472 static Node* lastInSpecialElement(const Position& pos)
473 {
474     Node* rootEditableElement = pos.containerNode()->rootEditableElement();
475     for (Node* n = pos.deprecatedNode(); n && n->rootEditableElement() == rootEditableElement; n = n->parentNode())
476         if (isSpecialElement(n)) {
477             VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
478             VisiblePosition lastInElement = VisiblePosition(lastPositionInOrAfterNode(n), DOWNSTREAM);
479             if (isRenderedTable(n) && vPos == lastInElement.previous())
480                 return n;
481             if (vPos == lastInElement)
482                 return n;
483         }
484     return 0;
485 }
486
487 bool isFirstVisiblePositionInSpecialElement(const Position& pos)
488 {
489     return firstInSpecialElement(pos);
490 }
491
492 Position positionBeforeContainingSpecialElement(const Position& pos, Node** containingSpecialElement)
493 {
494     Node* n = firstInSpecialElement(pos);
495     if (!n)
496         return pos;
497     Position result = positionInParentBeforeNode(n);
498     if (result.isNull() || result.deprecatedNode()->rootEditableElement() != pos.deprecatedNode()->rootEditableElement())
499         return pos;
500     if (containingSpecialElement)
501         *containingSpecialElement = n;
502     return result;
503 }
504
505 bool isLastVisiblePositionInSpecialElement(const Position& pos)
506 {
507     return lastInSpecialElement(pos);
508 }
509
510 Position positionAfterContainingSpecialElement(const Position& pos, Node **containingSpecialElement)
511 {
512     Node* n = lastInSpecialElement(pos);
513     if (!n)
514         return pos;
515     Position result = positionInParentAfterNode(n);
516     if (result.isNull() || result.deprecatedNode()->rootEditableElement() != pos.deprecatedNode()->rootEditableElement())
517         return pos;
518     if (containingSpecialElement)
519         *containingSpecialElement = n;
520     return result;
521 }
522
523 Position positionOutsideContainingSpecialElement(const Position &pos, Node **containingSpecialElement)
524 {
525     if (isFirstVisiblePositionInSpecialElement(pos))
526         return positionBeforeContainingSpecialElement(pos, containingSpecialElement);
527     if (isLastVisiblePositionInSpecialElement(pos))
528         return positionAfterContainingSpecialElement(pos, containingSpecialElement);
529     return pos;
530 }
531
532 Node* isFirstPositionAfterTable(const VisiblePosition& visiblePosition)
533 {
534     Position upstream(visiblePosition.deepEquivalent().upstream());
535     if (upstream.deprecatedNode() && upstream.deprecatedNode()->renderer() && upstream.deprecatedNode()->renderer()->isTable() && upstream.atLastEditingPositionForNode())
536         return upstream.deprecatedNode();
537     
538     return 0;
539 }
540
541 Node* isLastPositionBeforeTable(const VisiblePosition& visiblePosition)
542 {
543     Position downstream(visiblePosition.deepEquivalent().downstream());
544     if (downstream.deprecatedNode() && downstream.deprecatedNode()->renderer() && downstream.deprecatedNode()->renderer()->isTable() && downstream.atFirstEditingPositionForNode())
545         return downstream.deprecatedNode();
546     
547     return 0;
548 }
549
550 // Returns the visible position at the beginning of a node
551 VisiblePosition visiblePositionBeforeNode(Node* node)
552 {
553     ASSERT(node);
554     if (node->hasChildNodes())
555         return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
556     ASSERT(node->parentNode());
557     ASSERT(!node->parentNode()->isShadowRoot());
558     return positionInParentBeforeNode(node);
559 }
560
561 // Returns the visible position at the ending of a node
562 VisiblePosition visiblePositionAfterNode(Node* node)
563 {
564     ASSERT(node);
565     if (node->hasChildNodes())
566         return VisiblePosition(lastPositionInOrAfterNode(node), DOWNSTREAM);
567     ASSERT(node->parentNode());
568     ASSERT(!node->parentNode()->isShadowRoot());
569     return positionInParentAfterNode(node);
570 }
571
572 bool isListElement(Node *n)
573 {
574     return (n && (n->hasTagName(ulTag) || n->hasTagName(olTag) || n->hasTagName(dlTag)));
575 }
576
577 bool isListItem(const Node *n)
578 {
579     return n && (isListElement(n->parentNode()) || (n->renderer() && n->renderer()->isListItem()));
580 }
581
582 Element* enclosingElementWithTag(const Position& position, const QualifiedName& tagName)
583 {
584     if (position.isNull())
585         return nullptr;
586
587     Node* root = highestEditableRoot(position);
588     for (Node* node = position.deprecatedNode(); node; node = node->parentNode()) {
589         if (root && !node->hasEditableStyle())
590             continue;
591         if (!is<Element>(*node))
592             continue;
593         if (downcast<Element>(*node).hasTagName(tagName))
594             return downcast<Element>(node);
595         if (node == root)
596             return nullptr;
597     }
598
599     return nullptr;
600 }
601
602 Node* enclosingNodeOfType(const Position& p, bool (*nodeIsOfType)(const Node*), EditingBoundaryCrossingRule rule)
603 {
604     // FIXME: support CanSkipCrossEditingBoundary
605     ASSERT(rule == CanCrossEditingBoundary || rule == CannotCrossEditingBoundary);
606     if (p.isNull())
607         return 0;
608         
609     Node* root = rule == CannotCrossEditingBoundary ? highestEditableRoot(p) : 0;
610     for (Node* n = p.deprecatedNode(); n; n = n->parentNode()) {
611         // Don't return a non-editable node if the input position was editable, since
612         // the callers from editing will no doubt want to perform editing inside the returned node.
613         if (root && !n->hasEditableStyle())
614             continue;
615         if (nodeIsOfType(n))
616             return n;
617         if (n == root)
618             return 0;
619     }
620     
621     return 0;
622 }
623
624 Node* highestEnclosingNodeOfType(const Position& p, bool (*nodeIsOfType)(const Node*), EditingBoundaryCrossingRule rule, Node* stayWithin)
625 {
626     Node* highest = 0;
627     Node* root = rule == CannotCrossEditingBoundary ? highestEditableRoot(p) : 0;
628     for (Node* n = p.containerNode(); n && n != stayWithin; n = n->parentNode()) {
629         if (root && !n->hasEditableStyle())
630             continue;
631         if (nodeIsOfType(n))
632             highest = n;
633         if (n == root)
634             break;
635     }
636     
637     return highest;
638 }
639
640 static bool hasARenderedDescendant(Node* node, Node* excludedNode)
641 {
642     for (Node* n = node->firstChild(); n;) {
643         if (n == excludedNode) {
644             n = NodeTraversal::nextSkippingChildren(*n, node);
645             continue;
646         }
647         if (n->renderer())
648             return true;
649         n = NodeTraversal::next(*n, node);
650     }
651     return false;
652 }
653
654 Node* highestNodeToRemoveInPruning(Node* node)
655 {
656     Node* previousNode = 0;
657     Node* rootEditableElement = node ? node->rootEditableElement() : 0;
658     for (; node; node = node->parentNode()) {
659         if (RenderObject* renderer = node->renderer()) {
660             if (!renderer->canHaveChildren() || hasARenderedDescendant(node, previousNode) || rootEditableElement == node)
661                 return previousNode;
662         }
663         previousNode = node;
664     }
665     return 0;
666 }
667
668 Node* enclosingTableCell(const Position& p)
669 {
670     return downcast<Element>(enclosingNodeOfType(p, isTableCell));
671 }
672
673 Element* enclosingAnchorElement(const Position& p)
674 {
675     if (p.isNull())
676         return nullptr;
677
678     for (Node* node = p.deprecatedNode(); node; node = node->parentNode()) {
679         if (is<Element>(*node) && node->isLink())
680             return downcast<Element>(node);
681     }
682     return nullptr;
683 }
684
685 HTMLElement* enclosingList(Node* node)
686 {
687     if (!node)
688         return nullptr;
689         
690     Node* root = highestEditableRoot(firstPositionInOrBeforeNode(node));
691     
692     for (ContainerNode* ancestor = node->parentNode(); ancestor; ancestor = ancestor->parentNode()) {
693         if (is<HTMLUListElement>(*ancestor) || is<HTMLOListElement>(*ancestor))
694             return downcast<HTMLElement>(ancestor);
695         if (ancestor == root)
696             return nullptr;
697     }
698     
699     return nullptr;
700 }
701
702 Node* enclosingListChild(Node *node)
703 {
704     if (!node)
705         return nullptr;
706     // Check for a list item element, or for a node whose parent is a list element. Such a node
707     // will appear visually as a list item (but without a list marker)
708     Node* root = highestEditableRoot(firstPositionInOrBeforeNode(node));
709     
710     // FIXME: This function is inappropriately named if it starts with node instead of node->parentNode()
711     for (Node* n = node; n && n->parentNode(); n = n->parentNode()) {
712         if (n->hasTagName(liTag) || (isListElement(n->parentNode()) && n != root))
713             return n;
714         if (n == root || isTableCell(n))
715             return nullptr;
716     }
717     
718     return nullptr;
719 }
720
721 static HTMLElement* embeddedSublist(Node* listItem)
722 {
723     // Check the DOM so that we'll find collapsed sublists without renderers.
724     for (Node* n = listItem->firstChild(); n; n = n->nextSibling()) {
725         if (isListElement(n))
726             return downcast<HTMLElement>(n);
727     }
728     
729     return nullptr;
730 }
731
732 static Node* appendedSublist(Node* listItem)
733 {
734     // Check the DOM so that we'll find collapsed sublists without renderers.
735     for (Node* n = listItem->nextSibling(); n; n = n->nextSibling()) {
736         if (isListElement(n))
737             return downcast<HTMLElement>(n);
738         if (isListItem(listItem))
739             return nullptr;
740     }
741     
742     return nullptr;
743 }
744
745 // FIXME: This method should not need to call isStartOfParagraph/isEndOfParagraph
746 Node* enclosingEmptyListItem(const VisiblePosition& visiblePos)
747 {
748     // Check that position is on a line by itself inside a list item
749     Node* listChildNode = enclosingListChild(visiblePos.deepEquivalent().deprecatedNode());
750     if (!listChildNode || !isStartOfParagraph(visiblePos) || !isEndOfParagraph(visiblePos))
751         return 0;
752
753     VisiblePosition firstInListChild(firstPositionInOrBeforeNode(listChildNode));
754     VisiblePosition lastInListChild(lastPositionInOrAfterNode(listChildNode));
755
756     if (firstInListChild != visiblePos || lastInListChild != visiblePos)
757         return 0;
758     
759     if (embeddedSublist(listChildNode) || appendedSublist(listChildNode))
760         return 0;
761         
762     return listChildNode;
763 }
764
765 HTMLElement* outermostEnclosingList(Node* node, Node* rootList)
766 {
767     HTMLElement* list = enclosingList(node);
768     if (!list)
769         return 0;
770
771     while (HTMLElement* nextList = enclosingList(list)) {
772         if (nextList == rootList)
773             break;
774         list = nextList;
775     }
776
777     return list;
778 }
779
780 bool canMergeLists(Element* firstList, Element* secondList)
781 {
782     if (!firstList || !secondList || !firstList->isHTMLElement() || !secondList->isHTMLElement())
783         return false;
784
785     return firstList->hasTagName(secondList->tagQName()) // make sure the list types match (ol vs. ul)
786     && firstList->hasEditableStyle() && secondList->hasEditableStyle() // both lists are editable
787     && firstList->rootEditableElement() == secondList->rootEditableElement() // don't cross editing boundaries
788     && isVisiblyAdjacent(positionInParentAfterNode(firstList), positionInParentBeforeNode(secondList));
789     // Make sure there is no visible content between this li and the previous list
790 }
791
792 Node* highestAncestor(Node* node)
793 {
794     ASSERT(node);
795     Node* parent = node;
796     while ((node = node->parentNode()))
797         parent = node;
798     return parent;
799 }
800
801 static Node* previousNodeConsideringAtomicNodes(const Node* node)
802 {
803     if (node->previousSibling()) {
804         Node* n = node->previousSibling();
805         while (!isAtomicNode(n) && n->lastChild())
806             n = n->lastChild();
807         return n;
808     }
809     if (node->parentNode())
810         return node->parentNode();
811     return 0;
812 }
813
814 static Node* nextNodeConsideringAtomicNodes(const Node* node)
815 {
816     if (!isAtomicNode(node) && node->firstChild())
817         return node->firstChild();
818     if (node->nextSibling())
819         return node->nextSibling();
820     const Node* n = node;
821     while (n && !n->nextSibling())
822         n = n->parentNode();
823     if (n)
824         return n->nextSibling();
825     return 0;
826 }
827
828 Node* previousLeafNode(const Node* node)
829 {
830     Node* n = previousNodeConsideringAtomicNodes(node);
831     while (n) {
832         if (isAtomicNode(n))
833             return n;
834         n = previousNodeConsideringAtomicNodes(n);
835     }
836     return 0;
837 }
838
839 Node* nextLeafNode(const Node* node)
840 {
841     Node* n = nextNodeConsideringAtomicNodes(node);
842     while (n) {
843         if (isAtomicNode(n))
844             return n;
845         n = nextNodeConsideringAtomicNodes(n);
846     }
847     return 0;
848 }
849
850 // FIXME: do not require renderer, so that this can be used within fragments
851 bool isRenderedTable(const Node* n)
852 {
853     if (!n || !n->isElementNode())
854         return false;
855
856     RenderObject* renderer = n->renderer();
857     return (renderer && renderer->isTable());
858 }
859
860 bool isTableCell(const Node* node)
861 {
862     RenderObject* r = node->renderer();
863     if (!r)
864         return node->hasTagName(tdTag) || node->hasTagName(thTag);
865     
866     return r->isTableCell();
867 }
868
869 bool isEmptyTableCell(const Node* node)
870 {
871     // Returns true IFF the passed in node is one of:
872     //   .) a table cell with no children,
873     //   .) a table cell with a single BR child, and which has no other child renderers, including :before and :after renderers
874     //   .) the BR child of such a table cell
875
876     // Find rendered node
877     while (node && !node->renderer())
878         node = node->parentNode();
879     if (!node)
880         return false;
881
882     // Make sure the rendered node is a table cell or <br>.
883     // If it's a <br>, then the parent node has to be a table cell.
884     RenderObject* renderer = node->renderer();
885     if (renderer->isBR()) {
886         renderer = renderer->parent();
887         if (!renderer)
888             return false;
889     }
890     if (!is<RenderTableCell>(*renderer))
891         return false;
892
893     // Check that the table cell contains no child renderers except for perhaps a single <br>.
894     RenderObject* childRenderer = downcast<RenderTableCell>(*renderer).firstChild();
895     if (!childRenderer)
896         return true;
897     if (!childRenderer->isBR())
898         return false;
899     return !childRenderer->nextSibling();
900 }
901
902 PassRefPtr<HTMLElement> createDefaultParagraphElement(Document& document)
903 {
904     switch (document.frame()->editor().defaultParagraphSeparator()) {
905     case EditorParagraphSeparatorIsDiv:
906         return HTMLDivElement::create(document);
907     case EditorParagraphSeparatorIsP:
908         return HTMLParagraphElement::create(document);
909     }
910
911     ASSERT_NOT_REACHED();
912     return 0;
913 }
914
915 PassRefPtr<HTMLElement> createBreakElement(Document& document)
916 {
917     return HTMLBRElement::create(document);
918 }
919
920 PassRefPtr<HTMLElement> createOrderedListElement(Document& document)
921 {
922     return HTMLOListElement::create(document);
923 }
924
925 PassRefPtr<HTMLElement> createUnorderedListElement(Document& document)
926 {
927     return HTMLUListElement::create(document);
928 }
929
930 PassRefPtr<HTMLElement> createListItemElement(Document& document)
931 {
932     return HTMLLIElement::create(document);
933 }
934
935 Ref<HTMLElement> createHTMLElement(Document& document, const QualifiedName& name)
936 {
937     return HTMLElementFactory::createElement(name, document);
938 }
939
940 Ref<HTMLElement> createHTMLElement(Document& document, const AtomicString& tagName)
941 {
942     return createHTMLElement(document, QualifiedName(nullAtom, tagName, xhtmlNamespaceURI));
943 }
944
945 bool isTabSpanNode(const Node *node)
946 {
947     return node && node->hasTagName(spanTag) && node->isElementNode() && static_cast<const Element *>(node)->getAttribute(classAttr) == AppleTabSpanClass;
948 }
949
950 bool isTabSpanTextNode(const Node *node)
951 {
952     return node && node->isTextNode() && node->parentNode() && isTabSpanNode(node->parentNode());
953 }
954
955 Node* tabSpanNode(const Node *node)
956 {
957     return isTabSpanTextNode(node) ? node->parentNode() : 0;
958 }
959     
960 Position positionOutsideTabSpan(const Position& pos)
961 {
962     Node* node = pos.containerNode();
963     if (isTabSpanTextNode(node))
964         node = tabSpanNode(node);
965     else if (!isTabSpanNode(node))
966         return pos;
967
968     if (node && VisiblePosition(pos) == lastPositionInNode(node))
969         return positionInParentAfterNode(node);
970
971     return positionInParentBeforeNode(node);
972 }
973
974 PassRefPtr<Element> createTabSpanElement(Document& document, PassRefPtr<Node> prpTabTextNode)
975 {
976     RefPtr<Node> tabTextNode = prpTabTextNode;
977
978     // Make the span to hold the tab.
979     RefPtr<Element> spanElement = document.createElement(spanTag, false);
980     spanElement->setAttribute(classAttr, AppleTabSpanClass);
981     spanElement->setAttribute(styleAttr, "white-space:pre");
982
983     // Add tab text to that span.
984     if (!tabTextNode)
985         tabTextNode = document.createEditingTextNode("\t");
986
987     spanElement->appendChild(tabTextNode.release(), ASSERT_NO_EXCEPTION);
988
989     return spanElement.release();
990 }
991
992 PassRefPtr<Element> createTabSpanElement(Document& document, const String& tabText)
993 {
994     return createTabSpanElement(document, document.createTextNode(tabText));
995 }
996
997 PassRefPtr<Element> createTabSpanElement(Document& document)
998 {
999     return createTabSpanElement(document, PassRefPtr<Node>());
1000 }
1001
1002 bool isNodeRendered(const Node* node)
1003 {
1004     if (!node)
1005         return false;
1006
1007     RenderObject* renderer = node->renderer();
1008     if (!renderer)
1009         return false;
1010
1011     return renderer->style().visibility() == VISIBLE;
1012 }
1013
1014 unsigned numEnclosingMailBlockquotes(const Position& p)
1015 {
1016     unsigned num = 0;
1017     for (Node* n = p.deprecatedNode(); n; n = n->parentNode())
1018         if (isMailBlockquote(n))
1019             num++;
1020     
1021     return num;
1022 }
1023
1024 void updatePositionForNodeRemoval(Position& position, Node& node)
1025 {
1026     if (position.isNull())
1027         return;
1028     switch (position.anchorType()) {
1029     case Position::PositionIsBeforeChildren:
1030         if (node.containsIncludingShadowDOM(position.containerNode()))
1031             position = positionInParentBeforeNode(&node);
1032         break;
1033     case Position::PositionIsAfterChildren:
1034         if (node.containsIncludingShadowDOM(position.containerNode()))
1035             position = positionInParentBeforeNode(&node);
1036         break;
1037     case Position::PositionIsOffsetInAnchor:
1038         if (position.containerNode() == node.parentNode() && static_cast<unsigned>(position.offsetInContainerNode()) > node.computeNodeIndex())
1039             position.moveToOffset(position.offsetInContainerNode() - 1);
1040         else if (node.containsIncludingShadowDOM(position.containerNode()))
1041             position = positionInParentBeforeNode(&node);
1042         break;
1043     case Position::PositionIsAfterAnchor:
1044         if (node.containsIncludingShadowDOM(position.anchorNode()))
1045             position = positionInParentAfterNode(&node);
1046         break;
1047     case Position::PositionIsBeforeAnchor:
1048         if (node.containsIncludingShadowDOM(position.anchorNode()))
1049             position = positionInParentBeforeNode(&node);
1050         break;
1051     }
1052 }
1053
1054 bool isMailBlockquote(const Node *node)
1055 {
1056     if (!node || !node->hasTagName(blockquoteTag))
1057         return false;
1058         
1059     return static_cast<const Element *>(node)->getAttribute("type") == "cite";
1060 }
1061
1062 int caretMinOffset(const Node* n)
1063 {
1064     RenderObject* r = n->renderer();
1065     ASSERT(!n->isCharacterDataNode() || !r || r->isText()); // FIXME: This was a runtime check that seemingly couldn't fail; changed it to an assertion for now.
1066     return r ? r->caretMinOffset() : 0;
1067 }
1068
1069 // If a node can contain candidates for VisiblePositions, return the offset of the last candidate, otherwise 
1070 // return the number of children for container nodes and the length for unrendered text nodes.
1071 int caretMaxOffset(const Node* n)
1072 {
1073     // For rendered text nodes, return the last position that a caret could occupy.
1074     if (n->isTextNode() && n->renderer())
1075         return n->renderer()->caretMaxOffset();
1076     // For containers return the number of children. For others do the same as above.
1077     return lastOffsetForEditing(n);
1078 }
1079
1080 bool lineBreakExistsAtVisiblePosition(const VisiblePosition& visiblePosition)
1081 {
1082     return lineBreakExistsAtPosition(visiblePosition.deepEquivalent().downstream());
1083 }
1084
1085 bool lineBreakExistsAtPosition(const Position& position)
1086 {
1087     if (position.isNull())
1088         return false;
1089     
1090     if (position.anchorNode()->hasTagName(brTag) && position.atFirstEditingPositionForNode())
1091         return true;
1092     
1093     if (!position.anchorNode()->renderer())
1094         return false;
1095     
1096     if (!is<Text>(*position.anchorNode()) || !position.anchorNode()->renderer()->style().preserveNewline())
1097         return false;
1098     
1099     Text& textNode = downcast<Text>(*position.anchorNode());
1100     unsigned offset = position.offsetInContainerNode();
1101     return offset < textNode.length() && textNode.data()[offset] == '\n';
1102 }
1103
1104 // Modifies selections that have an end point at the edge of a table
1105 // that contains the other endpoint so that they don't confuse
1106 // code that iterates over selected paragraphs.
1107 VisibleSelection selectionForParagraphIteration(const VisibleSelection& original)
1108 {
1109     VisibleSelection newSelection(original);
1110     VisiblePosition startOfSelection(newSelection.visibleStart());
1111     VisiblePosition endOfSelection(newSelection.visibleEnd());
1112     
1113     // If the end of the selection to modify is just after a table, and
1114     // if the start of the selection is inside that table, then the last paragraph
1115     // that we'll want modify is the last one inside the table, not the table itself
1116     // (a table is itself a paragraph).
1117     if (Node* table = isFirstPositionAfterTable(endOfSelection))
1118         if (startOfSelection.deepEquivalent().deprecatedNode()->isDescendantOf(table))
1119             newSelection = VisibleSelection(startOfSelection, endOfSelection.previous(CannotCrossEditingBoundary));
1120     
1121     // If the start of the selection to modify is just before a table,
1122     // and if the end of the selection is inside that table, then the first paragraph
1123     // we'll want to modify is the first one inside the table, not the paragraph
1124     // containing the table itself.
1125     if (Node* table = isLastPositionBeforeTable(startOfSelection))
1126         if (endOfSelection.deepEquivalent().deprecatedNode()->isDescendantOf(table))
1127             newSelection = VisibleSelection(startOfSelection.next(CannotCrossEditingBoundary), endOfSelection);
1128     
1129     return newSelection;
1130 }
1131
1132 // FIXME: indexForVisiblePosition and visiblePositionForIndex use TextIterators to convert between 
1133 // VisiblePositions and indices. But TextIterator iteration using TextIteratorEmitsCharactersBetweenAllVisiblePositions 
1134 // does not exactly match VisiblePosition iteration, so using them to preserve a selection during an editing 
1135 // opertion is unreliable. TextIterator's TextIteratorEmitsCharactersBetweenAllVisiblePositions mode needs to be fixed, 
1136 // or these functions need to be changed to iterate using actual VisiblePositions.
1137 // FIXME: Deploy these functions everywhere that TextIterators are used to convert between VisiblePositions and indices.
1138 int indexForVisiblePosition(const VisiblePosition& visiblePosition, RefPtr<ContainerNode>& scope)
1139 {
1140     if (visiblePosition.isNull())
1141         return 0;
1142
1143     Position p(visiblePosition.deepEquivalent());
1144     Document& document = p.anchorNode()->document();
1145     ShadowRoot* shadowRoot = p.anchorNode()->containingShadowRoot();
1146
1147     if (shadowRoot)
1148         scope = shadowRoot;
1149     else
1150         scope = document.documentElement();
1151
1152     RefPtr<Range> range = Range::create(document, firstPositionInNode(scope.get()), p.parentAnchoredEquivalent());
1153     return TextIterator::rangeLength(range.get(), true);
1154 }
1155
1156 // FIXME: Merge these two functions.
1157 int indexForVisiblePosition(Node* node, const VisiblePosition& visiblePosition, bool forSelectionPreservation)
1158 {
1159     ASSERT(node);
1160     RefPtr<Range> range = Range::create(node->document(), firstPositionInNode(node), visiblePosition.deepEquivalent().parentAnchoredEquivalent());
1161     return TextIterator::rangeLength(range.get(), forSelectionPreservation);
1162 }
1163
1164 VisiblePosition visiblePositionForIndex(int index, ContainerNode* scope)
1165 {
1166     RefPtr<Range> range = TextIterator::rangeFromLocationAndLength(scope, index, 0, true);
1167     // Check for an invalid index. Certain editing operations invalidate indices because 
1168     // of problems with TextIteratorEmitsCharactersBetweenAllVisiblePositions.
1169     if (!range)
1170         return VisiblePosition();
1171     return VisiblePosition(range->startPosition());
1172 }
1173
1174 VisiblePosition visiblePositionForIndexUsingCharacterIterator(Node* node, int index)
1175 {
1176     ASSERT(node);
1177     if (index <= 0)
1178         return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
1179
1180     RefPtr<Range> range = Range::create(node->document());
1181     range->selectNodeContents(node, IGNORE_EXCEPTION);
1182     CharacterIterator it(*range);
1183     it.advance(index - 1);
1184     return VisiblePosition(it.atEnd() ? range->endPosition() : it.range()->endPosition(), UPSTREAM);
1185 }
1186
1187 // Determines whether two positions are visibly next to each other (first then second)
1188 // while ignoring whitespaces and unrendered nodes
1189 bool isVisiblyAdjacent(const Position& first, const Position& second)
1190 {
1191     return VisiblePosition(first) == VisiblePosition(second.upstream());
1192 }
1193
1194 // Determines whether a node is inside a range or visibly starts and ends at the boundaries of the range.
1195 // Call this function to determine whether a node is visibly fit inside selectedRange
1196 bool isNodeVisiblyContainedWithin(Node* node, const Range* selectedRange)
1197 {
1198     ASSERT(node);
1199     ASSERT(selectedRange);
1200     // If the node is inside the range, then it surely is contained within
1201     if (selectedRange->compareNode(node, IGNORE_EXCEPTION) == Range::NODE_INSIDE)
1202         return true;
1203
1204     bool startIsVisuallySame = visiblePositionBeforeNode(node) == selectedRange->startPosition();
1205     if (startIsVisuallySame && comparePositions(positionInParentAfterNode(node), selectedRange->endPosition()) < 0)
1206         return true;
1207
1208     bool endIsVisuallySame = visiblePositionAfterNode(node) == selectedRange->endPosition();
1209     if (endIsVisuallySame && comparePositions(selectedRange->startPosition(), positionInParentBeforeNode(node)) < 0)
1210         return true;
1211
1212     return startIsVisuallySame && endIsVisuallySame;
1213 }
1214
1215 bool isRenderedAsNonInlineTableImageOrHR(const Node* node)
1216 {
1217     if (!node)
1218         return false;
1219     RenderObject* renderer = node->renderer();
1220     return renderer && ((renderer->isTable() && !renderer->isInline()) || (renderer->isImage() && !renderer->isInline()) || renderer->isHR());
1221 }
1222
1223 bool areIdenticalElements(const Node* first, const Node* second)
1224 {
1225     if (!is<Element>(*first) || !is<Element>(*second))
1226         return false;
1227
1228     const Element& firstElement = downcast<Element>(*first);
1229     const Element& secondElement = downcast<Element>(*second);
1230     if (!firstElement.hasTagName(secondElement.tagQName()))
1231         return false;
1232
1233     return firstElement.hasEquivalentAttributes(&secondElement);
1234 }
1235
1236 bool isNonTableCellHTMLBlockElement(const Node* node)
1237 {
1238     return node->hasTagName(listingTag)
1239         || node->hasTagName(olTag)
1240         || node->hasTagName(preTag)
1241         || is<HTMLTableElement>(*node)
1242         || node->hasTagName(ulTag)
1243         || node->hasTagName(xmpTag)
1244         || node->hasTagName(h1Tag)
1245         || node->hasTagName(h2Tag)
1246         || node->hasTagName(h3Tag)
1247         || node->hasTagName(h4Tag)
1248         || node->hasTagName(h5Tag);
1249 }
1250
1251 Position adjustedSelectionStartForStyleComputation(const VisibleSelection& selection)
1252 {
1253     // This function is used by range style computations to avoid bugs like:
1254     // <rdar://problem/4017641> REGRESSION (Mail): you can only bold/unbold a selection starting from end of line once
1255     // It is important to skip certain irrelevant content at the start of the selection, so we do not wind up 
1256     // with a spurious "mixed" style.
1257
1258     VisiblePosition visiblePosition = selection.start();
1259     if (visiblePosition.isNull())
1260         return Position();
1261
1262     // if the selection is a caret, just return the position, since the style
1263     // behind us is relevant
1264     if (selection.isCaret())
1265         return visiblePosition.deepEquivalent();
1266
1267     // if the selection starts just before a paragraph break, skip over it
1268     if (isEndOfParagraph(visiblePosition))
1269         return visiblePosition.next().deepEquivalent().downstream();
1270
1271     // otherwise, make sure to be at the start of the first selected node,
1272     // instead of possibly at the end of the last node before the selection
1273     return visiblePosition.deepEquivalent().downstream();
1274 }
1275
1276 // FIXME: Should this be deprecated like deprecatedEnclosingBlockFlowElement is?
1277 bool isBlockFlowElement(const Node* node)
1278 {
1279     if (!node->isElementNode())
1280         return false;
1281     RenderObject* renderer = node->renderer();
1282     return renderer && renderer->isRenderBlockFlow();
1283 }
1284
1285 Element* deprecatedEnclosingBlockFlowElement(Node* node)
1286 {
1287     if (!node)
1288         return nullptr;
1289     if (isBlockFlowElement(node))
1290         return downcast<Element>(node);
1291     while ((node = node->parentNode())) {
1292         if (isBlockFlowElement(node) || is<HTMLBodyElement>(*node))
1293             return downcast<Element>(node);
1294     }
1295     return nullptr;
1296 }
1297
1298 static inline bool caretRendersInsideNode(Node* node)
1299 {
1300     return node && !isRenderedTable(node) && !editingIgnoresContent(node);
1301 }
1302
1303 RenderBlock* rendererForCaretPainting(Node* node)
1304 {
1305     if (!node)
1306         return nullptr;
1307
1308     RenderObject* renderer = node->renderer();
1309     if (!renderer)
1310         return nullptr;
1311
1312     // If caretNode is a block and caret is inside it, then caret should be painted by that block.
1313     bool paintedByBlock = is<RenderBlockFlow>(*renderer) && caretRendersInsideNode(node);
1314     return paintedByBlock ? downcast<RenderBlock>(renderer) : renderer->containingBlock();
1315 }
1316
1317 LayoutRect localCaretRectInRendererForCaretPainting(const VisiblePosition& caretPosition, RenderBlock*& caretPainter)
1318 {
1319     if (caretPosition.isNull())
1320         return LayoutRect();
1321
1322     ASSERT(caretPosition.deepEquivalent().deprecatedNode()->renderer());
1323
1324     // First compute a rect local to the renderer at the selection start.
1325     RenderObject* renderer;
1326     LayoutRect localRect = caretPosition.localCaretRect(renderer);
1327
1328     // Get the renderer that will be responsible for painting the caret
1329     // (which is either the renderer we just found, or one of its containers).
1330     caretPainter = rendererForCaretPainting(caretPosition.deepEquivalent().deprecatedNode());
1331
1332     // Compute an offset between the renderer and the caretPainter.
1333     while (renderer != caretPainter) {
1334         RenderElement* containerObject = renderer->container();
1335         if (!containerObject)
1336             return LayoutRect();
1337         localRect.move(renderer->offsetFromContainer(*containerObject, localRect.location()));
1338         renderer = containerObject;
1339     }
1340
1341     return localRect;
1342 }
1343
1344 IntRect absoluteBoundsForLocalCaretRect(RenderBlock* rendererForCaretPainting, const LayoutRect& rect)
1345 {
1346     if (!rendererForCaretPainting || rect.isEmpty())
1347         return IntRect();
1348
1349     LayoutRect localRect(rect);
1350     rendererForCaretPainting->flipForWritingMode(localRect);
1351     return rendererForCaretPainting->localToAbsoluteQuad(FloatRect(localRect)).enclosingBoundingBox();
1352 }
1353
1354 } // namespace WebCore