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() && node()->inDocument())
     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->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 
     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 
     74 void RenderTextControlMultiLine::forwardEvent(Event* event)
     75 {
     76     RenderTextControl::forwardEvent(event);
     77 }
     78 
     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 
     90 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 
     96 void RenderTextControlMultiLine::adjustControlHeightBasedOnLineHeight(int lineHeight)
     97 {
     98     setHeight(height() + lineHeight * static_cast<HTMLTextAreaElement*>(node())->rows());
     99 }
    100 
    101 int RenderTextControlMultiLine::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
    102 {
    103     return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
    104 }
    105 
    106 void RenderTextControlMultiLine::updateFromElement()
    107 {
    108     createSubtreeIfNeeded(0);
    109     RenderTextControl::updateFromElement();
    110 
    111     setInnerTextValue(static_cast<HTMLTextAreaElement*>(node())->value());
    112 }
    113 
    114 void RenderTextControlMultiLine::cacheSelection(int start, int end)
    115 {
    116     static_cast<HTMLTextAreaElement*>(node())->cacheSelection(start, end);
    117 }
    118 
    119 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 
    129 RenderStyle* RenderTextControlMultiLine::textBaseStyle() const
    130 {
    131     return style();
    132 }
    133 
    134 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 
    144 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 
    154 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