RenderTextControlMultiLine.cpp revision cad810f21b803229eb11403f9209855525a25d57
1/**
2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
3 *           (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB.  If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22#include "config.h"
23#include "RenderTextControlMultiLine.h"
24
25#include "Event.h"
26#include "EventNames.h"
27#include "Frame.h"
28#include "HTMLNames.h"
29#include "HTMLTextAreaElement.h"
30#include "HitTestResult.h"
31#ifdef ANDROID_LAYOUT
32#include "Settings.h"
33#endif
34
35namespace WebCore {
36
37RenderTextControlMultiLine::RenderTextControlMultiLine(Node* node, bool placeholderVisible)
38    : RenderTextControl(node, placeholderVisible)
39{
40}
41
42RenderTextControlMultiLine::~RenderTextControlMultiLine()
43{
44    if (node())
45        static_cast<HTMLTextAreaElement*>(node())->rendererWillBeDestroyed();
46}
47
48void RenderTextControlMultiLine::subtreeHasChanged()
49{
50    RenderTextControl::subtreeHasChanged();
51    HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(node());
52    textArea->setFormControlValueMatchesRenderer(false);
53    textArea->setNeedsValidityCheck();
54
55    if (!node()->focused())
56        return;
57
58    if (Frame* frame = this->frame())
59        frame->editor()->textDidChangeInTextArea(textArea);
60}
61
62bool RenderTextControlMultiLine::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
63{
64    if (!RenderTextControl::nodeAtPoint(request, result, x, y, tx, ty, hitTestAction))
65        return false;
66
67    if (result.innerNode() == node() || result.innerNode() == innerTextElement())
68        hitInnerTextElement(result, x, y, tx, ty);
69
70    return true;
71}
72
73void RenderTextControlMultiLine::forwardEvent(Event* event)
74{
75    RenderTextControl::forwardEvent(event);
76}
77
78float RenderTextControlMultiLine::getAvgCharWidth(AtomicString family)
79{
80    // Since Lucida Grande is the default font, we want this to match the width
81    // of Courier New, the default font for textareas in IE, Firefox and Safari Win.
82    // 1229 is the avgCharWidth value in the OS/2 table for Courier New.
83    if (family == AtomicString("Lucida Grande"))
84        return scaleEmToUnits(1229);
85
86    return RenderTextControl::getAvgCharWidth(family);
87}
88
89int RenderTextControlMultiLine::preferredContentWidth(float charWidth) const
90{
91    int factor = static_cast<HTMLTextAreaElement*>(node())->cols();
92    return static_cast<int>(ceilf(charWidth * factor)) + scrollbarThickness();
93}
94
95void RenderTextControlMultiLine::adjustControlHeightBasedOnLineHeight(int lineHeight)
96{
97    setHeight(height() + lineHeight * static_cast<HTMLTextAreaElement*>(node())->rows());
98}
99
100int RenderTextControlMultiLine::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
101{
102    return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
103}
104
105void RenderTextControlMultiLine::updateFromElement()
106{
107    createSubtreeIfNeeded(0);
108    RenderTextControl::updateFromElement();
109
110    setInnerTextValue(static_cast<HTMLTextAreaElement*>(node())->value());
111}
112
113void RenderTextControlMultiLine::cacheSelection(int start, int end)
114{
115    static_cast<HTMLTextAreaElement*>(node())->cacheSelection(start, end);
116}
117
118PassRefPtr<RenderStyle> RenderTextControlMultiLine::createInnerTextStyle(const RenderStyle* startStyle) const
119{
120    RefPtr<RenderStyle> textBlockStyle = RenderStyle::create();
121    textBlockStyle->inheritFrom(startStyle);
122    adjustInnerTextStyle(startStyle, textBlockStyle.get());
123    textBlockStyle->setDisplay(BLOCK);
124
125    return textBlockStyle.release();
126}
127
128RenderStyle* RenderTextControlMultiLine::textBaseStyle() const
129{
130    return style();
131}
132
133int RenderTextControlMultiLine::textBlockInsetLeft() const
134{
135    int inset = borderLeft() + paddingLeft();
136    if (HTMLElement* innerText = innerTextElement()) {
137        if (RenderBox* innerTextRenderer = innerText->renderBox())
138            inset += innerTextRenderer->paddingLeft();
139    }
140    return inset;
141}
142
143int RenderTextControlMultiLine::textBlockInsetRight() const
144{
145    int inset = borderRight() + paddingRight();
146    if (HTMLElement* innerText = innerTextElement()) {
147        if (RenderBox* innerTextRenderer = innerText->renderBox())
148            inset += innerTextRenderer->paddingRight();
149    }
150    return inset;
151}
152
153int RenderTextControlMultiLine::textBlockInsetTop() const
154{
155    int inset = borderTop() + paddingTop();
156    if (HTMLElement* innerText = innerTextElement()) {
157        if (RenderBox* innerTextRenderer = innerText->renderBox())
158            inset += innerTextRenderer->paddingTop();
159    }
160    return inset;
161}
162
163}
164