f25cfa3bae4533369a5560b3adf39461659b8741
[WebKit-https.git] / WebCore / khtml / xml / dom_position.cpp
1 /*
2  * Copyright (C) 2004 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "dom_position.h"
27
28 #include "helper.h"
29 #include "htmltags.h"
30 #include "qstring.h"
31 #include "rendering/render_block.h"
32 #include "rendering/render_line.h"
33 #include "rendering/render_object.h"
34 #include "rendering/render_style.h"
35 #include "rendering/render_text.h"
36 #include "xml/dom_edititerator.h"
37 #include "xml/dom_nodeimpl.h"
38
39 #if APPLE_CHANGES
40 #include "KWQAssertions.h"
41 #include "KWQLogging.h"
42 #endif
43
44 using DOM::DOMPosition;
45 using DOM::EditIterator;
46 using DOM::NodeImpl;
47 using khtml::InlineBox;
48 using khtml::InlineFlowBox;
49 using khtml::InlineTextBox;
50 using khtml::RenderBlock;
51 using khtml::RenderObject;
52 using khtml::RenderText;
53 using khtml::RootInlineBox;
54
55 #if !APPLE_CHANGES
56 #define ASSERT(assertion) ((void)0)
57 #define ASSERT_WITH_MESSAGE(assertion, formatAndArgs...) ((void)0)
58 #define ASSERT_NOT_REACHED() ((void)0)
59 #define LOG(channel, formatAndArgs...) ((void)0)
60 #define ERROR(formatAndArgs...) ((void)0)
61 #endif
62
63 static InlineBox *inlineBoxForRenderer(RenderObject *renderer, long offset)
64 {
65     if (!renderer)
66         return 0;
67
68     if (renderer->isBR() && static_cast<RenderText *>(renderer)->firstTextBox())
69         return static_cast<RenderText *>(renderer)->firstTextBox();
70     
71     if (renderer->isText()) {
72         RenderText *textRenderer = static_cast<khtml::RenderText *>(renderer); 
73         if (textRenderer->isBR() && textRenderer->firstTextBox())
74             return textRenderer->firstTextBox();
75         
76         for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
77             if (offset >= box->m_start && offset <= box->m_start + box->m_len) {
78                 return box;
79             }
80             else if (offset < box->m_start) {
81                 // The offset we're looking for is before this node
82                 // this means the offset must be in content that is
83                 // not rendered.
84                 return box->prevTextBox() ? box->prevTextBox() : textRenderer->firstTextBox();
85             }
86         }
87     }
88     else {
89         return renderer->inlineBoxWrapper();
90     } 
91     
92     return 0;
93 }
94
95 static bool renderersOnDifferentLine(RenderObject *r1, long o1, RenderObject *r2, long o2)
96 {
97     InlineBox *b1 = inlineBoxForRenderer(r1, o1);
98     InlineBox *b2 = inlineBoxForRenderer(r2, o2);
99     return (b1 && b2 && b1->root() != b2->root());
100 }
101
102 static NodeImpl *nextRenderedEditable(NodeImpl *node)
103 {
104     while (1) {
105         node = node->nextEditable();
106         if (!node)
107             return 0;
108         if (inlineBoxForRenderer(node->renderer(), 0))
109             return node;
110     }
111     return 0;
112 }
113
114 static NodeImpl *previousRenderedEditable(NodeImpl *node)
115 {
116     while (1) {
117         node = node->previousEditable();
118         if (!node)
119             return 0;
120         if (inlineBoxForRenderer(node->renderer(), 0))
121             return node;
122     }
123     return 0;
124 }
125
126
127 DOMPosition::DOMPosition(NodeImpl *node, long offset) 
128     : m_node(0), m_offset(offset) 
129
130     if (node) {
131         m_node = node;
132         m_node->ref();
133     }
134 };
135
136 DOMPosition::DOMPosition(const DOMPosition &o)
137     : m_node(0), m_offset(o.offset()) 
138 {
139     if (o.node()) {
140         m_node = o.node();
141         m_node->ref();
142     }
143 }
144
145 DOMPosition::~DOMPosition() {
146     if (m_node) {
147         m_node->deref();
148     }
149 }
150
151 DOMPosition &DOMPosition::operator=(const DOMPosition &o)
152 {
153     if (m_node) {
154         m_node->deref();
155     }
156     m_node = o.node();
157     if (m_node) {
158         m_node->ref();
159     }
160
161     m_offset = o.offset();
162     
163     return *this;
164 }
165
166 long DOMPosition::renderedOffset() const
167 {
168     if (!node()->isTextNode())
169         return offset();
170    
171     if (!node()->renderer())
172         return offset();
173                     
174     long result = 0;
175     RenderText *textRenderer = static_cast<RenderText *>(node()->renderer());
176     for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
177         long start = box->m_start;
178         long end = box->m_start + box->m_len;
179         if (offset() < start)
180             return result;
181         if (offset() <= end) {
182             result += offset() - start;
183             return result;
184         }
185         result += box->m_len;
186     }
187     return result;
188 }
189
190 DOMPosition DOMPosition::equivalentLeafPosition() const
191 {
192     if (node()->hasChildNodes() == false)
193         return *this;
194     
195     NodeImpl *n = node();
196     int count = 0;
197     while (1) {
198         n = n->nextLeafNode();
199         if (!n)
200             return *this;
201         if (count + n->maxOffset() >= offset()) {
202             count = offset() - count;
203             break;
204         }
205         count += n->maxOffset();
206     }
207     return DOMPosition(n, count);
208 }
209
210 DOMPosition DOMPosition::previousRenderedEditablePosition() const
211 {
212     if (isEmpty())
213         return DOMPosition();
214
215     if (node()->isContentEditable() && node()->hasChildNodes() == false && inRenderedContent())
216         return *this;
217
218     NodeImpl *n = node();
219     while (1) {
220         n = n->previousEditable();
221         if (!n)
222             return DOMPosition();
223         if (n->renderer() && n->renderer()->style()->visibility() == khtml::VISIBLE)
224             break;
225     }
226     
227     return DOMPosition(n, 0);
228 }
229
230 DOMPosition DOMPosition::nextRenderedEditablePosition() const
231 {
232     if (isEmpty())
233         return DOMPosition();
234
235     if (node()->isContentEditable() && node()->hasChildNodes() == false && inRenderedContent())
236         return *this;
237
238     NodeImpl *n = node();
239     while (1) {
240         n = n->nextEditable();
241         if (!n)
242             return DOMPosition();
243         if (n->renderer() && n->renderer()->style()->visibility() == khtml::VISIBLE)
244             break;
245     }
246     
247     return DOMPosition(n, 0);
248 }
249
250 DOMPosition DOMPosition::previousCharacterPosition() const
251 {
252     if (isEmpty())
253         return DOMPosition();
254
255     NodeImpl *fromRootEditableBlock = node()->rootEditableBlock();
256     EditIterator it(*this);
257
258     bool atStartOfLine = isFirstRenderedPositionOnLine();
259     
260     while (!it.atStart()) {
261         DOMPosition pos = it.previous();
262
263         if (pos.node()->rootEditableBlock() != fromRootEditableBlock)
264             return *this;
265
266         if (atStartOfLine) {
267             if (pos.inRenderedContent())
268                 return pos;
269         }
270         else if (rendersInDifferentPosition(pos))
271             return pos;
272     }
273     
274     return *this;
275 }
276
277 DOMPosition DOMPosition::nextCharacterPosition() const
278 {
279     if (isEmpty())
280         return DOMPosition();
281
282     NodeImpl *fromRootEditableBlock = node()->rootEditableBlock();
283     EditIterator it(*this);
284
285     bool atEndOfLine = isLastRenderedPositionOnLine();
286     
287     while (!it.atEnd()) {
288         DOMPosition pos = it.next();
289
290         if (pos.node()->rootEditableBlock() != fromRootEditableBlock)
291             return *this;
292
293         if (atEndOfLine) {
294             if (pos.inRenderedContent())
295                 return pos;
296         }
297         else if (rendersInDifferentPosition(pos))
298             return pos;
299     }
300     
301     return *this;
302 }
303
304 DOMPosition DOMPosition::previousWordPosition() const
305 {
306     if (isEmpty())
307         return DOMPosition();
308
309     DOMPosition pos = *this;
310     for (EditIterator it(*this); !it.atStart(); it.previous()) {
311         if (it.current().node()->nodeType() == Node::TEXT_NODE || it.current().node()->nodeType() == Node::CDATA_SECTION_NODE) {
312             DOMString t = it.current().node()->nodeValue();
313             QChar *chars = t.unicode();
314             uint len = t.length();
315             int start, end;
316             khtml::findWordBoundary(chars, len, it.current().offset(), &start, &end);
317             pos = DOMPosition(it.current().node(), start);
318         }
319         else {
320             pos = DOMPosition(it.current().node(), it.current().node()->caretMinOffset());
321         }
322         if (pos != *this)
323             return pos;
324         it.setPosition(pos);
325     }
326     
327     return *this;
328 }
329
330 DOMPosition DOMPosition::nextWordPosition() const
331 {
332     if (isEmpty())
333         return DOMPosition();
334
335     DOMPosition pos = *this;
336     for (EditIterator it(*this); !it.atEnd(); it.next()) {
337         if (it.current().node()->nodeType() == Node::TEXT_NODE || it.current().node()->nodeType() == Node::CDATA_SECTION_NODE) {
338             DOMString t = it.current().node()->nodeValue();
339             QChar *chars = t.unicode();
340             uint len = t.length();
341             int start, end;
342             khtml::findWordBoundary(chars, len, it.current().offset(), &start, &end);
343             pos = DOMPosition(it.current().node(), end);
344         }
345         else {
346             pos = DOMPosition(it.current().node(), it.current().node()->caretMaxOffset());
347         }
348         if (pos != *this)
349             return pos;
350         it.setPosition(pos);
351     }
352     
353     return *this;
354 }
355
356 DOMPosition DOMPosition::previousLinePosition(int x) const
357 {
358     if (!node())
359         return DOMPosition();
360
361     if (!node()->renderer())
362         return *this;
363
364     InlineBox *box = inlineBoxForRenderer(node()->renderer(), offset());
365     if (!box)
366         return *this;
367
368     RenderBlock *containingBlock = 0;
369     RootInlineBox *root = box->root()->prevRootBox();
370     if (root) {
371         containingBlock = node()->renderer()->containingBlock();
372     }
373     else {
374         // This containing editable block does not have a previous line.
375         // Need to move back to previous containing editable block in this root editable
376         // block and find the last root line box in that block.
377         NodeImpl *startBlock = node()->containingEditableBlock();
378         NodeImpl *n = node()->previousEditable();
379         while (n && startBlock == n->containingEditableBlock())
380             n = n->previousEditable();
381         if (n) {
382             while (n && !DOMPosition(n, n->caretMaxOffset()).inRenderedContent())
383                 n = n->previousEditable();
384             if (n && n->inSameRootEditableBlock(node())) {
385                 box = inlineBoxForRenderer(n->renderer(), n->caretMaxOffset());
386                 ASSERT(box);
387                 // previous root line box found
388                 root = box->root();
389                 containingBlock = n->renderer()->containingBlock();
390             }
391         }
392     }
393     
394     if (root) {
395         int absx, absy;
396         containingBlock->absolutePosition(absx, absy);
397         RenderObject *renderer = root->closestLeafChildForXPos(x, absx)->object();
398         return renderer->positionForCoordinates(x, absy + root->topOverflow());
399     }
400     
401     return *this;
402 }
403
404 DOMPosition DOMPosition::nextLinePosition(int x) const
405 {
406     if (!node())
407         return DOMPosition();
408
409     if (!node()->renderer())
410         return *this;
411
412     InlineBox *box = inlineBoxForRenderer(node()->renderer(), offset());
413     if (!box)
414         return *this;
415
416     RenderBlock *containingBlock = 0;
417     RootInlineBox *root = box->root()->nextRootBox();
418     if (root) {
419         containingBlock = node()->renderer()->containingBlock();
420     }
421     else {
422         // This containing editable block does not have a next line.
423         // Need to move forward to next containing editable block in this root editable
424         // block and find the first root line box in that block.
425         NodeImpl *startBlock = node()->containingEditableBlock();
426         NodeImpl *n = node()->nextEditable();
427         while (n && startBlock == n->containingEditableBlock())
428             n = n->nextEditable();
429         if (n) {
430             while (n && !DOMPosition(n, n->caretMinOffset()).inRenderedContent())
431                 n = n->nextEditable();
432             if (n && n->inSameRootEditableBlock(node())) {
433                 box = inlineBoxForRenderer(n->renderer(), n->caretMinOffset());
434                 ASSERT(box);
435                 // previous root line box found
436                 root = box->root();
437                 containingBlock = n->renderer()->containingBlock();
438             }
439         }
440     }
441     
442     if (root) {
443         int absx, absy;
444         containingBlock->absolutePosition(absx, absy);
445         RenderObject *renderer = root->closestLeafChildForXPos(x, absx)->object();
446         return renderer->positionForCoordinates(x, absy + root->topOverflow());
447     }
448
449     return *this;
450 }
451
452 DOMPosition DOMPosition::equivalentUpstreamPosition() const
453 {
454     if (!node())
455         return DOMPosition();
456
457     NodeImpl *block = node()->containingEditableBlock();
458     
459     EditIterator it(*this);            
460     for (; !it.atStart(); it.previous()) {   
461         if (block != it.current().node()->containingEditableBlock())
462             return it.next();
463
464         if (!node()->isContentEditable())
465             return it.next();
466             
467         RenderObject *renderer = it.current().node()->renderer();
468         if (!renderer)
469             continue;
470
471         if (renderer->style()->visibility() != khtml::VISIBLE)
472             continue;
473
474         if (renderer->isBlockFlow() || renderer->isReplaced() || renderer->isBR()) {
475             if (it.current().offset() >= renderer->caretMaxOffset())
476                 return DOMPosition(it.current().node(), renderer->caretMaxOffset());
477             else
478                 continue;
479         }
480
481         if (renderer->isText() && static_cast<RenderText *>(renderer)->firstTextBox()) {
482             if (it.current().node() != node())
483                 return DOMPosition(it.current().node(), renderer->caretMaxOffset());
484
485             if (it.current().offset() < 0)
486                 continue;
487             uint textOffset = it.current().offset();
488
489             RenderText *textRenderer = static_cast<RenderText *>(renderer);
490             for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
491                 if (textOffset > box->start() && textOffset <= box->start() + box->len())
492                     return it.current();
493             }
494         }
495     }
496     
497     return it.current();
498 }
499
500 DOMPosition DOMPosition::equivalentDownstreamPosition() const
501 {
502     if (!node())
503         return DOMPosition();
504
505     NodeImpl *block = node()->containingEditableBlock();
506     
507     EditIterator it(*this);            
508     for (; !it.atEnd(); it.next()) {   
509         if (block != it.current().node()->containingEditableBlock())
510             return it.previous();
511
512         if (!node()->isContentEditable())
513             return it.next();
514             
515         RenderObject *renderer = it.current().node()->renderer();
516         if (!renderer)
517             continue;
518
519         if (renderer->style()->visibility() != khtml::VISIBLE)
520             continue;
521
522         if (renderer->isBlockFlow() || renderer->isReplaced() || renderer->isBR()) {
523             if (it.current().offset() <= renderer->caretMinOffset())
524                 return DOMPosition(it.current().node(), renderer->caretMinOffset());
525             else
526                 continue;
527         }
528
529         if (renderer->isText() && static_cast<RenderText *>(renderer)->firstTextBox()) {
530             if (it.current().node() != node())
531                 return DOMPosition(it.current().node(), renderer->caretMinOffset());
532
533             if (it.current().offset() < 0)
534                 continue;
535             uint textOffset = it.current().offset();
536
537             RenderText *textRenderer = static_cast<RenderText *>(renderer);
538             for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
539                 if (textOffset >= box->start() && textOffset <= box->end())
540                     return it.current();
541             }
542         }
543     }
544     
545     return it.current();
546 }
547
548 bool DOMPosition::atStartOfContainingEditableBlock() const
549 {
550     return renderedOffset() == 0 && inFirstEditableInContainingEditableBlock();
551 }
552
553 bool DOMPosition::atStartOfRootEditableBlock() const
554 {
555     return renderedOffset() == 0 && inFirstEditableInRootEditableBlock();
556 }
557
558 bool DOMPosition::inRenderedContent() const
559 {
560     if (isEmpty())
561         return false;
562         
563     RenderObject *renderer = node()->renderer();
564     if (!renderer || !renderer->isEditable())
565         return false;
566     
567     if (renderer->style()->visibility() != khtml::VISIBLE)
568         return false;
569
570     if (renderer->isBR() && static_cast<RenderText *>(renderer)->firstTextBox()) {
571         return offset() == 0;
572     }
573     else if (renderer->isText()) {
574         RenderText *textRenderer = static_cast<RenderText *>(renderer);
575         for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
576             if (offset() >= box->m_start && offset() <= box->m_start + box->m_len) {
577                 return true;
578             }
579             else if (offset() < box->m_start) {
580                 // The offset we're looking for is before this node
581                 // this means the offset must be in content that is
582                 // not rendered. Return false.
583                 return false;
584             }
585         }
586     }
587     else if (offset() >= renderer->caretMinOffset() && offset() <= renderer->caretMaxOffset()) {
588         // don't return containing editable blocks unless they are empty
589         if (node()->containingEditableBlock() == node() && node()->firstChild())
590             return false;
591         return true;
592     }
593     
594     return false;
595 }
596
597 bool DOMPosition::inRenderedText() const
598 {
599     if (!node()->isTextNode())
600         return false;
601         
602     RenderObject *renderer = node()->renderer();
603     if (!renderer)
604         return false;
605     
606     RenderText *textRenderer = static_cast<RenderText *>(renderer);
607     for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
608         if (offset() < box->m_start) {
609             // The offset we're looking for is before this node
610             // this means the offset must be in content that is
611             // not rendered. Return false.
612             return false;
613         }
614         if (offset() >= box->m_start && offset() <= box->m_start + box->m_len)
615             return true;
616     }
617     
618     return false;
619 }
620
621 bool DOMPosition::rendersOnSameLine(const DOMPosition &pos) const
622 {
623     if (isEmpty() || pos.isEmpty())
624         return false;
625
626     if (node() == pos.node() && offset() == pos.offset())
627         return true;
628
629     if (node()->containingEditableBlock() != pos.node()->containingEditableBlock())
630         return false;
631
632     RenderObject *renderer = node()->renderer();
633     if (!renderer)
634         return false;
635     
636     RenderObject *posRenderer = pos.node()->renderer();
637     if (!posRenderer)
638         return false;
639
640     if (renderer->style()->visibility() != khtml::VISIBLE ||
641         posRenderer->style()->visibility() != khtml::VISIBLE)
642         return false;
643
644     return renderersOnDifferentLine(renderer, offset(), posRenderer, pos.offset());
645 }
646
647 bool DOMPosition::rendersInDifferentPosition(const DOMPosition &pos) const
648 {
649     if (isEmpty() || pos.isEmpty())
650         return false;
651
652     RenderObject *renderer = node()->renderer();
653     if (!renderer)
654         return false;
655     
656     RenderObject *posRenderer = pos.node()->renderer();
657     if (!posRenderer)
658         return false;
659
660     if (renderer->style()->visibility() != khtml::VISIBLE ||
661         posRenderer->style()->visibility() != khtml::VISIBLE)
662         return false;
663     
664     if (node() == pos.node()) {
665         if (node()->id() == ID_BR)
666             return false;
667
668         if (offset() == pos.offset())
669             return false;
670             
671         if (!node()->isTextNode() && !pos.node()->isTextNode()) {
672             if (offset() != pos.offset())
673                 return true;
674         }
675     }
676     
677     if (node()->id() == ID_BR && pos.inRenderedContent())
678         return true;
679                 
680     if (pos.node()->id() == ID_BR && inRenderedContent())
681         return true;
682                 
683     if (node()->containingEditableBlock() != pos.node()->containingEditableBlock())
684         return true;
685
686     if (node()->isTextNode() && !inRenderedText())
687         return false;
688
689     if (pos.node()->isTextNode() && !pos.inRenderedText())
690         return false;
691
692     long thisRenderedOffset = renderedOffset();
693     long posRenderedOffset = pos.renderedOffset();
694
695     if (renderer == posRenderer && thisRenderedOffset == posRenderedOffset)
696         return false;
697
698     LOG(Editing, "onDifferentLine:        %s\n", renderersOnDifferentLine(renderer, offset(), posRenderer, pos.offset()) ? "YES" : "NO");
699     LOG(Editing, "renderer:               %p [%p]\n", renderer, inlineBoxForRenderer(renderer, offset()));
700     LOG(Editing, "thisRenderedOffset:         %d\n", thisRenderedOffset);
701     LOG(Editing, "posRenderer:            %p [%p]\n", posRenderer, inlineBoxForRenderer(posRenderer, pos.offset()));
702     LOG(Editing, "posRenderedOffset:      %d\n", posRenderedOffset);
703     LOG(Editing, "node min/max:           %d:%d\n", node()->caretMinOffset(), node()->caretMaxRenderedOffset());
704     LOG(Editing, "pos node min/max:       %d:%d\n", pos.node()->caretMinOffset(), pos.node()->caretMaxRenderedOffset());
705     LOG(Editing, "----------------------------------------------------------------------\n");
706
707     InlineBox *b1 = inlineBoxForRenderer(renderer, offset());
708     InlineBox *b2 = inlineBoxForRenderer(posRenderer, pos.offset());
709
710     if (!b1 || !b2) {
711         return false;
712     }
713
714     if (b1->root() != b2->root()) {
715         return true;
716     }
717
718     if (nextRenderedEditable(node()) == pos.node() && 
719         thisRenderedOffset == (long)node()->caretMaxRenderedOffset() && posRenderedOffset == 0) {
720         return false;
721     }
722     
723     if (previousRenderedEditable(node()) == pos.node() && 
724         thisRenderedOffset == 0 && posRenderedOffset == (long)pos.node()->caretMaxRenderedOffset()) {
725         return false;
726     }
727
728     return true;
729 }
730
731 bool DOMPosition::isFirstRenderedPositionOnLine() const
732 {
733     if (isEmpty())
734         return false;
735
736     RenderObject *renderer = node()->renderer();
737     if (!renderer)
738         return false;
739
740     if (renderer->style()->visibility() != khtml::VISIBLE)
741         return false;
742     
743     DOMPosition pos(node(), offset());
744     EditIterator it(pos);
745     while (!it.atStart()) {
746         it.previous();
747         if (it.current().inRenderedContent())
748             return renderersOnDifferentLine(renderer, offset(), it.current().node()->renderer(), it.current().offset());
749     }
750     
751     return true;
752 }
753
754 bool DOMPosition::isLastRenderedPositionOnLine() const
755 {
756     if (isEmpty())
757         return false;
758
759     RenderObject *renderer = node()->renderer();
760     if (!renderer)
761         return false;
762
763     if (renderer->style()->visibility() != khtml::VISIBLE)
764         return false;
765     
766     if (node()->id() == ID_BR)
767         return true;
768     
769     DOMPosition pos(node(), offset());
770     EditIterator it(pos);
771     while (!it.atEnd()) {
772         it.next();
773         if (it.current().inRenderedContent())
774             return renderersOnDifferentLine(renderer, offset(), it.current().node()->renderer(), it.current().offset());
775     }
776     
777     return true;
778 }
779
780 bool DOMPosition::isLastRenderedPositionInEditableBlock() const
781 {
782     if (isEmpty())
783         return false;
784
785     RenderObject *renderer = node()->renderer();
786     if (!renderer)
787         return false;
788
789     if (renderer->style()->visibility() != khtml::VISIBLE)
790         return false;
791
792     if (renderedOffset() != (long)node()->caretMaxRenderedOffset())
793         return false;
794
795     DOMPosition pos(node(), offset());
796     EditIterator it(pos);
797     while (!it.atEnd()) {
798         it.next();
799         if (!it.current().node()->inSameContainingEditableBlock(node()))
800             return true;
801         if (it.current().inRenderedContent())
802             return false;
803     }
804     return true;
805 }
806
807 bool DOMPosition::inFirstEditableInRootEditableBlock() const
808 {
809     if (isEmpty() || !inRenderedContent())
810         return false;
811
812     EditIterator it(node(), offset());
813     while (!it.atStart()) {
814         if (it.previous().inRenderedContent())
815             return false;
816     }
817
818     return true;
819 }
820
821 bool DOMPosition::inLastEditableInRootEditableBlock() const
822 {
823     if (isEmpty() || !inRenderedContent())
824         return false;
825
826     EditIterator it(node(), offset());
827     while (!it.atEnd()) {
828         if (it.next().inRenderedContent())
829             return false;
830     }
831
832     return true;
833 }
834
835 bool DOMPosition::inFirstEditableInContainingEditableBlock() const
836 {
837     if (isEmpty() || !inRenderedContent())
838         return false;
839     
840     NodeImpl *block = node()->containingEditableBlock();
841
842     EditIterator it(node(), offset());
843     while (!it.atStart()) {
844         it.previous();
845         if (!it.current().inRenderedContent())
846             continue;
847         return block != it.current().node()->containingEditableBlock();
848     }
849
850     return true;
851 }
852
853 bool DOMPosition::inLastEditableInContainingEditableBlock() const
854 {
855     if (isEmpty() || !inRenderedContent())
856         return false;
857     
858     NodeImpl *block = node()->containingEditableBlock();
859
860     EditIterator it(node(), offset());
861     while (!it.atEnd()) {
862         it.next();
863         if (!it.current().inRenderedContent())
864             continue;
865         return block != it.current().node()->containingEditableBlock();
866     }
867
868     return true;
869 }