Home | History | Annotate | Download | only in rendering
      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 
     37 RenderTextControlMultiLine::RenderTextControlMultiLine(Node* node, bool placeholderVisible)
     38     : RenderTextControl(node, placeholderVisible)
     39 {
     40 }
     41 
     42 RenderTextControlMultiLine::~RenderTextControlMultiLine()
     43 {
     44     if (node())
     45         static_cast<HTMLTextAreaElement*>(node())->rendererWillBeDestroyed();
     46 }
     47 
     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 
     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 
     78 void RenderTextControlMultiLine::forwardEvent(Event* event)
     79 {
     80     RenderTextControl::forwardEvent(event);
     81 }
     82 
     83 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 
     89 void RenderTextControlMultiLine::adjustControlHeightBasedOnLineHeight(int lineHeight)
     90 {
     91     setHeight(height() + lineHeight * static_cast<HTMLTextAreaElement*>(node())->rows());
     92 }
     93 
     94 int RenderTextControlMultiLine::baselinePosition(bool, bool) const
     95 {
     96     return height() + marginTop() + marginBottom();
     97 }
     98 
     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 
    111 void RenderTextControlMultiLine::cacheSelection(int start, int end)
    112 {
    113     static_cast<HTMLTextAreaElement*>(node())->cacheSelection(start, end);
    114 }
    115 
    116 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 
    134 RenderStyle* RenderTextControlMultiLine::textBaseStyle() const
    135 {
    136     return style();
    137 }
    138 
    139 }
    140