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