Fix for 3629816, caret in wrong position when deleting <br>s on lines by themselves...
[WebKit-https.git] / WebCore / khtml / rendering / render_br.cpp
1 /**
2  * This file is part of the DOM implementation for KDE.
3  *
4  * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  */
22 #include "render_br.h"
23 #include "xml/dom_position.h"
24
25 using namespace khtml;
26 using DOM::Position;
27
28 RenderBR::RenderBR(DOM::NodeImpl* node)
29     : RenderText(node, new DOM::DOMStringImpl(QChar('\n'))), m_x(0), m_y(0), m_height(0),
30       m_lineHeight(-1)
31 {
32 }
33
34 RenderBR::~RenderBR()
35 {
36 }
37
38 void RenderBR::setPos(int xPos, int yPos)
39 {
40     m_x = xPos;
41     m_y = yPos;
42 }
43
44 InlineBox* RenderBR::createInlineBox(bool makePlaceholder, bool isRootLineBox, bool isOnlyRun)
45 {
46     // We only make a box for a <br> if we are on a line by ourself or in strict mode
47     // (Note the use of strict mode.  In "almost strict" mode, we don't make a box for <br>.)
48     if (isOnlyRun || document()->inStrictMode())
49         return RenderText::createInlineBox(makePlaceholder, isRootLineBox, isOnlyRun);
50     return 0;
51 }
52
53 void RenderBR::position(InlineBox* box, int from, int len, bool reverse)
54 {
55     InlineTextBox *s = static_cast<InlineTextBox*>(box);
56     
57     // We want the box to be destroyed, but get the position of it first.
58     m_x = s->xPos();
59     m_y = s->yPos();
60     m_height = s->height();
61 }
62
63 short RenderBR::lineHeight(bool firstLine, bool isRootLineBox) const
64 {
65     if (firstLine) {
66         RenderStyle* s = style(firstLine);
67         Length lh = s->lineHeight();
68         if (lh.value < 0) {
69             if (s == style()) {
70                 if (m_lineHeight == -1)
71                     m_lineHeight = RenderObject::lineHeight(false);
72                 return m_lineHeight;
73             }
74             return s->fontMetrics().lineSpacing();
75         }
76         if (lh.isPercent())
77             return lh.minWidth(s->font().pixelSize());
78         return lh.value;
79     }
80     
81     if (m_lineHeight == -1)
82         m_lineHeight = RenderObject::lineHeight(false);
83     return m_lineHeight;
84 }
85
86 void RenderBR::setStyle(RenderStyle* _style)
87 {
88     RenderText::setStyle(_style);
89     m_lineHeight = -1;
90 }
91
92 long RenderBR::caretMinOffset() const 
93
94     return 0; 
95 }
96
97 long RenderBR::caretMaxOffset() const 
98
99     return 1; 
100 }
101
102 unsigned long RenderBR::caretMaxRenderedOffset() const
103 {
104     return 1;
105 }
106
107 Position RenderBR::positionForCoordinates(int _x, int _y)
108 {
109     return Position(element(), 0);
110 }
111
112 void RenderBR::caretPos(int offset, bool override, int &_x, int &_y, int &_w, int &_h)
113 {
114     // EDIT FIXME: This does not work yet. Some other changes are need before
115     // an accurate position can be determined.
116     _h = lineHeight(false);
117     _x = xPos();
118     _y = yPos();
119
120     int absx, absy;
121     absolutePosition(absx,absy);
122     _x += absx;
123     _y += absy;
124 }
125
126 InlineBox *RenderBR::inlineBox(long offset)
127 {
128     return firstTextBox();
129 }