1635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project/**
2635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
3635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *           (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
4635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
5635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * This library is free software; you can redistribute it and/or
6635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * modify it under the terms of the GNU Library General Public
7635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * License as published by the Free Software Foundation; either
8635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * version 2 of the License, or (at your option) any later version.
9635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
10635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * This library is distributed in the hope that it will be useful,
11635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
12635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Library General Public License for more details.
14635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
15635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * You should have received a copy of the GNU Library General Public License
16635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
17635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Boston, MA 02110-1301, USA.
19635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
20635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project */
21635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
22635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "config.h"
23635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "RenderTextControlMultiLine.h"
24635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
25231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "Event.h"
26635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "EventNames.h"
27635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Frame.h"
28231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "HTMLNames.h"
29635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "HTMLTextAreaElement.h"
303f252f84468859d129a8c6a9302412d2e6e5a3faSteve Block#include "HitTestResult.h"
31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#ifdef ANDROID_LAYOUT
32635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Settings.h"
33635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
34635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
35635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectnamespace WebCore {
36635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
37231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockRenderTextControlMultiLine::RenderTextControlMultiLine(Node* node, bool placeholderVisible)
38231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    : RenderTextControl(node, placeholderVisible)
39635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
40635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
41635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
42635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRenderTextControlMultiLine::~RenderTextControlMultiLine()
43635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
44635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (node())
45635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        static_cast<HTMLTextAreaElement*>(node())->rendererWillBeDestroyed();
46635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
47635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
48635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderTextControlMultiLine::subtreeHasChanged()
49635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
50635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderTextControl::subtreeHasChanged();
51231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(node());
52231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    textArea->setFormControlValueMatchesRenderer(false);
535e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    textArea->setNeedsValidityCheck();
54635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
55635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!node()->focused())
56635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
57635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
58231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    node()->dispatchEvent(Event::create(eventNames().inputEvent, true, false));
590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
60635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (Frame* frame = document()->frame())
61231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        frame->textDidChangeInTextArea(textArea);
62635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
63635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
64635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool RenderTextControlMultiLine::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
65635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
66635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!RenderTextControl::nodeAtPoint(request, result, x, y, tx, ty, hitTestAction))
67635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return false;
68635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
69231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    bool resultIsTextValueOrPlaceholder
70643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        = (!m_placeholderVisible && result.innerNode() == innerTextElement())
71643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        || (m_placeholderVisible && result.innerNode()->isDescendantOf(innerTextElement()));
72231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (result.innerNode() == node() || resultIsTextValueOrPlaceholder)
738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        hitInnerTextElement(result, x, y, tx, ty);
74635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return true;
76635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
77635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
78635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderTextControlMultiLine::forwardEvent(Event* event)
79635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
80635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderTextControl::forwardEvent(event);
81635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
82635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
83635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectint RenderTextControlMultiLine::preferredContentWidth(float charWidth) const
84635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
85635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int factor = static_cast<HTMLTextAreaElement*>(node())->cols();
86635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return static_cast<int>(ceilf(charWidth * factor)) + scrollbarThickness();
87635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
88635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
89635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderTextControlMultiLine::adjustControlHeightBasedOnLineHeight(int lineHeight)
90635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
91635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    setHeight(height() + lineHeight * static_cast<HTMLTextAreaElement*>(node())->rows());
92635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
93635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
94635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectint RenderTextControlMultiLine::baselinePosition(bool, bool) const
95635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
96635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return height() + marginTop() + marginBottom();
97635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
98635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
99635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderTextControlMultiLine::updateFromElement()
100635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
101635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    createSubtreeIfNeeded(0);
102635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderTextControl::updateFromElement();
103635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
104231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(node());
105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (m_placeholderVisible)
106231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        setInnerTextValue(textArea->getAttribute(HTMLNames::placeholderAttr));
107231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    else
108231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        setInnerTextValue(textArea->value());
109635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
110635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
111635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderTextControlMultiLine::cacheSelection(int start, int end)
112635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
113635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    static_cast<HTMLTextAreaElement*>(node())->cacheSelection(start, end);
114635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
115635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
116635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<RenderStyle> RenderTextControlMultiLine::createInnerTextStyle(const RenderStyle* startStyle) const
117635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
118231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RefPtr<RenderStyle> textBlockStyle;
119231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (m_placeholderVisible) {
120231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (RenderStyle* pseudoStyle = getCachedPseudoStyle(INPUT_PLACEHOLDER))
121231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            textBlockStyle = RenderStyle::clone(pseudoStyle);
122231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
123231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!textBlockStyle) {
124231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        textBlockStyle = RenderStyle::create();
125231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        textBlockStyle->inheritFrom(startStyle);
126231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
127635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
128635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    adjustInnerTextStyle(startStyle, textBlockStyle.get());
129635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    textBlockStyle->setDisplay(BLOCK);
130635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
131635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return textBlockStyle.release();
132635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
133635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
134231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockRenderStyle* RenderTextControlMultiLine::textBaseStyle() const
135231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
136231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return style();
137231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
138231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
139635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
140