Home | History | Annotate | Download | only in rendering
      1 /**
      2  * Copyright (C) 2006, 2007, 2010 Apple Inc. All rights reserved.
      3  *           (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
      4  * Copyright (C) 2010 Google Inc. All rights reserved.
      5  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
      6  *
      7  * This library is free software; you can redistribute it and/or
      8  * modify it under the terms of the GNU Library General Public
      9  * License as published by the Free Software Foundation; either
     10  * version 2 of the License, or (at your option) any later version.
     11  *
     12  * This library is distributed in the hope that it will be useful,
     13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15  * Library General Public License for more details.
     16  *
     17  * You should have received a copy of the GNU Library General Public License
     18  * along with this library; see the file COPYING.LIB.  If not, write to
     19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     20  * Boston, MA 02110-1301, USA.
     21  *
     22  */
     23 
     24 #include "config.h"
     25 #include "RenderTextControlSingleLine.h"
     26 
     27 #include "Chrome.h"
     28 #include "CSSStyleSelector.h"
     29 #include "Event.h"
     30 #include "EventNames.h"
     31 #include "Frame.h"
     32 #include "FrameView.h"
     33 #include "HTMLInputElement.h"
     34 #include "HTMLNames.h"
     35 #include "HitTestResult.h"
     36 #include "InputElement.h"
     37 #include "LocalizedStrings.h"
     38 #include "MouseEvent.h"
     39 #include "PlatformKeyboardEvent.h"
     40 #include "RenderLayer.h"
     41 #include "RenderScrollbar.h"
     42 #include "RenderTheme.h"
     43 #include "SelectionController.h"
     44 #include "Settings.h"
     45 #include "SimpleFontData.h"
     46 #include "TextControlInnerElements.h"
     47 
     48 using namespace std;
     49 
     50 namespace WebCore {
     51 
     52 using namespace HTMLNames;
     53 
     54 VisiblePosition RenderTextControlInnerBlock::positionForPoint(const IntPoint& point)
     55 {
     56     IntPoint contentsPoint(point);
     57 
     58     // Multiline text controls have the scroll on shadowAncestorNode, so we need to take that
     59     // into account here.
     60     if (m_multiLine) {
     61         RenderTextControl* renderer = toRenderTextControl(node()->shadowAncestorNode()->renderer());
     62         if (renderer->hasOverflowClip())
     63             contentsPoint += renderer->layer()->scrolledContentOffset();
     64     }
     65 
     66     return RenderBlock::positionForPoint(contentsPoint);
     67 }
     68 
     69 // ----------------------------
     70 
     71 RenderTextControlSingleLine::RenderTextControlSingleLine(Node* node, bool placeholderVisible)
     72     : RenderTextControl(node, placeholderVisible)
     73     , m_searchPopupIsVisible(false)
     74     , m_shouldDrawCapsLockIndicator(false)
     75     , m_searchEventTimer(this, &RenderTextControlSingleLine::searchEventTimerFired)
     76     , m_searchPopup(0)
     77 {
     78 }
     79 
     80 RenderTextControlSingleLine::~RenderTextControlSingleLine()
     81 {
     82     if (m_searchPopup) {
     83         m_searchPopup->popupMenu()->disconnectClient();
     84         m_searchPopup = 0;
     85     }
     86 
     87     if (m_innerBlock) {
     88         m_innerBlock->detach();
     89         m_innerBlock = 0;
     90     }
     91 
     92     if (m_innerSpinButton)
     93         m_innerSpinButton->detach();
     94     if (m_outerSpinButton)
     95         m_outerSpinButton->detach();
     96 #if ENABLE(INPUT_SPEECH)
     97     if (m_speechButton)
     98         m_speechButton->detach();
     99 #endif
    100 }
    101 
    102 RenderStyle* RenderTextControlSingleLine::textBaseStyle() const
    103 {
    104     return m_innerBlock ? m_innerBlock->renderer()->style() : style();
    105 }
    106 
    107 void RenderTextControlSingleLine::addSearchResult()
    108 {
    109     ASSERT(node()->isHTMLElement());
    110     HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
    111     if (input->maxResults() <= 0)
    112         return;
    113 
    114     String value = input->value();
    115     if (value.isEmpty())
    116         return;
    117 
    118     Settings* settings = document()->settings();
    119     if (!settings || settings->privateBrowsingEnabled())
    120         return;
    121 
    122     int size = static_cast<int>(m_recentSearches.size());
    123     for (int i = size - 1; i >= 0; --i) {
    124         if (m_recentSearches[i] == value)
    125             m_recentSearches.remove(i);
    126     }
    127 
    128     m_recentSearches.insert(0, value);
    129     while (static_cast<int>(m_recentSearches.size()) > input->maxResults())
    130         m_recentSearches.removeLast();
    131 
    132     const AtomicString& name = autosaveName();
    133     if (!m_searchPopup)
    134         m_searchPopup = document()->page()->chrome()->createSearchPopupMenu(this);
    135 
    136     m_searchPopup->saveRecentSearches(name, m_recentSearches);
    137 }
    138 
    139 void RenderTextControlSingleLine::stopSearchEventTimer()
    140 {
    141     ASSERT(node()->isHTMLElement());
    142     m_searchEventTimer.stop();
    143 }
    144 
    145 void RenderTextControlSingleLine::showPopup()
    146 {
    147     ASSERT(node()->isHTMLElement());
    148     if (m_searchPopupIsVisible)
    149         return;
    150 
    151     if (!m_searchPopup)
    152         m_searchPopup = document()->page()->chrome()->createSearchPopupMenu(this);
    153 
    154     if (!m_searchPopup->enabled())
    155         return;
    156 
    157     m_searchPopupIsVisible = true;
    158 
    159     const AtomicString& name = autosaveName();
    160     m_searchPopup->loadRecentSearches(name, m_recentSearches);
    161 
    162     // Trim the recent searches list if the maximum size has changed since we last saved.
    163     HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
    164     if (static_cast<int>(m_recentSearches.size()) > input->maxResults()) {
    165         do {
    166             m_recentSearches.removeLast();
    167         } while (static_cast<int>(m_recentSearches.size()) > input->maxResults());
    168 
    169         m_searchPopup->saveRecentSearches(name, m_recentSearches);
    170     }
    171 
    172     m_searchPopup->popupMenu()->show(absoluteBoundingBoxRect(true), document()->view(), -1);
    173 }
    174 
    175 void RenderTextControlSingleLine::hidePopup()
    176 {
    177     ASSERT(node()->isHTMLElement());
    178     if (m_searchPopup)
    179         m_searchPopup->popupMenu()->hide();
    180 }
    181 
    182 void RenderTextControlSingleLine::subtreeHasChanged()
    183 {
    184     RenderTextControl::subtreeHasChanged();
    185 
    186     ASSERT(node()->isElementNode());
    187     Element* element = static_cast<Element*>(node());
    188     bool wasChanged = element->wasChangedSinceLastFormControlChangeEvent();
    189     element->setChangedSinceLastFormControlChangeEvent(true);
    190 
    191     InputElement* input = inputElement();
    192     // We don't need to call sanitizeUserInputValue() function here because
    193     // InputElement::handleBeforeTextInsertedEvent() has already called
    194     // sanitizeUserInputValue().
    195     // sanitizeValue() is needed because IME input doesn't dispatch BeforeTextInsertedEvent.
    196     String value = text();
    197     if (input->isAcceptableValue(value))
    198         input->setValueFromRenderer(input->sanitizeValue(input->convertFromVisibleValue(value)));
    199     if (node()->isHTMLElement()) {
    200         // Recalc for :invalid and hasUnacceptableValue() change.
    201         static_cast<HTMLInputElement*>(input)->setNeedsStyleRecalc();
    202     }
    203 
    204     if (m_cancelButton)
    205         updateCancelButtonVisibility();
    206 
    207     // If the incremental attribute is set, then dispatch the search event
    208     if (input->searchEventsShouldBeDispatched())
    209         startSearchEventTimer();
    210 
    211     if (!wasChanged && node()->focused()) {
    212         if (Frame* frame = this->frame())
    213             frame->editor()->textFieldDidBeginEditing(static_cast<Element*>(node()));
    214     }
    215 
    216     if (node()->focused()) {
    217         if (Frame* frame = document()->frame())
    218             frame->editor()->textDidChangeInTextField(static_cast<Element*>(node()));
    219     }
    220 }
    221 
    222 void RenderTextControlSingleLine::paint(PaintInfo& paintInfo, int tx, int ty)
    223 {
    224     RenderTextControl::paint(paintInfo, tx, ty);
    225 
    226     if (paintInfo.phase == PaintPhaseBlockBackground && m_shouldDrawCapsLockIndicator) {
    227         IntRect contentsRect = contentBoxRect();
    228 
    229         // Center vertically like the text.
    230         contentsRect.setY((height() - contentsRect.height()) / 2);
    231 
    232         // Convert the rect into the coords used for painting the content
    233         contentsRect.move(tx + x(), ty + y());
    234         theme()->paintCapsLockIndicator(this, paintInfo, contentsRect);
    235     }
    236 }
    237 
    238 void RenderTextControlSingleLine::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
    239 {
    240     paintBoxDecorationsWithSize(paintInfo, tx, ty, width() - decorationWidthRight(), height());
    241 }
    242 
    243 void RenderTextControlSingleLine::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
    244 {
    245     int w = width() - decorationWidthRight();
    246     if (w && height())
    247         rects.append(IntRect(tx, ty, w, height()));
    248 }
    249 
    250 void RenderTextControlSingleLine::layout()
    251 {
    252     int oldHeight = height();
    253     computeLogicalHeight();
    254 
    255     int oldWidth = width();
    256     computeLogicalWidth();
    257 
    258     bool relayoutChildren = oldHeight != height() || oldWidth != width();
    259 
    260 #ifdef ANDROID_LAYOUT
    261     checkAndSetRelayoutChildren(&relayoutChildren);
    262 #endif
    263 
    264     RenderBox* innerTextRenderer = innerTextElement()->renderBox();
    265     RenderBox* innerBlockRenderer = m_innerBlock ? m_innerBlock->renderBox() : 0;
    266 
    267     // Set the text block height
    268     int desiredHeight = textBlockHeight();
    269     int currentHeight = innerTextRenderer->height();
    270 
    271     if (currentHeight > height()) {
    272         if (desiredHeight != currentHeight)
    273             relayoutChildren = true;
    274         innerTextRenderer->style()->setHeight(Length(desiredHeight, Fixed));
    275         if (m_innerBlock)
    276             innerBlockRenderer->style()->setHeight(Length(desiredHeight, Fixed));
    277     }
    278 
    279     // Set the text block width
    280     int desiredWidth = textBlockWidth();
    281     if (desiredWidth != innerTextRenderer->width())
    282         relayoutChildren = true;
    283     innerTextRenderer->style()->setWidth(Length(desiredWidth, Fixed));
    284 
    285     if (m_innerBlock) {
    286         int innerBlockWidth = width() - borderAndPaddingWidth();
    287         if (innerBlockWidth != innerBlockRenderer->width())
    288             relayoutChildren = true;
    289         innerBlockRenderer->style()->setWidth(Length(innerBlockWidth, Fixed));
    290     }
    291 
    292     RenderBlock::layoutBlock(relayoutChildren);
    293 
    294     // Center the child block vertically
    295     RenderBox* childBlock = innerBlockRenderer ? innerBlockRenderer : innerTextRenderer;
    296     currentHeight = childBlock->height();
    297     if (currentHeight < height())
    298         childBlock->setY((height() - currentHeight) / 2);
    299 
    300     // Ignores the paddings for the inner spin button.
    301     if (RenderBox* spinBox = m_innerSpinButton ? m_innerSpinButton->renderBox() : 0) {
    302         spinBox->setLocation(spinBox->x() + paddingRight(), borderTop());
    303         spinBox->setHeight(height() - borderTop() - borderBottom());
    304     }
    305 
    306 #if ENABLE(INPUT_SPEECH)
    307     if (RenderBox* button = m_speechButton ? m_speechButton->renderBox() : 0) {
    308         if (m_innerBlock) {
    309             // This is mostly the case where this is a search field. The speech button is a sibling
    310             // of the inner block and laid out at the far right.
    311             int x = width() - borderAndPaddingWidth() - button->width() - button->borderAndPaddingWidth();
    312             int y = (height() - button->height()) / 2;
    313             button->setLocation(x, y);
    314         } else {
    315             // For non-search fields which are simpler and we let the defaut layout handle things
    316             // except for small tweaking below.
    317             button->setLocation(button->x() + paddingRight(), (height() - button->height()) / 2);
    318         }
    319     }
    320 #endif
    321 
    322     // Center the spin button vertically, and move it to the right by
    323     // padding + border of the text fields.
    324     if (RenderBox* spinBox = m_outerSpinButton ? m_outerSpinButton->renderBox() : 0) {
    325         int diff = height() - spinBox->height();
    326         // If the diff is odd, the top area over the spin button takes the
    327         // remaining one pixel. It's good for Mac NSStepper because it has
    328         // shadow at the bottom.
    329         int y = (diff / 2) + (diff % 2);
    330         int x = width() - borderRight() - paddingRight() - spinBox->width();
    331         spinBox->setLocation(x, y);
    332     }
    333 }
    334 
    335 bool RenderTextControlSingleLine::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int xPos, int yPos, int tx, int ty, HitTestAction hitTestAction)
    336 {
    337     // If we're within the text control, we want to act as if we've hit the inner text block element, in case the point
    338     // was on the control but not on the inner element (see Radar 4617841).
    339 
    340     // In a search field, we want to act as if we've hit the results block if we're to the left of the inner text block,
    341     // and act as if we've hit the close block if we're to the right of the inner text block.
    342 
    343     if (!RenderTextControl::nodeAtPoint(request, result, xPos, yPos, tx, ty, hitTestAction))
    344         return false;
    345 
    346     // If we hit a node inside the inner text element, say that we hit that element,
    347     // and if we hit our node (e.g. we're over the border or padding), also say that we hit the
    348     // inner text element so that it gains focus.
    349     if (result.innerNode()->isDescendantOf(innerTextElement()) || result.innerNode() == node())
    350         hitInnerTextElement(result, xPos, yPos, tx, ty);
    351 
    352     // If we found a spin button, we're done.
    353     if (m_innerSpinButton && result.innerNode() == m_innerSpinButton)
    354         return true;
    355     if (m_outerSpinButton && result.innerNode() == m_outerSpinButton)
    356         return true;
    357 #if ENABLE(INPUT_SPEECH)
    358     if (m_speechButton && result.innerNode() == m_speechButton)
    359         return true;
    360 #endif
    361     // If we're not a search field, or we already found the speech, results or cancel buttons, we're done.
    362     if (!m_innerBlock || result.innerNode() == m_resultsButton || result.innerNode() == m_cancelButton)
    363         return true;
    364 
    365     Node* innerNode = 0;
    366     RenderBox* innerBlockRenderer = m_innerBlock->renderBox();
    367     RenderBox* innerTextRenderer = innerTextElement()->renderBox();
    368 
    369     IntPoint localPoint = result.localPoint();
    370     localPoint.move(-innerBlockRenderer->x(), -innerBlockRenderer->y());
    371 
    372     int textLeft = tx + x() + innerBlockRenderer->x() + innerTextRenderer->x();
    373     if (m_resultsButton && m_resultsButton->renderer() && xPos < textLeft)
    374         innerNode = m_resultsButton.get();
    375 
    376     if (!innerNode) {
    377         int textRight = textLeft + innerTextRenderer->width();
    378         if (m_cancelButton && m_cancelButton->renderer() && xPos > textRight)
    379             innerNode = m_cancelButton.get();
    380     }
    381 
    382     if (innerNode) {
    383         result.setInnerNode(innerNode);
    384         localPoint.move(-innerNode->renderBox()->x(), -innerNode->renderBox()->y());
    385     }
    386 
    387     result.setLocalPoint(localPoint);
    388     return true;
    389 }
    390 
    391 void RenderTextControlSingleLine::forwardEvent(Event* event)
    392 {
    393     RenderBox* innerTextRenderer = innerTextElement()->renderBox();
    394 
    395     if (event->type() == eventNames().blurEvent) {
    396         if (innerTextRenderer) {
    397             if (RenderLayer* innerLayer = innerTextRenderer->layer())
    398                 innerLayer->scrollToOffset(!style()->isLeftToRightDirection() ? innerLayer->scrollWidth() : 0, 0);
    399         }
    400 
    401         capsLockStateMayHaveChanged();
    402     } else if (event->type() == eventNames().focusEvent)
    403         capsLockStateMayHaveChanged();
    404 
    405     if (!event->isMouseEvent()) {
    406         RenderTextControl::forwardEvent(event);
    407         return;
    408     }
    409 
    410 #if ENABLE(INPUT_SPEECH)
    411     if (RenderBox* speechBox = m_speechButton ? m_speechButton->renderBox() : 0) {
    412         FloatPoint pointInTextControlCoords = absoluteToLocal(static_cast<MouseEvent*>(event)->absoluteLocation(), false, true);
    413         if (speechBox->frameRect().contains(roundedIntPoint(pointInTextControlCoords))) {
    414             m_speechButton->defaultEventHandler(event);
    415             return;
    416         }
    417     }
    418 #endif
    419 
    420     FloatPoint localPoint = innerTextRenderer->absoluteToLocal(static_cast<MouseEvent*>(event)->absoluteLocation(), false, true);
    421     int textRight = innerTextRenderer->borderBoxRect().maxX();
    422 
    423     if (m_resultsButton && localPoint.x() < innerTextRenderer->borderBoxRect().x())
    424         m_resultsButton->defaultEventHandler(event);
    425     else if (m_cancelButton && localPoint.x() > textRight)
    426         m_cancelButton->defaultEventHandler(event);
    427     else
    428         RenderTextControl::forwardEvent(event);
    429 }
    430 
    431 void RenderTextControlSingleLine::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
    432 {
    433     RenderTextControl::styleDidChange(diff, oldStyle);
    434 
    435     if (RenderObject* innerBlockRenderer = m_innerBlock ? m_innerBlock->renderer() : 0) {
    436         // We may have set the width and the height in the old style in layout().
    437         // Reset them now to avoid getting a spurious layout hint.
    438         innerBlockRenderer->style()->setHeight(Length());
    439         innerBlockRenderer->style()->setWidth(Length());
    440         innerBlockRenderer->setStyle(createInnerBlockStyle(style()));
    441     }
    442 
    443     if (RenderObject* resultsRenderer = m_resultsButton ? m_resultsButton->renderer() : 0)
    444         resultsRenderer->setStyle(createResultsButtonStyle(style()));
    445 
    446     if (RenderObject* cancelRenderer = m_cancelButton ? m_cancelButton->renderer() : 0)
    447         cancelRenderer->setStyle(createCancelButtonStyle(style()));
    448 
    449     if (RenderObject* spinRenderer = m_outerSpinButton ? m_outerSpinButton->renderer() : 0)
    450         spinRenderer->setStyle(createOuterSpinButtonStyle());
    451 
    452     if (RenderObject* spinRenderer = m_innerSpinButton ? m_innerSpinButton->renderer() : 0)
    453         spinRenderer->setStyle(createInnerSpinButtonStyle());
    454 
    455 #if ENABLE(INPUT_SPEECH)
    456     if (RenderObject* speechRenderer = m_speechButton ? m_speechButton->renderer() : 0)
    457         speechRenderer->setStyle(createSpeechButtonStyle());
    458 #endif
    459 
    460     setHasOverflowClip(false);
    461 }
    462 
    463 void RenderTextControlSingleLine::capsLockStateMayHaveChanged()
    464 {
    465     if (!node() || !document())
    466         return;
    467 
    468     // Only draw the caps lock indicator if these things are true:
    469     // 1) The field is a password field
    470     // 2) The frame is active
    471     // 3) The element is focused
    472     // 4) The caps lock is on
    473     bool shouldDrawCapsLockIndicator = false;
    474 
    475     if (Frame* frame = document()->frame())
    476         shouldDrawCapsLockIndicator = inputElement()->isPasswordField()
    477                                       && frame->selection()->isFocusedAndActive()
    478                                       && document()->focusedNode() == node()
    479                                       && PlatformKeyboardEvent::currentCapsLockState();
    480 
    481     if (shouldDrawCapsLockIndicator != m_shouldDrawCapsLockIndicator) {
    482         m_shouldDrawCapsLockIndicator = shouldDrawCapsLockIndicator;
    483         repaint();
    484     }
    485 }
    486 
    487 bool RenderTextControlSingleLine::hasControlClip() const
    488 {
    489     bool clip = m_cancelButton;
    490     return clip;
    491 }
    492 
    493 IntRect RenderTextControlSingleLine::controlClipRect(int tx, int ty) const
    494 {
    495     // This should only get called for search & speech inputs.
    496     ASSERT(hasControlClip());
    497 
    498     IntRect clipRect = IntRect(m_innerBlock->renderBox()->frameRect());
    499     clipRect.move(tx, ty);
    500     return clipRect;
    501 }
    502 
    503 int RenderTextControlSingleLine::textBlockWidth() const
    504 {
    505     int width = RenderTextControl::textBlockWidth();
    506 
    507     if (RenderBox* resultsRenderer = m_resultsButton ? m_resultsButton->renderBox() : 0) {
    508         resultsRenderer->computeLogicalWidth();
    509         width -= resultsRenderer->width() + resultsRenderer->marginLeft() + resultsRenderer->marginRight();
    510     }
    511 
    512     if (RenderBox* cancelRenderer = m_cancelButton ? m_cancelButton->renderBox() : 0) {
    513         cancelRenderer->computeLogicalWidth();
    514         width -= cancelRenderer->width() + cancelRenderer->marginLeft() + cancelRenderer->marginRight();
    515     }
    516 
    517     if (RenderBox* spinRenderer = m_innerSpinButton ? m_innerSpinButton->renderBox() : 0) {
    518         spinRenderer->computeLogicalWidth();
    519         width -= spinRenderer->width() + spinRenderer->marginLeft() + spinRenderer->marginRight();
    520     }
    521 
    522 #if ENABLE(INPUT_SPEECH)
    523     if (RenderBox* speechRenderer = m_speechButton ? m_speechButton->renderBox() : 0) {
    524         speechRenderer->computeLogicalWidth();
    525         width -= speechRenderer->width() + speechRenderer->marginLeft() + speechRenderer->marginRight();
    526     }
    527 #endif
    528 
    529     return width - decorationWidthRight();
    530 }
    531 
    532 int RenderTextControlSingleLine::decorationWidthRight() const
    533 {
    534     int width = 0;
    535     if (RenderBox* spinRenderer = m_outerSpinButton ? m_outerSpinButton->renderBox() : 0) {
    536         spinRenderer->computeLogicalWidth();
    537         width += spinRenderer->width() + spinRenderer->marginLeft() + spinRenderer->marginRight();
    538     }
    539     if (width > 0)
    540         width += paddingRight() + borderRight();
    541     return width;
    542 }
    543 
    544 float RenderTextControlSingleLine::getAvgCharWidth(AtomicString family)
    545 {
    546     // Since Lucida Grande is the default font, we want this to match the width
    547     // of MS Shell Dlg, the default font for textareas in Firefox, Safari Win and
    548     // IE for some encodings (in IE, the default font is encoding specific).
    549     // 901 is the avgCharWidth value in the OS/2 table for MS Shell Dlg.
    550     if (family == AtomicString("Lucida Grande"))
    551         return scaleEmToUnits(901);
    552 
    553     return RenderTextControl::getAvgCharWidth(family);
    554 }
    555 
    556 int RenderTextControlSingleLine::preferredContentWidth(float charWidth) const
    557 {
    558     int factor = inputElement()->size();
    559     if (factor <= 0)
    560         factor = 20;
    561 
    562     int result = static_cast<int>(ceilf(charWidth * factor));
    563 
    564     float maxCharWidth = 0.f;
    565     AtomicString family = style()->font().family().family();
    566     // Since Lucida Grande is the default font, we want this to match the width
    567     // of MS Shell Dlg, the default font for textareas in Firefox, Safari Win and
    568     // IE for some encodings (in IE, the default font is encoding specific).
    569     // 4027 is the (xMax - xMin) value in the "head" font table for MS Shell Dlg.
    570     if (family == AtomicString("Lucida Grande"))
    571         maxCharWidth = scaleEmToUnits(4027);
    572     else if (hasValidAvgCharWidth(family))
    573         maxCharWidth = roundf(style()->font().primaryFont()->maxCharWidth());
    574 
    575     // For text inputs, IE adds some extra width.
    576     if (maxCharWidth > 0.f)
    577         result += maxCharWidth - charWidth;
    578 
    579     if (RenderBox* resultsRenderer = m_resultsButton ? m_resultsButton->renderBox() : 0)
    580         result += resultsRenderer->borderLeft() + resultsRenderer->borderRight() +
    581                   resultsRenderer->paddingLeft() + resultsRenderer->paddingRight();
    582 
    583     if (RenderBox* cancelRenderer = m_cancelButton ? m_cancelButton->renderBox() : 0)
    584         result += cancelRenderer->borderLeft() + cancelRenderer->borderRight() +
    585                   cancelRenderer->paddingLeft() + cancelRenderer->paddingRight();
    586 
    587 #if ENABLE(INPUT_SPEECH)
    588     if (RenderBox* speechRenderer = m_speechButton ? m_speechButton->renderBox() : 0) {
    589         result += speechRenderer->borderLeft() + speechRenderer->borderRight() +
    590                   speechRenderer->paddingLeft() + speechRenderer->paddingRight();
    591     }
    592 #endif
    593     return result;
    594 }
    595 
    596 int RenderTextControlSingleLine::preferredDecorationWidthRight() const
    597 {
    598     int width = 0;
    599     if (RenderBox* spinRenderer = m_outerSpinButton ? m_outerSpinButton->renderBox() : 0) {
    600         spinRenderer->computeLogicalWidth();
    601         width += spinRenderer->minPreferredLogicalWidth() + spinRenderer->marginLeft() + spinRenderer->marginRight();
    602     }
    603     if (width > 0)
    604         width += paddingRight() + borderRight();
    605     return width;
    606 }
    607 
    608 void RenderTextControlSingleLine::adjustControlHeightBasedOnLineHeight(int lineHeight)
    609 {
    610     if (RenderBox* resultsRenderer = m_resultsButton ? m_resultsButton->renderBox() : 0) {
    611         resultsRenderer->computeLogicalHeight();
    612         setHeight(max(height(),
    613                   resultsRenderer->borderTop() + resultsRenderer->borderBottom() +
    614                   resultsRenderer->paddingTop() + resultsRenderer->paddingBottom() +
    615                   resultsRenderer->marginTop() + resultsRenderer->marginBottom()));
    616         lineHeight = max(lineHeight, resultsRenderer->height());
    617     }
    618     if (RenderBox* cancelRenderer = m_cancelButton ? m_cancelButton->renderBox() : 0) {
    619         cancelRenderer->computeLogicalHeight();
    620         setHeight(max(height(),
    621                   cancelRenderer->borderTop() + cancelRenderer->borderBottom() +
    622                   cancelRenderer->paddingTop() + cancelRenderer->paddingBottom() +
    623                   cancelRenderer->marginTop() + cancelRenderer->marginBottom()));
    624         lineHeight = max(lineHeight, cancelRenderer->height());
    625     }
    626 
    627     setHeight(height() + lineHeight);
    628 }
    629 
    630 void RenderTextControlSingleLine::createSubtreeIfNeeded()
    631 {
    632     if (inputElement()->isSearchField()) {
    633         if (!m_innerBlock) {
    634             // Create the inner block element
    635             m_innerBlock = TextControlInnerElement::create(toHTMLElement(node()));
    636             m_innerBlock->attachInnerElement(node(), createInnerBlockStyle(style()), renderArena());
    637         }
    638 
    639 #if ENABLE(INPUT_SPEECH)
    640         if (inputElement()->isSpeechEnabled() && !m_speechButton) {
    641             // Create the speech button element.
    642             m_speechButton = InputFieldSpeechButtonElement::create(toHTMLElement(node()));
    643             m_speechButton->attachInnerElement(node(), createSpeechButtonStyle(), renderArena());
    644         }
    645 #endif
    646 
    647         if (!m_resultsButton) {
    648             // Create the search results button element.
    649             m_resultsButton = SearchFieldResultsButtonElement::create(document());
    650             m_resultsButton->attachInnerElement(m_innerBlock.get(), createResultsButtonStyle(m_innerBlock->renderer()->style()), renderArena());
    651         }
    652 
    653         // Create innerText element before adding the other buttons.
    654         RenderTextControl::createSubtreeIfNeeded(m_innerBlock.get());
    655 
    656         if (!m_cancelButton) {
    657             // Create the cancel button element.
    658             m_cancelButton = SearchFieldCancelButtonElement::create(document());
    659             m_cancelButton->attachInnerElement(m_innerBlock.get(), createCancelButtonStyle(m_innerBlock->renderer()->style()), renderArena());
    660         }
    661     } else {
    662         RenderTextControl::createSubtreeIfNeeded(0);
    663 
    664 #if ENABLE(INPUT_SPEECH)
    665         if (inputElement()->isSpeechEnabled() && !m_speechButton) {
    666             // Create the speech button element.
    667             m_speechButton = InputFieldSpeechButtonElement::create(toHTMLElement(node()));
    668             m_speechButton->attachInnerElement(node(), createSpeechButtonStyle(), renderArena());
    669         }
    670 #endif
    671 
    672         bool hasSpinButton = inputElement()->hasSpinButton();
    673 
    674         if (hasSpinButton && !m_innerSpinButton) {
    675             m_innerSpinButton = SpinButtonElement::create(toHTMLElement(node()));
    676             m_innerSpinButton->attachInnerElement(node(), createInnerSpinButtonStyle(), renderArena());
    677         }
    678         if (hasSpinButton && !m_outerSpinButton) {
    679             m_outerSpinButton = SpinButtonElement::create(toHTMLElement(node()));
    680             m_outerSpinButton->attachInnerElement(node(), createOuterSpinButtonStyle(), renderArena());
    681         }
    682     }
    683 }
    684 
    685 void RenderTextControlSingleLine::updateFromElement()
    686 {
    687     createSubtreeIfNeeded();
    688     RenderTextControl::updateFromElement();
    689 
    690     if (m_cancelButton)
    691         updateCancelButtonVisibility();
    692 
    693     if (!inputElement()->suggestedValue().isNull())
    694         setInnerTextValue(inputElement()->suggestedValue());
    695     else {
    696         if (node()->hasTagName(inputTag)) {
    697             // For HTMLInputElement, update the renderer value if the formControlValueMatchesRenderer()
    698             // flag is false. It protects an unacceptable renderer value from
    699             // being overwritten with the DOM value.
    700             if (!static_cast<HTMLInputElement*>(node())->formControlValueMatchesRenderer())
    701                 setInnerTextValue(inputElement()->visibleValue());
    702         }
    703     }
    704 
    705     if (m_searchPopupIsVisible)
    706         m_searchPopup->popupMenu()->updateFromElement();
    707 }
    708 
    709 void RenderTextControlSingleLine::cacheSelection(int start, int end)
    710 {
    711     inputElement()->cacheSelection(start, end);
    712 }
    713 
    714 PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerTextStyle(const RenderStyle* startStyle) const
    715 {
    716     RefPtr<RenderStyle> textBlockStyle = RenderStyle::create();
    717     textBlockStyle->inheritFrom(startStyle);
    718     adjustInnerTextStyle(startStyle, textBlockStyle.get());
    719 
    720     textBlockStyle->setWhiteSpace(PRE);
    721     textBlockStyle->setWordWrap(NormalWordWrap);
    722     textBlockStyle->setOverflowX(OHIDDEN);
    723     textBlockStyle->setOverflowY(OHIDDEN);
    724 
    725     // Do not allow line-height to be smaller than our default.
    726     if (textBlockStyle->fontMetrics().lineSpacing() > lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes))
    727         textBlockStyle->setLineHeight(Length(-100.0f, Percent));
    728 
    729     WebCore::EDisplay display = (m_innerBlock || inputElement()->hasSpinButton() ? INLINE_BLOCK : BLOCK);
    730 #if ENABLE(INPUT_SPEECH)
    731     if (inputElement()->isSpeechEnabled())
    732       display = INLINE_BLOCK;
    733 #endif
    734     textBlockStyle->setDisplay(display);
    735 
    736     // We're adding one extra pixel of padding to match WinIE.
    737     textBlockStyle->setPaddingLeft(Length(1, Fixed));
    738     textBlockStyle->setPaddingRight(Length(1, Fixed));
    739 
    740     return textBlockStyle.release();
    741 }
    742 
    743 PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerBlockStyle(const RenderStyle* startStyle) const
    744 {
    745     ASSERT(node()->isHTMLElement());
    746 
    747     RefPtr<RenderStyle> innerBlockStyle = RenderStyle::create();
    748     innerBlockStyle->inheritFrom(startStyle);
    749 
    750     innerBlockStyle->setDisplay(BLOCK);
    751     innerBlockStyle->setDirection(LTR);
    752 
    753     // We don't want the shadow dom to be editable, so we set this block to read-only in case the input itself is editable.
    754     innerBlockStyle->setUserModify(READ_ONLY);
    755 
    756     return innerBlockStyle.release();
    757 }
    758 
    759 PassRefPtr<RenderStyle> RenderTextControlSingleLine::createResultsButtonStyle(const RenderStyle* startStyle) const
    760 {
    761     ASSERT(node()->isHTMLElement());
    762     HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
    763 
    764     RefPtr<RenderStyle> resultsBlockStyle;
    765     if (input->maxResults() < 0)
    766         resultsBlockStyle = getCachedPseudoStyle(SEARCH_DECORATION);
    767     else if (!input->maxResults())
    768         resultsBlockStyle = getCachedPseudoStyle(SEARCH_RESULTS_DECORATION);
    769     else
    770         resultsBlockStyle = getCachedPseudoStyle(SEARCH_RESULTS_BUTTON);
    771 
    772     if (!resultsBlockStyle)
    773         resultsBlockStyle = RenderStyle::create();
    774 
    775     if (startStyle)
    776         resultsBlockStyle->inheritFrom(startStyle);
    777 
    778     return resultsBlockStyle.release();
    779 }
    780 
    781 PassRefPtr<RenderStyle> RenderTextControlSingleLine::createCancelButtonStyle(const RenderStyle* startStyle) const
    782 {
    783     ASSERT(node()->isHTMLElement());
    784     RefPtr<RenderStyle> cancelBlockStyle;
    785 
    786     if (RefPtr<RenderStyle> pseudoStyle = getCachedPseudoStyle(SEARCH_CANCEL_BUTTON))
    787         // We may be sharing style with another search field, but we must not share the cancel button style.
    788         cancelBlockStyle = RenderStyle::clone(pseudoStyle.get());
    789     else
    790         cancelBlockStyle = RenderStyle::create();
    791 
    792     if (startStyle)
    793         cancelBlockStyle->inheritFrom(startStyle);
    794 
    795     cancelBlockStyle->setVisibility(visibilityForCancelButton());
    796     return cancelBlockStyle.release();
    797 }
    798 
    799 PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerSpinButtonStyle() const
    800 {
    801     ASSERT(node()->isHTMLElement());
    802     RefPtr<RenderStyle> buttonStyle = getCachedPseudoStyle(INNER_SPIN_BUTTON);
    803     if (!buttonStyle)
    804         buttonStyle = RenderStyle::create();
    805     buttonStyle->inheritFrom(style());
    806     return buttonStyle.release();
    807 }
    808 
    809 PassRefPtr<RenderStyle> RenderTextControlSingleLine::createOuterSpinButtonStyle() const
    810 {
    811     ASSERT(node()->isHTMLElement());
    812     RefPtr<RenderStyle> buttonStyle = getCachedPseudoStyle(OUTER_SPIN_BUTTON);
    813     if (!buttonStyle)
    814         buttonStyle = RenderStyle::create();
    815     buttonStyle->inheritFrom(style());
    816     return buttonStyle.release();
    817 }
    818 
    819 #if ENABLE(INPUT_SPEECH)
    820 PassRefPtr<RenderStyle> RenderTextControlSingleLine::createSpeechButtonStyle() const
    821 {
    822     ASSERT(node()->isHTMLElement());
    823     RefPtr<RenderStyle> buttonStyle = getCachedPseudoStyle(INPUT_SPEECH_BUTTON);
    824     if (!buttonStyle)
    825         buttonStyle = RenderStyle::create();
    826     buttonStyle->inheritFrom(style());
    827     return buttonStyle.release();
    828 }
    829 #endif
    830 
    831 void RenderTextControlSingleLine::updateCancelButtonVisibility() const
    832 {
    833     if (!m_cancelButton->renderer())
    834         return;
    835 
    836     const RenderStyle* curStyle = m_cancelButton->renderer()->style();
    837     EVisibility buttonVisibility = visibilityForCancelButton();
    838     if (curStyle->visibility() == buttonVisibility)
    839         return;
    840 
    841     RefPtr<RenderStyle> cancelButtonStyle = RenderStyle::clone(curStyle);
    842     cancelButtonStyle->setVisibility(buttonVisibility);
    843     m_cancelButton->renderer()->setStyle(cancelButtonStyle);
    844 }
    845 
    846 EVisibility RenderTextControlSingleLine::visibilityForCancelButton() const
    847 {
    848     ASSERT(node()->isHTMLElement());
    849     HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
    850     return input->value().isEmpty() ? HIDDEN : VISIBLE;
    851 }
    852 
    853 const AtomicString& RenderTextControlSingleLine::autosaveName() const
    854 {
    855     return static_cast<Element*>(node())->getAttribute(autosaveAttr);
    856 }
    857 
    858 void RenderTextControlSingleLine::startSearchEventTimer()
    859 {
    860     ASSERT(node()->isHTMLElement());
    861     unsigned length = text().length();
    862 
    863     // If there's no text, fire the event right away.
    864     if (!length) {
    865         stopSearchEventTimer();
    866         static_cast<HTMLInputElement*>(node())->onSearch();
    867         return;
    868     }
    869 
    870     // After typing the first key, we wait 0.5 seconds.
    871     // After the second key, 0.4 seconds, then 0.3, then 0.2 from then on.
    872     m_searchEventTimer.startOneShot(max(0.2, 0.6 - 0.1 * length));
    873 }
    874 
    875 void RenderTextControlSingleLine::searchEventTimerFired(Timer<RenderTextControlSingleLine>*)
    876 {
    877     ASSERT(node()->isHTMLElement());
    878     static_cast<HTMLInputElement*>(node())->onSearch();
    879 }
    880 
    881 // PopupMenuClient methods
    882 void RenderTextControlSingleLine::valueChanged(unsigned listIndex, bool fireEvents)
    883 {
    884     ASSERT(node()->isHTMLElement());
    885     ASSERT(static_cast<int>(listIndex) < listSize());
    886     HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
    887     if (static_cast<int>(listIndex) == (listSize() - 1)) {
    888         if (fireEvents) {
    889             m_recentSearches.clear();
    890             const AtomicString& name = autosaveName();
    891             if (!name.isEmpty()) {
    892                 if (!m_searchPopup)
    893                     m_searchPopup = document()->page()->chrome()->createSearchPopupMenu(this);
    894                 m_searchPopup->saveRecentSearches(name, m_recentSearches);
    895             }
    896         }
    897     } else {
    898         input->setValue(itemText(listIndex));
    899         if (fireEvents)
    900             input->onSearch();
    901         input->select();
    902     }
    903 }
    904 
    905 String RenderTextControlSingleLine::itemText(unsigned listIndex) const
    906 {
    907     int size = listSize();
    908     if (size == 1) {
    909         ASSERT(!listIndex);
    910         return searchMenuNoRecentSearchesText();
    911     }
    912     if (!listIndex)
    913         return searchMenuRecentSearchesText();
    914     if (itemIsSeparator(listIndex))
    915         return String();
    916     if (static_cast<int>(listIndex) == (size - 1))
    917         return searchMenuClearRecentSearchesText();
    918     return m_recentSearches[listIndex - 1];
    919 }
    920 
    921 String RenderTextControlSingleLine::itemLabel(unsigned) const
    922 {
    923     return String();
    924 }
    925 
    926 String RenderTextControlSingleLine::itemIcon(unsigned) const
    927 {
    928     return String();
    929 }
    930 
    931 bool RenderTextControlSingleLine::itemIsEnabled(unsigned listIndex) const
    932 {
    933      if (!listIndex || itemIsSeparator(listIndex))
    934         return false;
    935     return true;
    936 }
    937 
    938 PopupMenuStyle RenderTextControlSingleLine::itemStyle(unsigned) const
    939 {
    940     return menuStyle();
    941 }
    942 
    943 PopupMenuStyle RenderTextControlSingleLine::menuStyle() const
    944 {
    945     return PopupMenuStyle(style()->visitedDependentColor(CSSPropertyColor), style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->font(), style()->visibility() == VISIBLE, style()->display() == NONE, style()->textIndent(), style()->direction(), style()->unicodeBidi() == Override);
    946 }
    947 
    948 int RenderTextControlSingleLine::clientInsetLeft() const
    949 {
    950     // Inset the menu by the radius of the cap on the left so that
    951     // it only runs along the straight part of the bezel.
    952     return height() / 2;
    953 }
    954 
    955 int RenderTextControlSingleLine::clientInsetRight() const
    956 {
    957     // Inset the menu by the radius of the cap on the right so that
    958     // it only runs along the straight part of the bezel (unless it needs
    959     // to be wider).
    960     return height() / 2;
    961 }
    962 
    963 int RenderTextControlSingleLine::clientPaddingLeft() const
    964 {
    965     int padding = paddingLeft();
    966 
    967     if (RenderBox* resultsRenderer = m_resultsButton ? m_resultsButton->renderBox() : 0)
    968         padding += resultsRenderer->width() + resultsRenderer->marginLeft() + resultsRenderer->paddingLeft() + resultsRenderer->marginRight() + resultsRenderer->paddingRight();
    969 
    970     return padding;
    971 }
    972 
    973 int RenderTextControlSingleLine::clientPaddingRight() const
    974 {
    975     int padding = paddingRight();
    976 
    977     if (RenderBox* cancelRenderer = m_cancelButton ? m_cancelButton->renderBox() : 0)
    978         padding += cancelRenderer->width() + cancelRenderer->marginLeft() + cancelRenderer->paddingLeft() + cancelRenderer->marginRight() + cancelRenderer->paddingRight();
    979 
    980     return padding;
    981 }
    982 
    983 int RenderTextControlSingleLine::listSize() const
    984 {
    985     // If there are no recent searches, then our menu will have 1 "No recent searches" item.
    986     if (!m_recentSearches.size())
    987         return 1;
    988     // Otherwise, leave room in the menu for a header, a separator, and the "Clear recent searches" item.
    989     return m_recentSearches.size() + 3;
    990 }
    991 
    992 int RenderTextControlSingleLine::selectedIndex() const
    993 {
    994     return -1;
    995 }
    996 
    997 void RenderTextControlSingleLine::popupDidHide()
    998 {
    999     m_searchPopupIsVisible = false;
   1000 }
   1001 
   1002 bool RenderTextControlSingleLine::itemIsSeparator(unsigned listIndex) const
   1003 {
   1004     // The separator will be the second to last item in our list.
   1005     return static_cast<int>(listIndex) == (listSize() - 2);
   1006 }
   1007 
   1008 bool RenderTextControlSingleLine::itemIsLabel(unsigned listIndex) const
   1009 {
   1010     return listIndex == 0;
   1011 }
   1012 
   1013 bool RenderTextControlSingleLine::itemIsSelected(unsigned) const
   1014 {
   1015     return false;
   1016 }
   1017 
   1018 void RenderTextControlSingleLine::setTextFromItem(unsigned listIndex)
   1019 {
   1020     ASSERT(node()->isHTMLElement());
   1021     static_cast<HTMLInputElement*>(node())->setValue(itemText(listIndex));
   1022 }
   1023 
   1024 FontSelector* RenderTextControlSingleLine::fontSelector() const
   1025 {
   1026     return document()->styleSelector()->fontSelector();
   1027 }
   1028 
   1029 HostWindow* RenderTextControlSingleLine::hostWindow() const
   1030 {
   1031     return document()->view()->hostWindow();
   1032 }
   1033 
   1034 void RenderTextControlSingleLine::autoscroll()
   1035 {
   1036     RenderLayer* layer = innerTextElement()->renderBox()->layer();
   1037     if (layer)
   1038         layer->autoscroll();
   1039 }
   1040 
   1041 int RenderTextControlSingleLine::scrollWidth() const
   1042 {
   1043     if (innerTextElement())
   1044         return innerTextElement()->scrollWidth();
   1045     return RenderBlock::scrollWidth();
   1046 }
   1047 
   1048 int RenderTextControlSingleLine::scrollHeight() const
   1049 {
   1050     if (innerTextElement())
   1051         return innerTextElement()->scrollHeight();
   1052     return RenderBlock::scrollHeight();
   1053 }
   1054 
   1055 int RenderTextControlSingleLine::scrollLeft() const
   1056 {
   1057     if (innerTextElement())
   1058         return innerTextElement()->scrollLeft();
   1059     return RenderBlock::scrollLeft();
   1060 }
   1061 
   1062 int RenderTextControlSingleLine::scrollTop() const
   1063 {
   1064     if (innerTextElement())
   1065         return innerTextElement()->scrollTop();
   1066     return RenderBlock::scrollTop();
   1067 }
   1068 
   1069 void RenderTextControlSingleLine::setScrollLeft(int newLeft)
   1070 {
   1071     if (innerTextElement())
   1072         innerTextElement()->setScrollLeft(newLeft);
   1073 }
   1074 
   1075 void RenderTextControlSingleLine::setScrollTop(int newTop)
   1076 {
   1077     if (innerTextElement())
   1078         innerTextElement()->setScrollTop(newTop);
   1079 }
   1080 
   1081 bool RenderTextControlSingleLine::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier, Node** stopNode)
   1082 {
   1083     RenderLayer* layer = innerTextElement()->renderBox()->layer();
   1084     if (layer && layer->scroll(direction, granularity, multiplier))
   1085         return true;
   1086     return RenderBlock::scroll(direction, granularity, multiplier, stopNode);
   1087 }
   1088 
   1089 bool RenderTextControlSingleLine::logicalScroll(ScrollLogicalDirection direction, ScrollGranularity granularity, float multiplier, Node** stopNode)
   1090 {
   1091     RenderLayer* layer = innerTextElement()->renderBox()->layer();
   1092     if (layer && layer->scroll(logicalToPhysical(direction, style()->isHorizontalWritingMode(), style()->isFlippedBlocksWritingMode()), granularity, multiplier))
   1093         return true;
   1094     return RenderBlock::logicalScroll(direction, granularity, multiplier, stopNode);
   1095 }
   1096 
   1097 PassRefPtr<Scrollbar> RenderTextControlSingleLine::createScrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, ScrollbarControlSize controlSize)
   1098 {
   1099     RefPtr<Scrollbar> widget;
   1100     bool hasCustomScrollbarStyle = style()->hasPseudoStyle(SCROLLBAR);
   1101     if (hasCustomScrollbarStyle)
   1102         widget = RenderScrollbar::createCustomScrollbar(scrollableArea, orientation, this);
   1103     else
   1104         widget = Scrollbar::createNativeScrollbar(scrollableArea, orientation, controlSize);
   1105     return widget.release();
   1106 }
   1107 
   1108 InputElement* RenderTextControlSingleLine::inputElement() const
   1109 {
   1110     return node()->toInputElement();
   1111 }
   1112 
   1113 int RenderTextControlSingleLine::textBlockInsetLeft() const
   1114 {
   1115     int inset = borderLeft() + clientPaddingLeft();
   1116     if (HTMLElement* innerText = innerTextElement()) {
   1117         if (RenderBox* innerTextRenderer = innerText->renderBox())
   1118             inset += innerTextRenderer->paddingLeft();
   1119     }
   1120     return inset;
   1121 }
   1122 
   1123 int RenderTextControlSingleLine::textBlockInsetRight() const
   1124 {
   1125     int inset = borderRight() + clientPaddingRight();
   1126     if (HTMLElement* innerText = innerTextElement()) {
   1127         if (RenderBox* innerTextRenderer = innerText->renderBox())
   1128             inset += innerTextRenderer->paddingRight();
   1129     }
   1130     return inset;
   1131 }
   1132 
   1133 int RenderTextControlSingleLine::textBlockInsetTop() const
   1134 {
   1135     RenderBox* innerRenderer = 0;
   1136     if (m_innerBlock)
   1137         innerRenderer = m_innerBlock->renderBox();
   1138     else if (HTMLElement* innerText = innerTextElement())
   1139         innerRenderer = innerText->renderBox();
   1140 
   1141     if (innerRenderer)
   1142         return innerRenderer->y();
   1143 
   1144     return borderTop() + paddingTop();
   1145 }
   1146 
   1147 }
   1148