• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
35 namespace WebCore {
36 
RenderTextControlMultiLine(Node * node,bool placeholderVisible)37 RenderTextControlMultiLine::RenderTextControlMultiLine(Node* node, bool placeholderVisible)
38     : RenderTextControl(node, placeholderVisible)
39 {
40 }
41 
~RenderTextControlMultiLine()42 RenderTextControlMultiLine::~RenderTextControlMultiLine()
43 {
44     if (node() && node()->inDocument())
45         static_cast<HTMLTextAreaElement*>(node())->rendererWillBeDestroyed();
46 }
47 
subtreeHasChanged()48 void RenderTextControlMultiLine::subtreeHasChanged()
49 {
50     RenderTextControl::subtreeHasChanged();
51     HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(node());
52     textArea->setChangedSinceLastFormControlChangeEvent(true);
53     textArea->setFormControlValueMatchesRenderer(false);
54     textArea->setNeedsValidityCheck();
55 
56     if (!node()->focused())
57         return;
58 
59     if (Frame* frame = this->frame())
60         frame->editor()->textDidChangeInTextArea(textArea);
61 }
62 
nodeAtPoint(const HitTestRequest & request,HitTestResult & result,int x,int y,int tx,int ty,HitTestAction hitTestAction)63 bool RenderTextControlMultiLine::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
64 {
65     if (!RenderTextControl::nodeAtPoint(request, result, x, y, tx, ty, hitTestAction))
66         return false;
67 
68     if (result.innerNode() == node() || result.innerNode() == innerTextElement())
69         hitInnerTextElement(result, x, y, tx, ty);
70 
71     return true;
72 }
73 
forwardEvent(Event * event)74 void RenderTextControlMultiLine::forwardEvent(Event* event)
75 {
76     RenderTextControl::forwardEvent(event);
77 }
78 
getAvgCharWidth(AtomicString family)79 float RenderTextControlMultiLine::getAvgCharWidth(AtomicString family)
80 {
81     // Since Lucida Grande is the default font, we want this to match the width
82     // of Courier New, the default font for textareas in IE, Firefox and Safari Win.
83     // 1229 is the avgCharWidth value in the OS/2 table for Courier New.
84     if (family == AtomicString("Lucida Grande"))
85         return scaleEmToUnits(1229);
86 
87     return RenderTextControl::getAvgCharWidth(family);
88 }
89 
preferredContentWidth(float charWidth) const90 int RenderTextControlMultiLine::preferredContentWidth(float charWidth) const
91 {
92     int factor = static_cast<HTMLTextAreaElement*>(node())->cols();
93     return static_cast<int>(ceilf(charWidth * factor)) + scrollbarThickness();
94 }
95 
adjustControlHeightBasedOnLineHeight(int lineHeight)96 void RenderTextControlMultiLine::adjustControlHeightBasedOnLineHeight(int lineHeight)
97 {
98     setHeight(height() + lineHeight * static_cast<HTMLTextAreaElement*>(node())->rows());
99 }
100 
baselinePosition(FontBaseline baselineType,bool firstLine,LineDirectionMode direction,LinePositionMode linePositionMode) const101 int RenderTextControlMultiLine::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
102 {
103     return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
104 }
105 
updateFromElement()106 void RenderTextControlMultiLine::updateFromElement()
107 {
108     createSubtreeIfNeeded(0);
109     RenderTextControl::updateFromElement();
110 
111     setInnerTextValue(static_cast<HTMLTextAreaElement*>(node())->value());
112 }
113 
cacheSelection(int start,int end)114 void RenderTextControlMultiLine::cacheSelection(int start, int end)
115 {
116     static_cast<HTMLTextAreaElement*>(node())->cacheSelection(start, end);
117 }
118 
createInnerTextStyle(const RenderStyle * startStyle) const119 PassRefPtr<RenderStyle> RenderTextControlMultiLine::createInnerTextStyle(const RenderStyle* startStyle) const
120 {
121     RefPtr<RenderStyle> textBlockStyle = RenderStyle::create();
122     textBlockStyle->inheritFrom(startStyle);
123     adjustInnerTextStyle(startStyle, textBlockStyle.get());
124     textBlockStyle->setDisplay(BLOCK);
125 
126     return textBlockStyle.release();
127 }
128 
textBaseStyle() const129 RenderStyle* RenderTextControlMultiLine::textBaseStyle() const
130 {
131     return style();
132 }
133 
textBlockInsetLeft() const134 int RenderTextControlMultiLine::textBlockInsetLeft() const
135 {
136     int inset = borderLeft() + paddingLeft();
137     if (HTMLElement* innerText = innerTextElement()) {
138         if (RenderBox* innerTextRenderer = innerText->renderBox())
139             inset += innerTextRenderer->paddingLeft();
140     }
141     return inset;
142 }
143 
textBlockInsetRight() const144 int RenderTextControlMultiLine::textBlockInsetRight() const
145 {
146     int inset = borderRight() + paddingRight();
147     if (HTMLElement* innerText = innerTextElement()) {
148         if (RenderBox* innerTextRenderer = innerText->renderBox())
149             inset += innerTextRenderer->paddingRight();
150     }
151     return inset;
152 }
153 
textBlockInsetTop() const154 int RenderTextControlMultiLine::textBlockInsetTop() const
155 {
156     int inset = borderTop() + paddingTop();
157     if (HTMLElement* innerText = innerTextElement()) {
158         if (RenderBox* innerTextRenderer = innerText->renderBox())
159             inset += innerTextRenderer->paddingTop();
160     }
161     return inset;
162 }
163 
164 }
165