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())
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->setFormControlValueMatchesRenderer(false);
53 textArea->setNeedsValidityCheck();
54
55 if (!node()->focused())
56 return;
57
58 node()->dispatchEvent(Event::create(eventNames().inputEvent, true, false));
59
60 if (Frame* frame = document()->frame())
61 frame->textDidChangeInTextArea(textArea);
62 }
63
nodeAtPoint(const HitTestRequest & request,HitTestResult & result,int x,int y,int tx,int ty,HitTestAction hitTestAction)64 bool RenderTextControlMultiLine::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
65 {
66 if (!RenderTextControl::nodeAtPoint(request, result, x, y, tx, ty, hitTestAction))
67 return false;
68
69 bool resultIsTextValueOrPlaceholder
70 = (!m_placeholderVisible && result.innerNode() == innerTextElement())
71 || (m_placeholderVisible && result.innerNode()->isDescendantOf(innerTextElement()));
72 if (result.innerNode() == node() || resultIsTextValueOrPlaceholder)
73 hitInnerTextElement(result, x, y, tx, ty);
74
75 return true;
76 }
77
forwardEvent(Event * event)78 void RenderTextControlMultiLine::forwardEvent(Event* event)
79 {
80 RenderTextControl::forwardEvent(event);
81 }
82
preferredContentWidth(float charWidth) const83 int RenderTextControlMultiLine::preferredContentWidth(float charWidth) const
84 {
85 int factor = static_cast<HTMLTextAreaElement*>(node())->cols();
86 return static_cast<int>(ceilf(charWidth * factor)) + scrollbarThickness();
87 }
88
adjustControlHeightBasedOnLineHeight(int lineHeight)89 void RenderTextControlMultiLine::adjustControlHeightBasedOnLineHeight(int lineHeight)
90 {
91 setHeight(height() + lineHeight * static_cast<HTMLTextAreaElement*>(node())->rows());
92 }
93
baselinePosition(bool,bool) const94 int RenderTextControlMultiLine::baselinePosition(bool, bool) const
95 {
96 return height() + marginTop() + marginBottom();
97 }
98
updateFromElement()99 void RenderTextControlMultiLine::updateFromElement()
100 {
101 createSubtreeIfNeeded(0);
102 RenderTextControl::updateFromElement();
103
104 HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(node());
105 if (m_placeholderVisible)
106 setInnerTextValue(textArea->getAttribute(HTMLNames::placeholderAttr));
107 else
108 setInnerTextValue(textArea->value());
109 }
110
cacheSelection(int start,int end)111 void RenderTextControlMultiLine::cacheSelection(int start, int end)
112 {
113 static_cast<HTMLTextAreaElement*>(node())->cacheSelection(start, end);
114 }
115
createInnerTextStyle(const RenderStyle * startStyle) const116 PassRefPtr<RenderStyle> RenderTextControlMultiLine::createInnerTextStyle(const RenderStyle* startStyle) const
117 {
118 RefPtr<RenderStyle> textBlockStyle;
119 if (m_placeholderVisible) {
120 if (RenderStyle* pseudoStyle = getCachedPseudoStyle(INPUT_PLACEHOLDER))
121 textBlockStyle = RenderStyle::clone(pseudoStyle);
122 }
123 if (!textBlockStyle) {
124 textBlockStyle = RenderStyle::create();
125 textBlockStyle->inheritFrom(startStyle);
126 }
127
128 adjustInnerTextStyle(startStyle, textBlockStyle.get());
129 textBlockStyle->setDisplay(BLOCK);
130
131 return textBlockStyle.release();
132 }
133
textBaseStyle() const134 RenderStyle* RenderTextControlMultiLine::textBaseStyle() const
135 {
136 return style();
137 }
138
139 }
140